use clap::{Parser, Subcommand};
#[derive(Subcommand, PartialEq)]
pub(crate) enum Command {
#[command(about = "Compare installed hooks with configuration file")]
Compare,
#[command(
about = "Initialize hooksmith configuration interactively",
alias = "i"
)]
Init,
#[command(about = "Install all hooks listed in the config file")]
Install,
#[command(about = "Run a specific hook")]
Run {
#[arg(default_value = None)]
hook_names: Option<Vec<String>>,
#[arg(short, long, default_value_t = false)]
interactive: bool,
#[arg(short, long, default_value_t = false)]
profile: bool,
},
#[command(about = "Uninstall hooks")]
Uninstall {
#[arg(default_value = None)]
hook_name: Option<String>,
},
#[command(about = "Validate hooks in configuration file against standard Git hooks")]
Validate,
}
#[derive(Parser)]
#[command(about = "A trivial Git hooks utility.")]
#[command(author = "Tom Planche <tomplanche@proton.me>")]
#[command(name = "hooksmith")]
#[command(version)]
pub(crate) struct Cli {
#[command(subcommand)]
pub(crate) command: Command,
#[arg(short, long, default_value_t = String::from("hooksmith.yaml"))]
pub(crate) config_path: String,
#[arg(short, long, default_value_t = false)]
pub(crate) verbose: bool,
#[arg(long, default_value_t = false)]
pub(crate) dry_run: bool,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_cli_parsing() {
let args = vec!["hooksmith", "install"];
let cli = Cli::parse_from(args);
match cli.command {
Command::Install => {}
_ => panic!("Expected Install command"),
}
let args = vec!["hooksmith", "run", "pre-commit", "pre-push"];
let cli = Cli::parse_from(args);
match cli.command {
Command::Run {
hook_names,
interactive,
profile,
} => {
assert_eq!(
hook_names,
Some(vec!["pre-commit".to_string(), "pre-push".to_string()])
);
assert!(!interactive);
assert!(!profile);
}
_ => panic!("Expected Run command with hook_names=[pre-commit, pre-push]"),
}
}
}