- Settings (gear in the branch header) edits the branch's .branchgraph in its worktree; never committed or pushed. Settings are read per branch: worktree file, else committed on the branch, else main's. - Run and Send ask once about commands main lacks (run, setup, copy, agent, verify); approval covers exactly what was shown. - copy patterns stay inside the checkout; never written through a symlink. - Send dialog: review, edit, copy brief then mark as sent; only the comments and text that went out are marked, also for `brief --ack`. - Setup still runs when saving Settings made the worktree. - Code-review skill fixes from seven rounds; drop --quiet and the hostname URL.
80 lines
2.6 KiB
Rust
80 lines
2.6 KiB
Rust
mod fixture;
|
|
|
|
use std::process::Command;
|
|
|
|
use branchgraph::git;
|
|
use branchgraph::state::{self, Anchor, Comment};
|
|
use fixture::{Fixture, git as run};
|
|
|
|
/// `branchgraph brief` from inside the agent's worktree prints the unsent
|
|
/// review of the branch checked out there; `--ack` marks it sent.
|
|
#[test]
|
|
fn brief_prints_the_review_of_the_current_worktree_and_ack_clears_it() {
|
|
let f = Fixture::new();
|
|
let xdg = tempfile::tempdir().unwrap();
|
|
// This test binary holds one test, so the variable cannot race another.
|
|
unsafe { std::env::set_var("XDG_STATE_HOME", xdg.path()) };
|
|
let repo = git::open(&f.clone).unwrap();
|
|
let dir = state::dir(&repo).unwrap();
|
|
let tip = run(&f.clone, &["rev-parse", "agent/x"]);
|
|
state::update(&dir, "agent/x", |r| {
|
|
r.comments.push(Comment {
|
|
id: 1,
|
|
anchor: Anchor::Lines {
|
|
path: "agent.txt".into(),
|
|
start: 2,
|
|
end: 2,
|
|
},
|
|
excerpt: "y".into(),
|
|
text: "Say why y follows x.".into(),
|
|
tip: tip.clone(),
|
|
sent: None,
|
|
})
|
|
})
|
|
.unwrap();
|
|
|
|
let wt = f.clone.with_file_name("wt-agent");
|
|
let bg = |args: &[&str]| {
|
|
let out = Command::new(env!("CARGO_BIN_EXE_branchgraph"))
|
|
.args(args)
|
|
.current_dir(&wt)
|
|
.env("XDG_STATE_HOME", xdg.path())
|
|
.output()
|
|
.unwrap();
|
|
assert!(
|
|
out.status.success(),
|
|
"{}",
|
|
String::from_utf8_lossy(&out.stderr)
|
|
);
|
|
String::from_utf8(out.stdout).unwrap()
|
|
};
|
|
let brief = bg(&["brief"]);
|
|
assert!(brief.contains("# Review of `agent/x`"), "{brief}");
|
|
assert!(
|
|
brief.contains("agent.txt:2 @") && brief.contains("Say why y follows x."),
|
|
"{brief}"
|
|
);
|
|
// A comment added, or edited, after the agent read the brief stays
|
|
// unsent on --ack: the agent never saw that text.
|
|
state::update(&dir, "agent/x", |r| {
|
|
r.comments[0].text = "Say why y follows x, with a test.".into();
|
|
r.add(Comment {
|
|
id: 0,
|
|
anchor: Anchor::Branch,
|
|
excerpt: String::new(),
|
|
text: "Also add a test.".into(),
|
|
tip: tip.clone(),
|
|
sent: None,
|
|
})
|
|
})
|
|
.unwrap();
|
|
assert!(bg(&["brief", "--ack"]).contains("Marked 0 comments"));
|
|
let rest = bg(&["brief"]);
|
|
assert!(
|
|
rest.contains("Also add a test.") && rest.contains("with a test."),
|
|
"{rest}"
|
|
);
|
|
assert!(bg(&["brief", "--ack"]).contains("Marked 2 comments"));
|
|
assert!(bg(&["brief"]).contains("No unsent review for agent/x."));
|
|
}
|