Initial commit
This commit is contained in:
139
skills/clap-patterns/templates/subcommands.rs
Normal file
139
skills/clap-patterns/templates/subcommands.rs
Normal file
@@ -0,0 +1,139 @@
|
||||
/// Subcommand Template with Clap
|
||||
///
|
||||
/// This template demonstrates:
|
||||
/// - Subcommand derive macro
|
||||
/// - Nested command structure
|
||||
/// - Per-subcommand arguments
|
||||
/// - Enum-based command routing
|
||||
|
||||
use clap::{Parser, Subcommand};
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(name = "git-like")]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
#[command(propagate_version = true)]
|
||||
struct Cli {
|
||||
/// Enable verbose output
|
||||
#[arg(global = true, short, long)]
|
||||
verbose: bool,
|
||||
|
||||
#[command(subcommand)]
|
||||
command: Commands,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
enum Commands {
|
||||
/// Initialize a new repository
|
||||
Init {
|
||||
/// Directory to initialize
|
||||
#[arg(value_name = "DIR", default_value = ".")]
|
||||
path: PathBuf,
|
||||
|
||||
/// Create a bare repository
|
||||
#[arg(long)]
|
||||
bare: bool,
|
||||
},
|
||||
|
||||
/// Add files to staging area
|
||||
Add {
|
||||
/// Files to add
|
||||
#[arg(value_name = "FILE", required = true)]
|
||||
files: Vec<PathBuf>,
|
||||
|
||||
/// Add all files
|
||||
#[arg(short = 'A', long)]
|
||||
all: bool,
|
||||
},
|
||||
|
||||
/// Commit staged changes
|
||||
Commit {
|
||||
/// Commit message
|
||||
#[arg(short, long)]
|
||||
message: String,
|
||||
|
||||
/// Amend previous commit
|
||||
#[arg(long)]
|
||||
amend: bool,
|
||||
},
|
||||
|
||||
/// Remote repository operations
|
||||
Remote {
|
||||
#[command(subcommand)]
|
||||
command: RemoteCommands,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
enum RemoteCommands {
|
||||
/// Add a new remote
|
||||
Add {
|
||||
/// Remote name
|
||||
name: String,
|
||||
|
||||
/// Remote URL
|
||||
url: String,
|
||||
},
|
||||
|
||||
/// Remove a remote
|
||||
Remove {
|
||||
/// Remote name
|
||||
name: String,
|
||||
},
|
||||
|
||||
/// List all remotes
|
||||
List {
|
||||
/// Show URLs
|
||||
#[arg(short, long)]
|
||||
verbose: bool,
|
||||
},
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let cli = Cli::parse();
|
||||
|
||||
match &cli.command {
|
||||
Commands::Init { path, bare } => {
|
||||
if cli.verbose {
|
||||
println!("Initializing repository at {:?}", path);
|
||||
}
|
||||
println!(
|
||||
"Initialized {} repository in {}",
|
||||
if *bare { "bare" } else { "normal" },
|
||||
path.display()
|
||||
);
|
||||
}
|
||||
|
||||
Commands::Add { files, all } => {
|
||||
if *all {
|
||||
println!("Adding all files");
|
||||
} else {
|
||||
println!("Adding {} file(s)", files.len());
|
||||
if cli.verbose {
|
||||
for file in files {
|
||||
println!(" - {}", file.display());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Commands::Commit { message, amend } => {
|
||||
if *amend {
|
||||
println!("Amending previous commit");
|
||||
}
|
||||
println!("Committing with message: {}", message);
|
||||
}
|
||||
|
||||
Commands::Remote { command } => match command {
|
||||
RemoteCommands::Add { name, url } => {
|
||||
println!("Adding remote '{}' -> {}", name, url);
|
||||
}
|
||||
RemoteCommands::Remove { name } => {
|
||||
println!("Removing remote '{}'", name);
|
||||
}
|
||||
RemoteCommands::List { verbose } => {
|
||||
println!("Listing remotes{}", if *verbose { " (verbose)" } else { "" });
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user