use clap::{Parser, Subcommand};
#[derive(Parser, Debug)]
#[command(
name = "git-sync",
version,
about,
long_about = None,
)]
pub struct Cli {
#[arg(short = 'y', long)]
pub yes: bool,
#[arg(short = 'n', long)]
pub dry_run: bool,
#[arg(short, long)]
pub verbose: bool,
#[arg(long)]
pub no_fetch: bool,
#[arg(long)]
pub local_only: bool,
#[arg(long)]
pub remote_only: bool,
#[arg(long)]
pub no_worktrees: bool,
#[arg(long, overrides_with = "no_worktrunk")]
pub worktrunk: bool,
#[arg(long, overrides_with = "worktrunk")]
pub no_worktrunk: bool,
#[command(subcommand)]
pub command: Option<Command>,
}
#[derive(Subcommand, Debug)]
pub enum Command {
Config {
#[command(subcommand)]
action: ConfigAction,
},
}
#[derive(Subcommand, Debug)]
pub enum ConfigAction {
List,
Set {
key: String,
value: String,
},
AddProtected {
pattern: String,
},
RemoveProtected {
pattern: String,
},
AddRemote {
name: String,
},
RemoveRemote {
name: String,
},
Protect {
branch: String,
},
Unprotect {
branch: String,
},
Setup,
}
#[cfg(test)]
mod tests {
use super::*;
use clap::Parser;
#[test]
fn test_cli_default_flags() {
let cli = Cli::parse_from(["git-sync"]);
assert!(!cli.yes);
assert!(!cli.dry_run);
assert!(!cli.verbose);
assert!(!cli.no_fetch);
assert!(!cli.local_only);
assert!(!cli.remote_only);
assert!(!cli.no_worktrees);
assert!(!cli.worktrunk);
assert!(!cli.no_worktrunk);
assert!(cli.command.is_none());
}
#[test]
fn test_cli_flag_parsing() {
let cli = Cli::parse_from(["git-sync", "-y", "-n", "-v", "--no-fetch", "--local-only"]);
assert!(cli.yes);
assert!(cli.dry_run);
assert!(cli.verbose);
assert!(cli.no_fetch);
assert!(cli.local_only);
assert!(!cli.remote_only);
}
#[test]
fn test_cli_worktrunk_flag() {
let cli = Cli::parse_from(["git-sync", "--worktrunk"]);
assert!(cli.worktrunk);
assert!(!cli.no_worktrunk);
}
#[test]
fn test_cli_no_worktrunk_flag() {
let cli = Cli::parse_from(["git-sync", "--no-worktrunk"]);
assert!(!cli.worktrunk);
assert!(cli.no_worktrunk);
}
#[test]
fn test_cli_worktrunk_overrides() {
let cli = Cli::parse_from(["git-sync", "--worktrunk", "--no-worktrunk"]);
assert!(!cli.worktrunk);
assert!(cli.no_worktrunk);
let cli = Cli::parse_from(["git-sync", "--no-worktrunk", "--worktrunk"]);
assert!(cli.worktrunk);
assert!(!cli.no_worktrunk);
}
#[test]
fn test_cli_config_subcommand() {
let cli = Cli::parse_from(["git-sync", "config", "list"]);
assert!(cli.command.is_some());
match cli.command.unwrap() {
Command::Config { action } => match action {
ConfigAction::List => {} _ => panic!("Expected ConfigAction::List"),
},
}
let cli = Cli::parse_from(["git-sync", "config", "set", "remote", "origin"]);
match cli.command.unwrap() {
Command::Config { action } => match action {
ConfigAction::Set { key, value } => {
assert_eq!(key, "remote");
assert_eq!(value, "origin");
}
_ => panic!("Expected ConfigAction::Set"),
},
}
let cli = Cli::parse_from(["git-sync", "config", "add-protected", "release/*"]);
match cli.command.unwrap() {
Command::Config { action } => match action {
ConfigAction::AddProtected { pattern } => {
assert_eq!(pattern, "release/*");
}
_ => panic!("Expected ConfigAction::AddProtected"),
},
}
}
}