packc/cli/
lint.rs

1#![forbid(unsafe_code)]
2
3use std::path::PathBuf;
4
5use anyhow::Result;
6use clap::Parser;
7use greentic_flow::compile_ygtc_str;
8use tracing::info;
9
10use crate::config::load_pack_config;
11
12#[derive(Debug, Parser)]
13pub struct LintArgs {
14    /// Root directory of the pack (must contain pack.yaml)
15    #[arg(long = "in", value_name = "DIR")]
16    pub input: PathBuf,
17
18    /// Allow OCI component refs in extensions to be tag-based (default requires sha256 digest)
19    #[arg(long = "allow-oci-tags", default_value_t = false)]
20    pub allow_oci_tags: bool,
21}
22
23pub fn handle(args: LintArgs, json: bool) -> Result<()> {
24    let pack_dir = normalize(args.input);
25    info!(path = %pack_dir.display(), "linting pack");
26
27    let cfg = load_pack_config(&pack_dir)?;
28    crate::extensions::validate_components_extension(&cfg.extensions, args.allow_oci_tags)?;
29
30    let mut compiled = 0usize;
31    for flow in &cfg.flows {
32        let src = std::fs::read_to_string(&flow.file)?;
33        compile_ygtc_str(&src)?;
34        compiled += 1;
35    }
36
37    if json {
38        println!(
39            "{}",
40            serde_json::to_string_pretty(&serde_json::json!({
41                "status": "ok",
42                "pack_id": cfg.pack_id,
43                "version": cfg.version,
44                "flows": compiled,
45                "components": cfg.components.len(),
46                "dependencies": cfg.dependencies.len(),
47            }))?
48        );
49    } else {
50        println!(
51            "lint ok\n  pack: {}@{}\n  flows: {}\n  components: {}\n  dependencies: {}",
52            cfg.pack_id,
53            cfg.version,
54            compiled,
55            cfg.components.len(),
56            cfg.dependencies.len()
57        );
58    }
59
60    Ok(())
61}
62
63fn normalize(path: PathBuf) -> PathBuf {
64    if path.is_absolute() {
65        path
66    } else {
67        std::env::current_dir()
68            .unwrap_or_else(|_| PathBuf::from("."))
69            .join(path)
70    }
71}