1use anyhow::Result;
2use clap::Args;
3use gn_core::namespace::Namespace;
4use gn_core::NotesEngine;
5use std::collections::HashMap;
6use std::process::Command;
7
8#[derive(Args, Debug)]
9pub struct DiffArgs {
10 pub target: Option<String>,
12
13 #[arg(short, long, default_value = "comments")]
15 pub namespace: String,
16}
17
18pub fn run(args: &DiffArgs) -> Result<()> {
19 let engine = NotesEngine::new(".");
20 let ns = Namespace::from_str(&args.namespace);
21 let notes = engine.read_notes(&ns).unwrap_or_default();
22
23 let mut notes_by_file: HashMap<String, Vec<&gn_core::note::Note>> = HashMap::new();
25 for note in ¬es {
26 if let Some(ref f) = note.file {
27 notes_by_file.entry(f.clone()).or_default().push(note);
28 }
29 }
30
31 let mut git_cmd = Command::new("git");
32 git_cmd.arg("diff");
33 if let Some(ref t) = args.target {
34 git_cmd.arg(t);
35 }
36
37 let output = git_cmd.output()?;
38 let diff_text = String::from_utf8_lossy(&output.stdout);
39
40 if diff_text.trim().is_empty() {
41 println!("No diff found.");
42 return Ok(());
43 }
44
45 let mut current_file: Option<String> = None;
46
47 for line in diff_text.lines() {
48 if line.starts_with("+++ b/") {
49 let f = line.trim_start_matches("+++ b/").to_string();
50 current_file = Some(f);
51 println!("{}", line);
52 continue;
53 }
54
55 if line.starts_with("@@ ") {
56 println!("\x1b[36m{}\x1b[0m", line);
57 if let Some(ref f) = current_file {
59 if let Some(file_notes) = notes_by_file.get(f) {
60 for n in file_notes {
61 let id_short = &n.id.to_string()[..8];
62 let line_str = n.line_start.map(|l| format!(":{}", l)).unwrap_or_default();
63 println!(
64 " \x1b[33m💬 Note [{}] on {}{} by {}: \"{}\"\x1b[0m",
65 id_short,
66 f,
67 line_str,
68 n.author.split('<').next().unwrap_or(&n.author).trim(),
69 n.body.replace('\n', " ").chars().take(60).collect::<String>()
70 );
71 }
72 }
73 }
74 continue;
75 }
76
77 if line.starts_with('+') {
78 println!("\x1b[32m{}\x1b[0m", line);
79 } else if line.starts_with('-') {
80 println!("\x1b[31m{}\x1b[0m", line);
81 } else {
82 println!("{}", line);
83 }
84 }
85
86 Ok(())
87}