Skip to main content

greentic_bundle/cli/info/
command.rs

1use std::path::{Path, PathBuf};
2
3use anyhow::{Context, Result, anyhow};
4use clap::Args;
5
6use super::human;
7use super::report::InfoReport;
8
9#[derive(Debug, Args)]
10pub struct InfoArgs {
11    /// Path to a .gtbundle file or bundle workspace directory.
12    #[arg(value_name = "PATH", help = "cli.info.arg.path")]
13    pub path: PathBuf,
14
15    /// Emit the info report as JSON.
16    #[arg(long, default_value_t = false, help = "cli.info.flag.json")]
17    pub json: bool,
18}
19
20pub fn run(args: InfoArgs) -> Result<()> {
21    let report = build_report(&args.path)?;
22    if args.json {
23        let pretty =
24            serde_json::to_string_pretty(&report).context("serialize info report as JSON")?;
25        println!("{pretty}");
26    } else {
27        print!("{}", human::render(&report));
28    }
29    Ok(())
30}
31
32fn build_report(path: &Path) -> Result<InfoReport> {
33    if !path.exists() {
34        let path_display = path.display().to_string();
35        eprintln!(
36            "{}",
37            crate::i18n::trf(
38                "cli.info.error.not_a_bundle",
39                &[("0", path_display.as_str())]
40            )
41        );
42        std::process::exit(2);
43    }
44    if path.is_dir() {
45        return InfoReport::from_workspace(path).context("reading bundle workspace");
46    }
47    match path.extension().and_then(|s| s.to_str()) {
48        Some(ext) if ext.eq_ignore_ascii_case("gtbundle") => {
49            let opened = greentic_bundle_reader::open_artifact(path)
50                .map_err(|e| anyhow!("{}", e))
51                .context("reading bundle artifact")?;
52            Ok(InfoReport::from_opened_bundle(&opened))
53        }
54        _ => {
55            eprintln!(
56                "{}: not a .gtbundle file or bundle workspace",
57                path.display()
58            );
59            std::process::exit(2);
60        }
61    }
62}
63
64#[cfg(test)]
65mod tests {
66    use super::*;
67
68    #[test]
69    fn info_args_default_json_is_false() {
70        let args = InfoArgs {
71            path: PathBuf::from("demo.gtbundle"),
72            json: false,
73        };
74        assert!(!args.json);
75    }
76}