Skip to main content

hexz_cli/cmd/data/
status.rs

1//! Show status of local changes in a workspace.
2
3use anyhow::{Context, Result};
4use colored::Colorize;
5use std::path::PathBuf;
6use walkdir::WalkDir;
7
8use super::workspace::Workspace;
9
10/// Execute the `hexz status` command to show workspace changes.
11pub fn run(path: Option<PathBuf>) -> Result<()> {
12    let start_path = path.unwrap_or(std::env::current_dir().context("Failed to get current directory")?);
13
14    let ws = Workspace::find(&start_path)?
15        .ok_or_else(|| anyhow::anyhow!("Not in a hexz workspace (no .hexz found)"))?;
16
17    let overlay = ws.overlay_path();
18
19    println!("{} Workspace   {}", "╭".dimmed(), ws.root.display().to_string().cyan());
20    if let Some(b) = ws.config.base_archive {
21        println!("{} Base        {}", "╰".dimmed(), b.display().to_string().bright_black());
22    } else {
23        println!("{} Base        {}", "╰".dimmed(), "(none)".bright_black());
24    }
25
26    let mut changes = Vec::new();
27    for entry in WalkDir::new(&overlay).into_iter().filter_map(std::result::Result::ok) {
28        if entry.path() == overlay { continue; }
29
30        let rel = entry.path().strip_prefix(&overlay)?;
31        if entry.file_type().is_dir() {
32            changes.push(format!("    {} {} {}", "→".dimmed(), rel.display(), "(dir)".bright_black()));
33        } else {
34            changes.push(format!("    {} {} {}", "→".dimmed(), rel.display().to_string().green(), "(mod)".bright_black()));
35        }
36    }
37
38    if changes.is_empty() {
39        println!("  {} No changes detected.", "→".green());
40    } else {
41        println!("  {} Changes detected:", "→".yellow());
42        for change in changes {
43            println!("{change}");
44        }
45    }
46
47    Ok(())
48}