ferrous_forge/commands/
init.rs1use crate::{config::Config, Result};
4use console::style;
5
6pub async fn execute(force: bool) -> Result<()> {
8 println!(
9 "{}",
10 style("🔨 Initializing Ferrous Forge...").bold().cyan()
11 );
12
13 let config = Config::load_or_default().await?;
14 if check_already_initialized(&config, force)? {
15 return Ok(());
16 }
17
18 perform_initialization(config).await?;
19 print_completion_message();
20
21 Ok(())
22}
23
24fn check_already_initialized(config: &Config, force: bool) -> Result<bool> {
26 if config.is_initialized() && !force {
27 println!(
28 "{}",
29 style("✅ Ferrous Forge is already initialized!").green()
30 );
31 println!("Use --force to reinitialize.");
32 return Ok(true);
33 }
34 Ok(false)
35}
36
37async fn perform_initialization(config: Config) -> Result<()> {
39 println!("📁 Creating configuration directories...");
40 config.ensure_directories().await?;
41
42 println!("🔧 Setting up cargo command hijacking...");
43 install_cargo_hijacking().await?;
44
45 println!("📋 Installing clippy configuration...");
46 install_clippy_config().await?;
47
48 println!("🐚 Installing shell integration...");
49 install_shell_integration().await?;
50
51 let mut config = config;
52 config.mark_initialized();
53 config.save().await?;
54
55 Ok(())
56}
57
58fn print_completion_message() {
60 println!(
61 "{}",
62 style("🎉 Ferrous Forge initialization complete!")
63 .bold()
64 .green()
65 );
66 println!();
67 println!("Next steps:");
68 println!("• Restart your shell or run: source ~/.bashrc");
69 println!("• Create a new project: cargo new my-project");
70 println!("• All new projects will automatically use Edition 2024 + strict standards!");
71}
72
73async fn install_cargo_hijacking() -> Result<()> {
74 let home_dir =
78 dirs::home_dir().ok_or_else(|| crate::Error::config("Could not find home directory"))?;
79
80 let bin_dir = home_dir.join(".local").join("bin");
81 tokio::fs::create_dir_all(&bin_dir).await?;
82
83 let cargo_wrapper = include_str!("../../templates/cargo-wrapper.sh");
85 let cargo_path = bin_dir.join("cargo");
86 tokio::fs::write(&cargo_path, cargo_wrapper).await?;
87
88 #[cfg(unix)]
90 {
91 use std::os::unix::fs::PermissionsExt;
92 let mut perms = tokio::fs::metadata(&cargo_path).await?.permissions();
93 perms.set_mode(0o755);
94 tokio::fs::set_permissions(&cargo_path, perms).await?;
95 }
96
97 Ok(())
98}
99
100async fn install_clippy_config() -> Result<()> {
101 let home_dir =
103 dirs::home_dir().ok_or_else(|| crate::Error::config("Could not find home directory"))?;
104
105 let clippy_config = include_str!("../../templates/clippy.toml");
106 let clippy_path = home_dir.join(".clippy.toml");
107 tokio::fs::write(&clippy_path, clippy_config).await?;
108
109 Ok(())
110}
111
112async fn install_shell_integration() -> Result<()> {
113 let home_dir =
115 dirs::home_dir().ok_or_else(|| crate::Error::config("Could not find home directory"))?;
116
117 let shell_config = format!(
118 r#"
119# Ferrous Forge - Rust Development Standards Enforcer
120export PATH="$HOME/.local/bin:$PATH"
121
122# Enable Ferrous Forge for all Rust development
123export FERROUS_FORGE_ENABLED=1
124"#
125 );
126
127 for shell_file in &[".bashrc", ".zshrc", ".profile"] {
129 let shell_path = home_dir.join(shell_file);
130 if shell_path.exists() {
131 let mut contents = tokio::fs::read_to_string(&shell_path).await?;
132 if !contents.contains("Ferrous Forge") {
133 contents.push_str(&shell_config);
134 tokio::fs::write(&shell_path, contents).await?;
135 }
136 }
137 }
138
139 Ok(())
140}