spec_driven_docs/commands/
assess.rs1use crate::cli::assess::AssessArgs;
7use crate::context::AppContext;
8use crate::error::AppError;
9use crate::output;
10use crate::services::assess::assess;
11
12pub fn run(ctx: &AppContext, args: AssessArgs) -> Result<(), AppError> {
19 let target = if args.target.is_absolute() {
20 args.target
21 } else if args.target == "." {
22 ctx.cwd.clone()
23 } else {
24 return Err(AppError::Usage("target must be absolute or .".to_string()));
25 };
26 let report = assess(
27 &target,
28 &crate::release::embedded::EmbeddedReleaseBundle::new(),
29 )?;
30 if args.json {
31 return output::json(&report);
32 }
33 output::line(format!(
34 "classification: {}",
35 report.classification.as_str()
36 ));
37 output::line(format!("instance: {}", report.instance.instance));
38 output::line(format!("doc roots: {}", join_or_none(&report.doc_roots)));
39 output::line(format!(
40 "populated doc roots: {}",
41 join_or_none(&report.populated_doc_roots)
42 ));
43 output::line(format!("document files: {}", report.documents.count));
44 output::line(format!(
45 "methodology markers: {}",
46 join_or_none(&report.methodology_markers)
47 ));
48 for (profile, existing) in &report.collisions {
49 output::line(format!("collisions ({profile}): {}", existing.len()));
50 }
51 Ok(())
52}
53
54fn join_or_none(items: &[String]) -> String {
55 if items.is_empty() {
56 "none".to_string()
57 } else {
58 items.join(", ")
59 }
60}