use clap::{Parser, Subcommand};
mod build;
mod dev;
mod export;
mod migrate;
mod monitor;
mod new;
mod setup;
#[derive(Parser)]
#[command(name = "autumn", version, about = "The Autumn web framework CLI")]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
New {
name: String,
},
Build {
#[arg(long)]
debug: bool,
#[arg(short, long)]
package: Option<String>,
},
Dev {
#[arg(short, long)]
package: Option<String>,
#[arg(long)]
show_config: bool,
},
Setup {
#[arg(long)]
force: bool,
},
Migrate {
#[command(subcommand)]
action: Option<MigrateCommands>,
},
Monitor {
#[arg(short, long, default_value = "http://localhost:3000")]
url: String,
#[arg(short, long, default_value = "1")]
interval: u64,
},
Export {
#[arg(short, long, default_value = "http://localhost:3000")]
url: String,
#[arg(short, long, default_value = "autumn-diag.json")]
output: String,
},
}
#[derive(Subcommand)]
enum MigrateCommands {
Status,
}
fn main() {
let cli = Cli::parse();
match cli.command {
Commands::Build { debug, package } => build::run(debug, package.as_deref()),
Commands::Dev {
package,
show_config,
} => dev::run(package.as_deref(), show_config),
Commands::Migrate { action } => {
let action = match action {
Some(MigrateCommands::Status) => migrate::MigrateAction::Status,
None => migrate::MigrateAction::Run,
};
migrate::run(action);
}
Commands::Monitor { url, interval } => monitor::run(&url, interval),
Commands::Export { url, output } => export::run(&url, &output),
Commands::New { name } => new::run(&name),
Commands::Setup { force } => setup::run(force),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parse_new_subcommand() {
let cli = Cli::try_parse_from(["autumn", "new", "my-app"]).unwrap();
match cli.command {
Commands::New { ref name } => {
assert_eq!(name, "my-app");
}
_ => panic!("expected New command"),
}
}
#[test]
fn parse_new_with_underscores() {
let cli = Cli::try_parse_from(["autumn", "new", "my_app"]).unwrap();
match cli.command {
Commands::New { ref name } => {
assert_eq!(name, "my_app");
}
_ => panic!("expected New command"),
}
}
#[test]
fn parse_setup_subcommand() {
let cli = Cli::try_parse_from(["autumn", "setup"]).unwrap();
assert!(matches!(cli.command, Commands::Setup { force: false }));
}
#[test]
fn parse_setup_with_force() {
let cli = Cli::try_parse_from(["autumn", "setup", "--force"]).unwrap();
assert!(matches!(cli.command, Commands::Setup { force: true }));
}
#[test]
fn new_rejects_removed_wasm_flag() {
assert!(Cli::try_parse_from(["autumn", "new", "my-app", "--wasm"]).is_err());
}
#[test]
fn setup_rejects_removed_wasm_flag() {
assert!(Cli::try_parse_from(["autumn", "setup", "--wasm"]).is_err());
}
#[test]
fn no_args_is_error() {
assert!(Cli::try_parse_from(["autumn"]).is_err());
}
#[test]
fn new_missing_name_is_error() {
assert!(Cli::try_parse_from(["autumn", "new"]).is_err());
}
#[test]
fn parse_build_subcommand() {
let cli = Cli::try_parse_from(["autumn", "build"]).unwrap();
assert!(matches!(
cli.command,
Commands::Build {
debug: false,
package: None
}
));
}
#[test]
fn parse_build_debug() {
let cli = Cli::try_parse_from(["autumn", "build", "--debug"]).unwrap();
assert!(matches!(
cli.command,
Commands::Build {
debug: true,
package: None
}
));
}
#[test]
fn parse_build_with_package() {
let cli = Cli::try_parse_from(["autumn", "build", "-p", "blog"]).unwrap();
match cli.command {
Commands::Build { debug, package } => {
assert!(!debug);
assert_eq!(package.as_deref(), Some("blog"));
}
_ => panic!("expected Build command"),
}
}
#[test]
fn parse_build_with_long_package() {
let cli = Cli::try_parse_from(["autumn", "build", "--package", "blog", "--debug"]).unwrap();
match cli.command {
Commands::Build { debug, package } => {
assert!(debug);
assert_eq!(package.as_deref(), Some("blog"));
}
_ => panic!("expected Build command"),
}
}
#[test]
fn parse_dev_subcommand() {
let cli = Cli::try_parse_from(["autumn", "dev"]).unwrap();
assert!(matches!(
cli.command,
Commands::Dev {
package: None,
show_config: false
}
));
}
#[test]
fn parse_dev_with_package() {
let cli = Cli::try_parse_from(["autumn", "dev", "-p", "hello"]).unwrap();
match cli.command {
Commands::Dev {
package,
show_config,
} => {
assert_eq!(package.as_deref(), Some("hello"));
assert!(!show_config);
}
_ => panic!("expected Dev command"),
}
}
#[test]
fn parse_dev_with_show_config() {
let cli = Cli::try_parse_from(["autumn", "dev", "--show-config"]).unwrap();
assert!(matches!(
cli.command,
Commands::Dev {
package: None,
show_config: true
}
));
}
#[test]
fn parse_migrate_subcommand() {
let cli = Cli::try_parse_from(["autumn", "migrate"]).unwrap();
assert!(matches!(cli.command, Commands::Migrate { action: None }));
}
#[test]
fn parse_migrate_status() {
let cli = Cli::try_parse_from(["autumn", "migrate", "status"]).unwrap();
assert!(matches!(
cli.command,
Commands::Migrate {
action: Some(MigrateCommands::Status)
}
));
}
#[test]
fn parse_monitor_defaults() {
let cli = Cli::try_parse_from(["autumn", "monitor"]).unwrap();
match cli.command {
Commands::Monitor { url, interval } => {
assert_eq!(url, "http://localhost:3000");
assert_eq!(interval, 1);
}
_ => panic!("expected Monitor command"),
}
}
#[test]
fn parse_monitor_custom_url() {
let cli = Cli::try_parse_from(["autumn", "monitor", "-u", "http://prod:8080", "-i", "5"])
.unwrap();
match cli.command {
Commands::Monitor { url, interval } => {
assert_eq!(url, "http://prod:8080");
assert_eq!(interval, 5);
}
_ => panic!("expected Monitor command"),
}
}
#[test]
fn parse_export_defaults() {
let cli = Cli::try_parse_from(["autumn", "export"]).unwrap();
match cli.command {
Commands::Export { url, output } => {
assert_eq!(url, "http://localhost:3000");
assert_eq!(output, "autumn-diag.json");
}
_ => panic!("expected Export command"),
}
}
#[test]
fn parse_export_custom() {
let cli = Cli::try_parse_from([
"autumn",
"export",
"-u",
"http://prod:8080",
"-o",
"snapshot.json",
])
.unwrap();
match cli.command {
Commands::Export { url, output } => {
assert_eq!(url, "http://prod:8080");
assert_eq!(output, "snapshot.json");
}
_ => panic!("expected Export command"),
}
}
#[test]
fn unknown_subcommand_is_error() {
assert!(Cli::try_parse_from(["autumn", "bogus"]).is_err());
}
}