ggen_cli_lib/cmds/project/
diff.rs1use clap::Args;
2use ggen_utils::error::Result;
3use std::process::Command;
4
5#[derive(Args, Debug)]
6pub struct DiffArgs {
7 pub template_ref: String,
9
10 #[arg(short = 'v', long = "var")]
12 pub vars: Vec<String>,
13
14 #[arg(short = 'U', long = "unified", default_value = "3")]
16 pub context: usize,
17
18 #[arg(long, default_value = "true")]
20 pub color: bool,
21}
22
23pub async fn run(args: &DiffArgs) -> Result<()> {
25 println!("Generating unified diff");
26
27 if args.template_ref.is_empty() {
29 return Err(ggen_utils::error::Error::new(
30 "Template reference cannot be empty",
31 ));
32 }
33
34 let mut variables = std::collections::HashMap::new();
36 for var in &args.vars {
37 if let Some((key, value)) = var.split_once('=') {
38 variables.insert(key.to_string(), value.to_string());
39 } else {
40 return Err(ggen_utils::error::Error::new_fmt(format_args!(
41 "Invalid variable format: {}. Expected key=value",
42 var
43 )));
44 }
45 }
46
47 let mut cmd = Command::new("cargo");
49 cmd.args(["make", "project-diff"]);
50 cmd.arg("--template").arg(&args.template_ref);
51 cmd.arg("--context").arg(args.context.to_string());
52
53 if args.color {
54 cmd.arg("--color");
55 }
56
57 for (key, value) in &variables {
58 cmd.arg("--var").arg(format!("{}={}", key, value));
59 }
60
61 let output = cmd.output().map_err(ggen_utils::error::Error::from)?;
62
63 if !output.status.success() {
64 let stderr = String::from_utf8_lossy(&output.stderr);
65 return Err(ggen_utils::error::Error::new_fmt(format_args!(
66 "Diff generation failed: {}",
67 stderr
68 )));
69 }
70
71 let stdout = String::from_utf8_lossy(&output.stdout);
72
73 if stdout.trim().is_empty() {
74 println!("✅ No differences found");
75 println!("No differences found between template output and current project state.");
76 } else {
77 println!("✅ Diff generated successfully");
78 println!("{}", stdout);
79 }
80
81 Ok(())
82}
83
84#[cfg(test)]
85mod tests {
86 use super::*;
87
88 #[tokio::test]
89 async fn test_diff_args_parsing() {
90 let args = DiffArgs {
91 template_ref: "test.tmpl".to_string(),
92 vars: vec!["name=Test".to_string()],
93 context: 5,
94 color: true,
95 };
96
97 assert_eq!(args.template_ref, "test.tmpl");
98 assert_eq!(args.context, 5);
99 }
100}