#![forbid(unsafe_code)]
#![warn(missing_docs)]
use clap::Parser;
use ferrous_forge::{Result, cli::Cli, commands};
#[tokio::main]
async fn main() -> Result<()> {
tracing_subscriber::fmt::init();
let cli = Cli::parse();
execute_command(cli.command).await
}
async fn execute_command(command: commands::Commands) -> Result<()> {
match command {
commands::Commands::Init { force, project } => {
if project {
commands::init::execute_project().await
} else {
commands::init::execute(force).await
}
}
commands::Commands::Status => commands::status::execute().await,
commands::Commands::Update {
channel,
rules_only,
dry_run,
} => commands::update::execute(channel, rules_only, dry_run).await,
commands::Commands::Config { command } => {
if let Some(cmd) = command {
commands::config::execute_with_subcommand(cmd).await
} else {
commands::config::show_help();
Ok(())
}
}
commands::Commands::Validate {
path,
ai_report,
compare_previous: _,
locked_only,
} => commands::validate::execute(path, ai_report, locked_only).await,
commands::Commands::Rollback { version } => commands::rollback::execute(version).await,
commands::Commands::Uninstall { confirm } => commands::uninstall::execute(confirm).await,
commands::Commands::Rust { command } => execute_rust_command(command).await,
commands::Commands::Edition { command } => execute_edition_command(command).await,
commands::Commands::Template { command } => command.execute().await,
commands::Commands::Safety { command } => execute_safety_command(command).await,
commands::Commands::Fix {
path,
only,
skip,
dry_run,
limit,
ai_analysis,
} => commands::fix::execute_with_ai(path, only, skip, dry_run, limit, ai_analysis).await,
}
}
async fn execute_rust_command(command: commands::RustCommand) -> Result<()> {
match command {
commands::RustCommand::Check { verbose, enforce } => {
commands::rust::handle_check(verbose, enforce).await
}
commands::RustCommand::Recommend { stable_only } => {
commands::rust::handle_recommend(stable_only).await
}
commands::RustCommand::List { count, toolchains } => {
commands::rust::handle_list(count, toolchains).await
}
commands::RustCommand::Releases { count } => commands::rust::handle_releases(count).await,
commands::RustCommand::CheckUpdates { verbose } => {
commands::rust::handle_check_updates(verbose).await
}
commands::RustCommand::ReleaseNotes { version, detailed } => {
commands::rust::handle_release_notes(version, detailed).await
}
commands::RustCommand::Security { fail_on_issues } => {
commands::rust::handle_security(fail_on_issues).await
}
commands::RustCommand::Update {
dry_run,
yes,
self_update,
} => commands::rust::handle_update(dry_run, yes, self_update).await,
commands::RustCommand::InstallToolchain { channel, default } => {
commands::rust::handle_install_toolchain(channel, default).await
}
commands::RustCommand::UninstallToolchain { channel } => {
commands::rust::handle_uninstall_toolchain(channel).await
}
commands::RustCommand::Switch { channel } => commands::rust::handle_switch(channel).await,
}
}
async fn execute_edition_command(command: commands::EditionCommand) -> Result<()> {
match command {
commands::EditionCommand::Check { path } => commands::edition::handle_check(&path).await,
commands::EditionCommand::Migrate {
edition,
no_backup,
test,
idioms,
} => commands::edition::handle_migrate(&edition, no_backup, test, idioms).await,
commands::EditionCommand::Analyze { path, edition } => {
commands::edition::handle_analyze(&path, &edition).await
}
}
}
async fn execute_safety_command(command: commands::SafetyCommand) -> Result<()> {
match command {
commands::SafetyCommand::Status => commands::safety::handle_status().await,
commands::SafetyCommand::Install { force, path, cargo } => {
commands::safety::handle_install(force, &path, cargo).await
}
commands::SafetyCommand::Check {
stage,
path,
verbose,
} => commands::safety::handle_check(&stage, &path, verbose).await,
commands::SafetyCommand::Test { path } => {
commands::safety::test_individual_checks(&path).await
}
commands::SafetyCommand::Bypass {
stage,
reason,
duration,
user,
} => commands::safety::bypass_cmd::handle_bypass(stage, reason, duration, user).await,
commands::SafetyCommand::Audit { limit } => {
commands::safety::bypass_cmd::handle_audit(limit).await
}
commands::SafetyCommand::CheckBypass { stage } => {
commands::safety::handle_check_bypass(stage).await
}
commands::SafetyCommand::Uninstall { path, confirm } => {
commands::safety::handle_uninstall(&path, confirm).await
}
commands::SafetyCommand::Config { show, set, get } => {
if show {
commands::safety::config_cmd::handle_config_show().await
} else if let Some(key_value) = set {
let parts: Vec<&str> = key_value.splitn(2, '=').collect();
if parts.len() == 2 {
commands::safety::config_cmd::handle_config_set(
parts[0].to_string(),
parts[1].to_string(),
)
.await
} else {
Err(ferrous_forge::Error::config(
"Invalid format. Use: --set key=value".to_string(),
))
}
} else if let Some(key) = get {
commands::safety::config_cmd::handle_config_get(key).await
} else {
commands::safety::config_cmd::handle_config_show().await
}
}
commands::SafetyCommand::Report { last, audit, stage } => {
commands::safety::report_cmd::handle_report(last, audit, stage).await
}
commands::SafetyCommand::Stats { days } => {
commands::safety::stats_cmd::handle_stats(days).await
}
}
}