mod docs;
mod init;
mod proc;
mod project;
mod run;
mod settings;
mod test;
mod tools;
mod update;
mod update_check;
use anyhow::Result;
use clap::{Parser, Subcommand, ValueEnum};
#[derive(Parser)]
#[command(name = "cfasim", about = "CFA Simulator CLI")]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
Init {
#[arg(long, default_missing_value = ".")]
dir: Option<String>,
#[arg(long)]
template: Option<TemplateArg>,
#[arg(long)]
local: bool,
},
Update,
Tools {
#[arg(long)]
offline: bool,
},
Docs {
#[arg(long)]
json: bool,
},
Test {
#[arg(long)]
unit: bool,
#[arg(long)]
e2e: bool,
},
Run {
#[arg(trailing_var_arg = true, allow_hyphen_values = true)]
args: Vec<String>,
},
}
#[derive(Clone, ValueEnum)]
enum TemplateArg {
Python,
Rust,
}
fn main() -> Result<()> {
let cli = Cli::parse();
let is_update = matches!(cli.command, Commands::Update);
let is_tools = matches!(cli.command, Commands::Tools { .. });
let is_docs = matches!(cli.command, Commands::Docs { .. });
let is_test = matches!(cli.command, Commands::Test { .. });
let is_run = matches!(cli.command, Commands::Run { .. });
if !is_update {
settings::prompt_for_updates_if_first_run();
}
let result = match cli.command {
Commands::Init {
dir,
template,
local,
} => {
let template = template.map(|t| match t {
TemplateArg::Python => init::Template::Python,
TemplateArg::Rust => init::Template::Rust,
});
init::run(dir, template, local).map_err(|e| anyhow::anyhow!("{e}"))
}
Commands::Update => update::run(),
Commands::Tools { offline } => tools::run(offline),
Commands::Docs { json } => docs::run(json),
Commands::Test { unit, e2e } => test::run(unit, e2e),
Commands::Run { args } => run::run(args),
};
if !is_update && !is_tools && !is_docs && !is_test && !is_run {
update_check::maybe_print_update_hint();
}
result
}