callisto_cli/commands/
validate.rs1use std::process::ExitCode;
2
3use callisto_graph::commands::ValidateOptions;
4
5use crate::cli::{GlobalArgs, OutputFormat, ValidateArgs};
6use crate::error::CliError;
7use crate::output::write_json;
8use crate::render;
9use crate::runner::CliCommandRunner;
10use crate::workspace::load_workspace;
11
12pub fn handle(args: ValidateArgs, global: &GlobalArgs) -> Result<ExitCode, CliError> {
13 let runner = CliCommandRunner;
14 let ws = load_workspace(global, &runner)?;
15
16 let opts = ValidateOptions {
17 staged: args.staged,
18 since: args.since,
19 strict: args.strict,
20 strict_graph: args.strict_graph,
21 };
22
23 let report = callisto_graph::commands::validate(&ws, &opts)?;
24
25 match global.format {
26 OutputFormat::Json => write_json(&mut std::io::stdout(), &report)?,
27 OutputFormat::Text => render::render_validate(&report, &mut std::io::stdout())?,
28 }
29
30 if report.ok {
31 Ok(ExitCode::SUCCESS)
32 } else {
33 Ok(ExitCode::FAILURE)
34 }
35}
36
37#[cfg(test)]
38mod tests {
39 use super::*;
40
41 fn seed_workspace_with_unknown_package_changeset() -> tempfile::TempDir {
45 let tmp = tempfile::TempDir::new().unwrap();
46 let root = tmp.path();
47 std::fs::write(root.join("Cargo.toml"), "[workspace]\nmembers = []\nresolver = \"2\"\n").unwrap();
48 std::fs::write(root.join("callisto.toml"), "").unwrap();
49 let changeset_dir = root.join(".changeset");
50 std::fs::create_dir_all(&changeset_dir).unwrap();
51 std::fs::write(
52 changeset_dir.join("bad.md"),
53 "---\nnot-a-real-package: patch\n---\n\nSome change.\n",
54 )
55 .unwrap();
56 tmp
57 }
58
59 fn opts() -> ValidateArgs {
60 ValidateArgs {
61 staged: false,
62 since: None,
63 strict: false,
64 strict_graph: false,
65 }
66 }
67
68 #[test]
69 fn handle_text_format_reports_clean_workspace_as_success() {
70 let tmp = tempfile::TempDir::new().unwrap();
71 let root = tmp.path();
72 std::fs::write(root.join("Cargo.toml"), "[workspace]\nmembers = []\nresolver = \"2\"\n").unwrap();
73 std::fs::write(root.join("callisto.toml"), "").unwrap();
74
75 let global = GlobalArgs {
76 format: OutputFormat::Text,
77 cwd: root.to_path_buf(),
78 dry_run: false,
79 };
80
81 let result = handle(opts(), &global);
82 assert_eq!(result.unwrap(), ExitCode::SUCCESS);
83 }
84
85 #[test]
86 fn handle_returns_failure_exit_code_when_report_is_not_ok() {
87 let tmp = seed_workspace_with_unknown_package_changeset();
88 let global = GlobalArgs {
89 format: OutputFormat::Json,
90 cwd: tmp.path().to_path_buf(),
91 dry_run: false,
92 };
93
94 let result = handle(opts(), &global).expect("validate should not error on an invalid-but-parseable changeset");
95 assert_eq!(
96 result,
97 ExitCode::FAILURE,
98 "a workspace with a changeset naming an unknown package must report ok=false"
99 );
100 }
101}