Skip to main content

autom8/commands/
init.rs

1//! Init command handler.
2//!
3//! Initializes the autom8 config directory structure for a project.
4
5use crate::completion;
6use crate::error::Result;
7use crate::output::{BOLD, CYAN, GRAY, GREEN, RESET, YELLOW};
8
9/// Initialize autom8 configuration for the current project.
10///
11/// Creates the following directory structure:
12/// - `~/.config/autom8/` - Base config directory
13/// - `~/.config/autom8/config.toml` - Global configuration
14/// - `~/.config/autom8/<project>/` - Project-specific directory
15/// - `~/.config/autom8/<project>/spec/` - Spec files
16/// - `~/.config/autom8/<project>/runs/` - Archived run states
17///
18/// # Returns
19///
20/// * `Ok(())` on success
21/// * `Err(Autom8Error)` if directory creation fails
22pub fn init_command() -> Result<()> {
23    println!("Initializing autom8...");
24    println!();
25
26    // Create base config directory ~/.config/autom8/
27    let (config_dir, config_created) = crate::config::ensure_config_dir()?;
28    if config_created {
29        println!("  {GREEN}Created{RESET} {}", config_dir.display());
30    } else {
31        println!("  {GRAY}Exists{RESET}  {}", config_dir.display());
32    }
33
34    // Reset global config file to defaults
35    let global_config_path = crate::config::global_config_path()?;
36    crate::config::save_global_config(&crate::config::Config::default())?;
37    println!(
38        "Created default configuration at {}",
39        global_config_path.display()
40    );
41
42    // Create project-specific config directory with subdirectories
43    let (project_dir, project_created) = crate::config::ensure_project_config_dir()?;
44    if project_created {
45        println!("  {GREEN}Created{RESET} {}", project_dir.display());
46        println!("  {GREEN}Created{RESET} {}/spec/", project_dir.display());
47        println!("  {GREEN}Created{RESET} {}/runs/", project_dir.display());
48    } else {
49        println!("  {GRAY}Exists{RESET}  {}", project_dir.display());
50    }
51
52    println!();
53    println!("{GREEN}Initialization complete!{RESET}");
54    println!();
55    println!("Config directory structure:");
56    println!("  {CYAN}{}{RESET}", project_dir.display());
57    println!("    ├── spec/  (spec markdown and JSON files)");
58    println!("    └── runs/  (archived run states)");
59    // Install shell completions
60    println!();
61    println!("{BOLD}Shell completions:{RESET}");
62    match completion::install_completions() {
63        Ok(result) => {
64            println!(
65                "  {GREEN}Installed{RESET} {} completions to {}",
66                result.shell,
67                result.path.display()
68            );
69            if let Some(instructions) = result.setup_instructions {
70                println!();
71                println!("{YELLOW}Note:{RESET} {}", instructions);
72            }
73        }
74        Err(e) => {
75            // Don't fail init for completion errors - just inform the user
76            let msg = e.to_string();
77            if msg.contains("Unsupported shell") {
78                println!("  {YELLOW}Skipped{RESET} Shell completions not available for your shell");
79                println!("         Supported shells: bash, zsh, fish");
80            } else if msg.contains("$SHELL") {
81                println!("  {YELLOW}Skipped{RESET} Could not detect shell ($SHELL not set)");
82            } else {
83                println!(
84                    "  {YELLOW}Warning{RESET} Could not install completions: {}",
85                    e
86                );
87            }
88        }
89    }
90
91    println!();
92    println!("{BOLD}Next steps:{RESET}");
93    println!("  Run {CYAN}autom8{RESET} to start creating a spec");
94
95    Ok(())
96}