Skip to main content

chronicle/cli/
contracts.rs

1use crate::error::Result;
2use crate::git::CliOps;
3
4/// Run the `git chronicle contracts` command.
5pub fn run(path: String, anchor: Option<String>, format: String, compact: bool) -> Result<()> {
6    let repo_dir = std::env::current_dir().map_err(|e| crate::error::ChronicleError::Io {
7        source: e,
8        location: snafu::Location::default(),
9    })?;
10    let git_ops = CliOps::new(repo_dir);
11
12    let query = crate::read::contracts::ContractsQuery { file: path, anchor };
13
14    let output = crate::read::contracts::query_contracts(&git_ops, &query).map_err(|e| {
15        crate::error::ChronicleError::Git {
16            source: e,
17            location: snafu::Location::default(),
18        }
19    })?;
20
21    match format.as_str() {
22        "json" => {
23            let json = if compact {
24                let compact_out = serde_json::json!({
25                    "contracts": output.contracts,
26                    "dependencies": output.dependencies,
27                });
28                serde_json::to_string_pretty(&compact_out)
29            } else {
30                serde_json::to_string_pretty(&output)
31            }
32            .map_err(|e| crate::error::ChronicleError::Json {
33                source: e,
34                location: snafu::Location::default(),
35            })?;
36            println!("{json}");
37        }
38        _ => {
39            if output.contracts.is_empty() && output.dependencies.is_empty() {
40                println!("No contracts or dependencies found.");
41                return Ok(());
42            }
43            if !output.contracts.is_empty() {
44                println!("Contracts:");
45                for c in &output.contracts {
46                    let anchor_str = c
47                        .anchor
48                        .as_ref()
49                        .map(|a| format!(":{}", a))
50                        .unwrap_or_default();
51                    println!(
52                        "  [{}] {}{}: {}",
53                        c.source, c.file, anchor_str, c.description
54                    );
55                }
56            }
57            if !output.dependencies.is_empty() {
58                println!("Dependencies:");
59                for d in &output.dependencies {
60                    let anchor_str = d
61                        .anchor
62                        .as_ref()
63                        .map(|a| format!(":{}", a))
64                        .unwrap_or_default();
65                    println!(
66                        "  {}{} -> {}:{} ({})",
67                        d.file, anchor_str, d.target_file, d.target_anchor, d.assumption
68                    );
69                }
70            }
71        }
72    }
73
74    Ok(())
75}