use clap::{Parser, Subcommand, ValueEnum};
#[derive(Clone, Debug, PartialEq, ValueEnum)]
pub enum ShellType {
Bash,
Zsh,
Fish,
Powershell,
Elvish,
Nushell,
}
#[derive(Clone, Debug, PartialEq, ValueEnum)]
pub enum FeedbackType {
Bug,
Feature,
Ux,
Performance,
Documentation,
Other,
}
#[derive(Parser, Debug)]
#[command(name = "devtool")]
#[command(
about = "A CLI tool for updating rustup toolchain, mise maintained tools and homebrew packages."
)]
#[command(
long_about = "devtool is a modern, efficient developer tool written in Rust that unifies the update process for your development environment tools and package managers with a single command."
)]
#[command(version = env!("CARGO_PKG_VERSION"))]
pub struct Args {
#[command(subcommand)]
pub command: Option<Commands>,
}
#[derive(Subcommand, Debug)]
pub enum Commands {
Update {
#[arg(short = 'n', long = "dry-run")]
dry_run: bool,
#[arg(short = 'v', long = "verbose")]
verbose: bool,
#[arg(long = "no-color")]
no_color: bool,
#[arg(long = "keep-logs")]
keep_logs: bool,
#[arg(long = "parallel", default_value_t = true)]
parallel: bool,
#[arg(long = "sequential")]
sequential: bool,
#[arg(long = "jobs", default_value_t = 3)]
jobs: usize,
#[arg(long = "no-banner")]
no_banner: bool,
#[arg(long = "compact")]
compact: bool,
},
Completion {
#[arg(value_enum)]
shell: ShellType,
},
Feedback {
#[arg(short = 't', long = "type", value_enum)]
feedback_type: Option<FeedbackType>,
#[arg(short = 'm', long = "message")]
message: Option<String>,
#[arg(short = 'v', long = "verbose")]
verbose: bool,
},
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_args_defaults() {
let args = Args::parse_from(["devtool"]);
assert!(args.command.is_none());
}
#[test]
fn test_args_update() {
let args = Args::parse_from(["devtool", "update"]);
match args.command {
Some(Commands::Update {
dry_run,
verbose,
no_color,
..
}) => {
assert!(!dry_run);
assert!(!verbose);
assert!(!no_color);
}
_ => panic!("Expected Update command"),
}
}
#[test]
fn test_args_update_dry_run() {
let args = Args::parse_from(["devtool", "update", "--dry-run"]);
match args.command {
Some(Commands::Update { dry_run, .. }) => {
assert!(dry_run);
}
_ => panic!("Expected Update command"),
}
}
#[test]
fn test_args_completion() {
let args = Args::parse_from(["devtool", "completion", "bash"]);
match args.command {
Some(Commands::Completion { shell }) => {
assert_eq!(shell, ShellType::Bash);
}
_ => panic!("Expected Completion command"),
}
}
#[test]
fn test_args_completion_nushell() {
let args = Args::parse_from(["devtool", "completion", "nushell"]);
match args.command {
Some(Commands::Completion { shell }) => {
assert_eq!(shell, ShellType::Nushell);
}
_ => panic!("Expected Completion command with nushell"),
}
}
}