diff --git a/Cargo.lock b/Cargo.lock index eafd8ee8..be4a681d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2017,9 +2017,9 @@ checksum = "db20136bbc9ae63f3fec8e5a6c369f4902fac2244501b5dfc6d668e43475aaa4" [[package]] name = "radicle-surf" -version = "0.14.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b801a32980495a643bd380cc88f2074cf978862efbc8c085d5bd9f3be4caafd6" +checksum = "1c04ade152e9721c0c288960acd260c8c0b038569ae0b054e76c5914fa9e0dd8" dependencies = [ "anyhow", "base64 0.13.1", diff --git a/radicle-httpd/Cargo.toml b/radicle-httpd/Cargo.toml index 74981baf..c2a74788 100644 --- a/radicle-httpd/Cargo.toml +++ b/radicle-httpd/Cargo.toml @@ -26,7 +26,7 @@ hyper = { version = "0.14.17", default-features = false } lexopt = { version = "0.2.1" } lru = { version = "0.11.0" } nonempty = { version = "0.8.1", features = ["serialize"] } -radicle-surf = { version = "0.14.0", default-features = false, features = ["serde"] } +radicle-surf = { version = "0.14.1", default-features = false, features = ["serde"] } serde = { version = "1", features = ["derive"] } serde_json = { version = "1", features = ["preserve_order"] } thiserror = { version = "1" } diff --git a/radicle-httpd/src/api/v1/projects.rs b/radicle-httpd/src/api/v1/projects.rs index 8fbc9570..7c5de80d 100644 --- a/radicle-httpd/src/api/v1/projects.rs +++ b/radicle-httpd/src/api/v1/projects.rs @@ -1,4 +1,4 @@ -use std::collections::BTreeMap; +use std::collections::{BTreeMap, HashMap}; use axum::extract::State; use axum::handler::Handler; @@ -8,6 +8,7 @@ use axum::routing::{get, patch, post}; use axum::{Json, Router}; use axum_auth::AuthBearer; use hyper::StatusCode; +use radicle_surf::blob::{Blob, BlobRef}; use serde::{Deserialize, Serialize}; use serde_json::json; use tower_http::set_header::SetResponseHeaderLayer; @@ -19,7 +20,7 @@ use radicle::node::AliasStore; use radicle::node::NodeId; use radicle::storage::git::paths; use radicle::storage::{ReadRepository, ReadStorage, WriteRepository}; -use radicle_surf::{Glob, Oid, Repository}; +use radicle_surf::{diff, Glob, Oid, Repository}; use crate::api::error::Error; use crate::api::project::Info; @@ -249,6 +250,29 @@ async fn diff_handler( let base = repo.commit(base)?; let commit = repo.commit(oid)?; let diff = repo.diff(base.id, commit.id)?; + let mut files: HashMap>> = HashMap::new(); + diff.files().for_each(|file_diff| match file_diff { + diff::FileDiff::Added(added) => { + if let Ok(blob) = repo.blob(commit.id, &added.path) { + files.insert(added.new.oid, blob); + } + } + diff::FileDiff::Deleted(deleted) => { + if let Ok(blob) = repo.blob(commit.id, &deleted.path) { + files.insert(deleted.old.oid, blob); + } + } + diff::FileDiff::Modified(modified) => { + if let (Ok(old_blob), Ok(new_blob)) = ( + repo.blob(commit.parents[0], &modified.path), + repo.blob(commit.id, &modified.path), + ) { + files.insert(modified.old.oid, old_blob); + files.insert(modified.new.oid, new_blob); + } + } + _ => (), + }); let commits = repo .history(commit.id)? @@ -262,7 +286,7 @@ async fn diff_handler( .map(|r| r.map(|c| api::json::commit(&c))) .collect::, _>>()?; - let response = json!({ "diff": diff, "commits": commits }); + let response = json!({ "diff": diff, "files": files, "commits": commits }); Ok::<_, Error>(Json(response)) } @@ -1656,6 +1680,32 @@ mod routes { "deletions": 0, }, }, + "files": { + "1dd5654ca2d2cf9f33b14c92b5ca9e1d21a91ae1": { + "id": "1dd5654ca2d2cf9f33b14c92b5ca9e1d21a91ae1", + "binary": false, + "content": "Hello World from dir1!\n", + "lastCommit": { + "id": "e8c676b9e3b42308dc9d218b70faa5408f8e58ca", + "author": { + "name": "Alice Liddell", + "email": "alice@radicle.xyz", + "time": 1673003014, + }, + "committer": { + "name": "Alice Liddell", + "email": "alice@radicle.xyz", + "time": 1673003014, + }, + "summary": "Add another folder", + "message": "Add another folder\n", + "description": "", + "parents": [ + "ee8d6a29304623a78ebfa5eeed5af674d0e58f83", + ], + }, + }, + }, "commits": [ { "id": HEAD,