diff --git a/Cargo.lock b/Cargo.lock index 078f0da9..053b20a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1944,6 +1944,7 @@ dependencies = [ "radicle-crypto", "radicle-git-ext", "radicle-node", + "radicle-surf", "radicle-term", "serde", "serde_json", @@ -2031,9 +2032,9 @@ dependencies = [ [[package]] name = "radicle-git-ext" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d6531d5c9b029df83b8887c27d56e05de59f2821f70fc5e8fce0646437ecda5" +checksum = "85d13d7488924b07c0d541760520b1e4224c6ffa2d9765e05d1de9591e248970" dependencies = [ "git-ref-format", "git2", diff --git a/radicle-cli/Cargo.toml b/radicle-cli/Cargo.toml index f9ccab04..260fab7c 100644 --- a/radicle-cli/Cargo.toml +++ b/radicle-cli/Cargo.toml @@ -21,6 +21,7 @@ nonempty = { version = "0.8" } # N.b. this is required to use macros, even though it's re-exported # through radicle radicle-git-ext = { version = "0.5.0", features = ["serde"] } +radicle-surf = { version = "0.12.0" } serde = { version = "1.0" } serde_json = { version = "1" } serde_yaml = { version = "0.8" } diff --git a/radicle-cli/examples/rad-review-by-hunk.md b/radicle-cli/examples/rad-review-by-hunk.md new file mode 100644 index 00000000..ea616213 --- /dev/null +++ b/radicle-cli/examples/rad-review-by-hunk.md @@ -0,0 +1,184 @@ +Let's start by creating some files we will patch: + +``` ./MENU.txt +Classics +-------- +Salmon Tartare +Mac & Cheese + +Comfort Food +------------ +Reuben Sandwich +Club Sandwich +Fried Shrimp Basket + +Sides +----- +French Fries +``` + +``` ./INSTRUCTIONS.txt +Notes on how to prepare food go here. +``` + +``` ./.gitignore +*.draft +``` + +Now let's commit and push them: + +``` +$ git add MENU.txt INSTRUCTIONS.txt .gitignore +$ git commit -q -a -m "Add files" +$ git push rad master +``` + +We can now make some changes and create a patch: + +``` +$ sed -i '$a Garlic Green Beans' MENU.txt +$ sed -i '3i\Baked Brie' MENU.txt +$ sed -i 's/French Fries/French Fries!/' MENU.txt +$ rm .gitignore +$ mkdir notes +$ mv INSTRUCTIONS.txt notes/ +``` + +``` ./DISCLAIMER.txt +All food is served as-is, with no warranty! +``` + +``` +$ git checkout -q -b patch/1 +$ git add . +$ git status --short +D .gitignore +A DISCLAIMER.txt +M MENU.txt +R INSTRUCTIONS.txt -> notes/INSTRUCTIONS.txt +$ git commit -q -m "Update files" +``` + +``` (stderr) +$ git push rad HEAD:refs/patches +✓ Patch a05c57911e6ec9eba4e5539a095a6a86e2bf7c2c opened +To rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi + * [new reference] HEAD -> refs/patches +``` + +Finally, we do a review of the patch by hunk. The output of this command should +match `git diff master -W100% -U5 --patience`: + +``` +$ rad review --no-sync --patch -U5 a05c57911e6ec9eba4e5539a095a6a86e2bf7c2c +diff --git a/.gitignore b/.gitignore +deleted file mode 100644 +index 7937fb3..0000000 +--- a/.gitignore ++++ /dev/null +@@ -1 +0,0 @@ +-*.draft +diff --git a/DISCLAIMER.txt b/DISCLAIMER.txt +new file mode 100644 +index 0000000..2b5bd86 +--- /dev/null ++++ b/DISCLAIMER.txt +@@ -0,0 +1 @@ ++All food is served as-is, with no warranty! +diff --git a/MENU.txt b/MENU.txt +index 867958c..3af9741 100644 +--- a/MENU.txt ++++ b/MENU.txt +@@ -1,7 +1,8 @@ + Classics + -------- ++Baked Brie + Salmon Tartare + Mac & Cheese +[..] + Comfort Food + ------------ +@@ -9,6 +10,7 @@ Reuben Sandwich + Club Sandwich + Fried Shrimp Basket +[..] + Sides + ----- +-French Fries ++French Fries! ++Garlic Green Beans +diff --git a/INSTRUCTIONS.txt b/notes/INSTRUCTIONS.txt +similarity index 100% +rename from INSTRUCTIONS.txt +rename to notes/INSTRUCTIONS.txt +``` + +Now let's accept these hunks one by one.. + +``` +$ rad review --no-sync --patch --accept --hunk 1 a05c57911e6ec9eba4e5539a095a6a86e2bf7c2c +✓ Loaded existing review ([..]) for patch a05c57911e6ec9eba4e5539a095a6a86e2bf7c2c +diff --git a/.gitignore b/.gitignore +deleted file mode 100644 +index 7937fb3..0000000 +--- a/.gitignore ++++ /dev/null +@@ -1 +0,0 @@ +-*.draft +``` +``` +$ rad review --no-sync --patch --accept --hunk 1 a05c57911e6ec9eba4e5539a095a6a86e2bf7c2c +✓ Loaded existing review ([..]) for patch a05c57911e6ec9eba4e5539a095a6a86e2bf7c2c +diff --git a/DISCLAIMER.txt b/DISCLAIMER.txt +new file mode 100644 +index 0000000..2b5bd86 +--- /dev/null ++++ b/DISCLAIMER.txt +@@ -0,0 +1 @@ ++All food is served as-is, with no warranty! +``` +``` +$ rad review --no-sync --patch --accept -U3 --hunk 1 a05c57911e6ec9eba4e5539a095a6a86e2bf7c2c +✓ Loaded existing review ([..]) for patch a05c57911e6ec9eba4e5539a095a6a86e2bf7c2c +diff --git a/MENU.txt b/MENU.txt +index 867958c..3af9741 100644 +--- a/MENU.txt ++++ b/MENU.txt +@@ -1,5 +1,6 @@ + Classics + -------- ++Baked Brie + Salmon Tartare + Mac & Cheese +[..] +``` +``` +$ rad review --no-sync --patch --accept -U3 --hunk 1 a05c57911e6ec9eba4e5539a095a6a86e2bf7c2c +✓ Loaded existing review ([..]) for patch a05c57911e6ec9eba4e5539a095a6a86e2bf7c2c +diff --git a/MENU.txt b/MENU.txt +index 4e2e828..3af9741 100644 +--- a/MENU.txt ++++ b/MENU.txt +@@ -12,4 +12,5 @@ Fried Shrimp Basket +[..] + Sides + ----- +-French Fries ++French Fries! ++Garlic Green Beans +``` + +``` +$ rad review --no-sync --patch --accept --hunk 1 a05c57911e6ec9eba4e5539a095a6a86e2bf7c2c +✓ Loaded existing review ([..]) for patch a05c57911e6ec9eba4e5539a095a6a86e2bf7c2c +diff --git a/INSTRUCTIONS.txt b/notes/INSTRUCTIONS.txt +similarity index 100% +rename from INSTRUCTIONS.txt +rename to notes/INSTRUCTIONS.txt +``` + +``` +$ rad review --no-sync --patch --accept --hunk 1 a05c57911e6ec9eba4e5539a095a6a86e2bf7c2c +✓ Loaded existing review ([..]) for patch a05c57911e6ec9eba4e5539a095a6a86e2bf7c2c +✓ All hunks have been reviewed +``` diff --git a/radicle-cli/src/commands/ls.rs b/radicle-cli/src/commands/ls.rs index b06861c6..6664a524 100644 --- a/radicle-cli/src/commands/ls.rs +++ b/radicle-cli/src/commands/ls.rs @@ -81,7 +81,7 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> { continue; } }; - let head = term::format::oid(head); + let head = term::format::oid(head).into(); table.push([ term::format::bold(proj.name().to_owned()), term::format::tertiary(id.urn()), diff --git a/radicle-cli/src/commands/patch/show.rs b/radicle-cli/src/commands/patch/show.rs index c3e3a0ce..745a2ef1 100644 --- a/radicle-cli/src/commands/patch/show.rs +++ b/radicle-cli/src/commands/patch/show.rs @@ -41,7 +41,9 @@ fn patch_commits(patch: &patch::Patch, stored: &Repository) -> anyhow::Result( + term::format::oid(commit.id()).into(), + )), term::label(term::format::default( commit.summary().unwrap_or_default().to_owned(), )), diff --git a/radicle-cli/src/commands/review.rs b/radicle-cli/src/commands/review.rs index da4f1a60..2fe01b20 100644 --- a/radicle-cli/src/commands/review.rs +++ b/radicle-cli/src/commands/review.rs @@ -1,3 +1,8 @@ +#[path = "review/builder.rs"] +mod builder; +#[path = "review/diff.rs"] +mod diff; + use std::ffi::OsString; use std::str::FromStr; @@ -5,7 +10,7 @@ use anyhow::{anyhow, Context}; use radicle::cob::patch::{Patches, RevisionIx, Verdict}; use radicle::prelude::*; -use radicle::rad; +use radicle::{git, rad}; use crate::git::Rev; use crate::terminal as term; @@ -19,13 +24,23 @@ pub const HELP: Help = Help { usage: r#" Usage - rad review [] [--accept|--reject] [-m []] [