Radish alpha
r
Radicle web interface
Radicle
Git (anonymous pull)
Log in to clone via SSH
Update `radicle-git` and `radicle-surf`
xphoniex committed 3 years ago
commit 4a27cc3f6c5c84dab5428149691ea82a8ad2f7cb
parent a6d120fa28d4e5845cc178bf601d9e798d927798
4 files changed +47 -30
modified radicle-httpd/Cargo.toml
@@ -24,6 +24,7 @@ fastrand = { version = "1.7.0" }
flate2 = { version = "1" }
hyper = { version = "0.14.17", default-features = false }
lexopt = { version = "0.2.1" }
+
radicle-surf = { version = "0.9.0", default-features = false, features = ["serde"] }
serde = { version = "1", features = ["derive"] }
serde_json = { version = "1", features = ["preserve_order"] }
thiserror = { version = "1" }
@@ -38,11 +39,6 @@ tracing-subscriber = { version = "0.3", default-features = false, features = ["s
path = "../radicle"
version = "0.2.0"

-
[dependencies.radicle-surf]
-
git = "https://github.com/radicle-dev/radicle-git"
-
features = ["serde"]
-
rev = "48022590d0439e7fb196605a573a725bbbf0e4d2"
-

[dev-dependencies]
hyper = { version = "0.14.17", default-features = false, features = ["client"] }
radicle-cli = { path = "../radicle-cli" }
modified radicle-httpd/src/api/json.rs
@@ -1,6 +1,7 @@
//! Utilities for building JSON responses of our API.

use std::path::Path;
+
use std::str;

use serde::Serialize;
use serde_json::{json, Value};
@@ -46,14 +47,22 @@ pub(crate) fn session(session_id: String, session: &Session) -> Value {
}

/// Returns JSON for a blob with a given `path`.
-
pub(crate) fn blob(blob: &Blob, path: &str) -> Value {
-
    json!({
+
pub(crate) fn blob<T: AsRef<[u8]>>(blob: &Blob<T>, path: &str) -> Value {
+
    let mut response = json!({
        "binary": blob.is_binary(),
-
        "content": blob.content(),
        "name": name_in_path(path),
        "path": path,
        "lastCommit": commit(blob.commit())
-
    })
+
    });
+

+
    if !blob.is_binary() {
+
        match str::from_utf8(blob.content()) {
+
            Ok(content) => response["content"] = content.into(),
+
            Err(err) => return json!({ "error": err.to_string() }),
+
        }
+
    }
+

+
    response
}

/// Returns JSON for a tree with a given `path` and `stats`.
@@ -85,9 +94,9 @@ pub(crate) fn issue(id: IssueId, issue: Issue) -> Value {
    json!({
        "id": id.to_string(),
        "author": issue.author(),
-
        "assignees": issue.assigned().collect::<Vec<_>>(),
        "title": issue.title(),
        "state": issue.state(),
+
        "assignees": issue.assigned().collect::<Vec<_>>(),
        "discussion": issue.comments().collect::<Comments>(),
        "tags": issue.tags().collect::<Vec<_>>(),
    })
modified radicle-httpd/src/api/test.rs
@@ -22,6 +22,8 @@ use crate::api::{auth, Context};

pub const HEAD: &str = "1e978d19f251cd9821d9d9a76d1bd436bf0690d5";
pub const HEAD_1: &str = "f604ce9fd5b7cc77b7609beda45ea8760bee78f7";
+
pub const PATCH_ID: &str = "4250f0117659ee4de9af99e699a63395cd6ffa1c";
+
pub const ISSUE_ID: &str = "d8131af9738258fac139c4c96b71c02411f94892";

const PASSWORD: &str = "radicle";

modified radicle-httpd/src/api/v1/projects.rs
@@ -423,11 +423,14 @@ async fn issue_create_handler(
        .map_err(|_| Error::Auth("Unauthorized"))?;
    let repo = storage.repository(project)?;
    let mut issues = Issues::open(ctx.profile.public_key, &repo)?;
-
    issues
+
    let issue = issues
        .create(issue.title, issue.description, &issue.tags, &signer)
        .map_err(Error::from)?;

-
    Ok::<_, Error>((StatusCode::CREATED, Json(json!({ "success": true }))))
+
    Ok::<_, Error>((
+
        StatusCode::CREATED,
+
        Json(json!({ "success": true, "id": issue.id().to_string() })),
+
    ))
}

/// Update an issue.
@@ -546,7 +549,9 @@ mod routes {
    use axum::http::StatusCode;
    use serde_json::json;

-
    use crate::api::test::{self, get, patch, post, HEAD, HEAD_1};
+
    use crate::api::test::{self, get, patch, post, HEAD, HEAD_1, ISSUE_ID, PATCH_ID};
+

+
    const CREATED_ISSUE_ID: &str = "768c6735912a34856552ae6a9ca77d728962bf31";

    #[tokio::test]
    async fn test_projects_root() {
@@ -635,7 +640,8 @@ mod routes {
                                }
                              ]
                            }
-
                          ]
+
                          ],
+
                          "eof": "noneMissing",
                        }
                      }
                    ],
@@ -685,7 +691,8 @@ mod routes {
                                }
                              ]
                            }
-
                          ]
+
                          ],
+
                          "eof": "noneMissing",
                        }
                      }
                    ],
@@ -759,7 +766,8 @@ mod routes {
                            }
                          ]
                        }
-
                      ]
+
                      ],
+
                      "eof": "noneMissing",
                    }
                  }
                ],
@@ -996,7 +1004,7 @@ mod routes {
            response.json().await,
            json!([
              {
-
                "id": "90c8f0bab59d9efe35e234acf3abce4168bba6b4",
+
                "id": ISSUE_ID,
                "author": {
                    "id": "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
                },
@@ -1044,19 +1052,21 @@ mod routes {
        .await;

        assert_eq!(response.status(), StatusCode::CREATED);
-
        assert_eq!(response.json().await, json!({ "success": true }));
+
        assert_eq!(
+
            response.json().await,
+
            json!({ "success": true, "id": CREATED_ISSUE_ID })
+
        );

-
        let issue_id = "bd2bde30b52db0fc2dae35f4e97ff9fdcc93dead";
        let response = get(
            &app,
-
            format!("/projects/rad:z4FucBZHZMCsxTyQE1dfE2YR59Qbp/issues/{issue_id}"),
+
            format!("/projects/rad:z4FucBZHZMCsxTyQE1dfE2YR59Qbp/issues/{CREATED_ISSUE_ID}"),
        )
        .await;

        assert_eq!(
            response.json().await,
            json!({
-
              "id": issue_id,
+
              "id": CREATED_ISSUE_ID,
              "author": {
                  "id": "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
              },
@@ -1098,7 +1108,7 @@ mod routes {
        .unwrap();
        let response = patch(
            &app,
-
            "/projects/rad:z4FucBZHZMCsxTyQE1dfE2YR59Qbp/issues/90c8f0bab59d9efe35e234acf3abce4168bba6b4",
+
            format!("/projects/rad:z4FucBZHZMCsxTyQE1dfE2YR59Qbp/issues/{ISSUE_ID}"),
            Some(Body::from(body)),
            Some("u9MGAkkfkMOv0uDDB2WeUHBT7HbsO2Dy".to_string()),
        )
@@ -1109,14 +1119,14 @@ mod routes {

        let response = get(
            &app,
-
            "/projects/rad:z4FucBZHZMCsxTyQE1dfE2YR59Qbp/issues/90c8f0bab59d9efe35e234acf3abce4168bba6b4",
+
            format!("/projects/rad:z4FucBZHZMCsxTyQE1dfE2YR59Qbp/issues/{ISSUE_ID}"),
        )
        .await;

        assert_eq!(
            response.json().await,
            json!({
-
              "id": "90c8f0bab59d9efe35e234acf3abce4168bba6b4",
+
              "id": ISSUE_ID,
              "author": {
                  "id": "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
              },
@@ -1168,7 +1178,7 @@ mod routes {
        .unwrap();
        let response = patch(
            &app,
-
            "/projects/rad:z4FucBZHZMCsxTyQE1dfE2YR59Qbp/issues/90c8f0bab59d9efe35e234acf3abce4168bba6b4",
+
            format!("/projects/rad:z4FucBZHZMCsxTyQE1dfE2YR59Qbp/issues/{ISSUE_ID}"),
            Some(Body::from(body)),
            Some("u9MGAkkfkMOv0uDDB2WeUHBT7HbsO2Dy".to_string()),
        )
@@ -1179,14 +1189,14 @@ mod routes {

        let response = get(
            &app,
-
            "/projects/rad:z4FucBZHZMCsxTyQE1dfE2YR59Qbp/issues/90c8f0bab59d9efe35e234acf3abce4168bba6b4",
+
            format!("/projects/rad:z4FucBZHZMCsxTyQE1dfE2YR59Qbp/issues/{ISSUE_ID}"),
        )
        .await;

        assert_eq!(
            response.json().await,
            json!({
-
              "id": "90c8f0bab59d9efe35e234acf3abce4168bba6b4",
+
              "id": ISSUE_ID,
              "author": {
                  "id": "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
              },
@@ -1233,7 +1243,7 @@ mod routes {
            response.json().await,
            json!([
              {
-
                "id": "5de9f17ca5326258412ab02f9a5339b6482198ce",
+
                "id": PATCH_ID,
                "author": {
                    "id": "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
                },
@@ -1255,7 +1265,7 @@ mod routes {

        let response = get(
            &app,
-
            "/projects/rad:z4FucBZHZMCsxTyQE1dfE2YR59Qbp/patches/5de9f17ca5326258412ab02f9a5339b6482198ce",
+
            format!("/projects/rad:z4FucBZHZMCsxTyQE1dfE2YR59Qbp/patches/{PATCH_ID}"),
        )
        .await;

@@ -1264,7 +1274,7 @@ mod routes {
            response.json().await,
            json!(
              {
-
                "id": "5de9f17ca5326258412ab02f9a5339b6482198ce",
+
                "id": PATCH_ID,
                "author": {
                    "id": "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
                },