git_atomic/cli/commands/
status.rs1use crate::cli::StatusArgs;
2use crate::cli::output::Printer;
3use crate::core::{ComponentMatcher, Error};
4use crate::git::branch::BranchManager;
5use std::path::{Path, PathBuf};
6
7pub fn run(args: &StatusArgs, config_path: &Path, printer: &Printer) -> Result<(), Error> {
8 let repo = crate::git::open_repo(
9 &std::env::current_dir().map_err(|e| Error::General(e.to_string()))?,
10 )?;
11
12 let resolved = crate::config::load_layered_config(Some(&repo), config_path)?;
13
14 if !args.no_config {
16 printer.print_config_provenance(&resolved);
17 }
18
19 let warnings = crate::config::layered::validate_resolved(&resolved);
21 for w in &warnings {
22 printer.print_config_warning(w);
23 }
24
25 if resolved.components.is_empty() {
26 return Ok(());
27 }
28
29 let cfg = resolved.to_config();
30 let matcher = ComponentMatcher::from_config(&cfg)?;
31
32 let source_id = crate::git::resolve_commit(&repo, &args.source_ref)?;
33 let files = crate::git::changed_files(&repo, source_id)?;
34 let path_refs: Vec<&Path> = files.iter().map(|p| p.as_path()).collect();
35 let (grouped, _) = matcher.group_files(&path_refs);
36
37 let base_id = crate::git::resolve_commit(&repo, &cfg.settings.base_branch)?;
38 let branch_mgr = BranchManager::new(&repo, base_id, cfg.settings.branch_template.clone());
39
40 let mut components = Vec::new();
41 for (name, comp_files) in &grouped {
42 let comp_cfg = cfg.components.iter().find(|c| c.name == *name);
43 let branch_override = comp_cfg.and_then(|c| c.branch.as_deref());
44 let ref_name = branch_mgr.branch_ref_name(name, branch_override);
45 let state = branch_mgr.check_state(&ref_name)?;
46 let branch_display = ref_name
47 .strip_prefix("refs/heads/")
48 .unwrap_or(&ref_name)
49 .to_string();
50
51 components.push((
52 name.to_string(),
53 comp_files
54 .iter()
55 .map(|p| p.to_path_buf())
56 .collect::<Vec<PathBuf>>(),
57 state,
58 branch_display,
59 ));
60 }
61
62 printer.print_status(&components);
63 Ok(())
64}