Skip to main content

git_same/commands/
init.rs

1//! Init command handler.
2//!
3//! Checks system requirements and writes the global configuration file.
4
5use crate::checks::{self, CheckResult};
6use crate::cli::InitArgs;
7use crate::config::Config;
8use crate::errors::{AppError, Result};
9use crate::output::Output;
10
11/// Initialize gisa configuration.
12pub async fn run(args: &InitArgs, output: &Output) -> Result<()> {
13    // Step 1: Run requirement checks
14    output.info("Checking requirements...");
15    let results = checks::check_requirements().await;
16    display_check_results(&results, output);
17
18    let critical_failures: Vec<&CheckResult> =
19        results.iter().filter(|r| !r.passed && r.critical).collect();
20    if !critical_failures.is_empty() {
21        output.warn("Some critical checks failed. You can still create the config, but gisa may not work correctly.");
22    }
23
24    // Step 2: Write global config
25    let config_path = match args.path.clone() {
26        Some(p) => p,
27        None => Config::default_path()?,
28    };
29
30    if config_path.exists() && !args.force {
31        return Err(AppError::config(format!(
32            "Config file already exists at {}. Use --force to overwrite.",
33            config_path.display()
34        )));
35    }
36
37    // Create parent directory
38    if let Some(parent) = config_path.parent() {
39        std::fs::create_dir_all(parent)
40            .map_err(|e| AppError::path(format!("Failed to create config directory: {}", e)))?;
41    }
42
43    // Write default config
44    let default_config = Config::default_toml();
45    std::fs::write(&config_path, default_config)
46        .map_err(|e| AppError::path(format!("Failed to write config: {}", e)))?;
47
48    output.success(&format!("Created config at {}", config_path.display()));
49
50    // Step 3: Next steps
51    output.info("Run 'git-same setup' to configure a local folder as workspace.");
52
53    Ok(())
54}
55
56/// Display check results with pass/fail indicators.
57fn display_check_results(results: &[CheckResult], output: &Output) {
58    for result in results {
59        if result.passed {
60            output.success(&format!("  {} — {}", result.name, result.message));
61        } else if result.critical {
62            output.error(&format!("  {} — {}", result.name, result.message));
63            if let Some(ref suggestion) = result.suggestion {
64                output.info(&format!("    {}", suggestion));
65            }
66        } else {
67            output.warn(&format!("  {} — {}", result.name, result.message));
68            if let Some(ref suggestion) = result.suggestion {
69                output.info(&format!("    {}", suggestion));
70            }
71        }
72    }
73}
74
75#[cfg(test)]
76#[path = "init_tests.rs"]
77mod tests;