clap

安装量: 70
排名: #10956

安装

npx skills add https://github.com/bobmatnyc/claude-mpm-skills --skill clap

Clap (Rust) - Production CLI Patterns Overview

Clap provides declarative command-line parsing with strong help output, validation, and subcommand support. Use it to build CLIs with predictable UX and testable execution paths.

Quick Start Minimal CLI

✅ Correct: derive Parser

use clap::Parser;

[derive(Parser, Debug)]

[command(name = "mytool", version, about = "Example CLI")]

struct Args { /// Enable verbose output #[arg(long)] verbose: bool,

/// Input file path
#[arg(value_name = "FILE")]
input: String,

}

fn main() { let args = Args::parse(); if args.verbose { eprintln!("verbose enabled"); } println!("input={}", args.input); }

❌ Wrong: parse multiple times

fn main() { let _a = Args::parse(); let _b = Args::parse(); // duplicate parsing and inconsistent behavior }

Subcommands (real tools)

Model multi-mode CLIs with subcommands and shared global flags.

✅ Correct: global flags + subcommands

use clap::{Parser, Subcommand, ValueEnum};

[derive(Parser, Debug)]

struct Args { #[arg(long, global = true)] verbose: bool,

#[arg(long, global = true, env = "MYTOOL_CONFIG")]
config: Option<String>,

#[command(subcommand)]
cmd: Command,

}

[derive(Subcommand, Debug)]

enum Command { Serve { #[arg(long, default_value_t = 3000)] port: u16 }, Migrate { #[arg(long, value_enum, default_value_t = Mode::Up)] mode: Mode }, }

[derive(Copy, Clone, Debug, ValueEnum)]

enum Mode { Up, Down }

fn main() { let args = Args::parse(); match args.cmd { Command::Serve { port } => println!("serve on {}", port), Command::Migrate { mode } => println!("migrate: {:?}", mode), } }

Config layering (CLI + env + config file)

Prefer explicit precedence:

CLI flags Environment variables Config file Defaults

✅ Correct: merge config with CLI overrides

use clap::Parser; use serde::Deserialize;

[derive(Parser, Debug)]

struct Args { #[arg(long, env = "APP_PORT")] port: Option, }

[derive(Deserialize)]

struct FileConfig { port: Option, }

fn effective_port(args: &Args, file: &FileConfig) -> u16 { args.port.or(file.port).unwrap_or(3000) }

Exit codes and error handling

Map failures to stable exit codes. Return Result from command handlers and centralize printing.

✅ Correct: command returns Result

use std::process::ExitCode;

fn main() -> ExitCode { match run() { Ok(()) => ExitCode::SUCCESS, Err(e) => { eprintln!("{e}"); ExitCode::from(1) } } }

fn run() -> Result<(), String> { Ok(()) }

Testing (assert_cmd)

Test the binary surface (arguments, output, exit codes) without coupling to internals.

✅ Correct: integration test

use assert_cmd::Command;

[test]

fn shows_help() { Command::cargo_bin("mytool") .unwrap() .arg("--help") .assert() .success(); }

Shell completions (optional)

Generate completions for Bash/Zsh/Fish.

✅ Correct: emit completions

use clap::{CommandFactory, Parser}; use clap_complete::{generate, shells::Zsh}; use std::io;

fn print_zsh_completions() { let mut cmd = super::Args::command(); generate(Zsh, &mut cmd, "mytool", &mut io::stdout()); }

Anti-Patterns Parse arguments in library code; parse once in main and pass a typed config down. Hide failures behind unwrap; return stable exit codes and structured errors. Overload one command with flags; use subcommands for distinct modes. Resources Clap: https://docs.rs/clap assert_cmd: https://docs.rs/assert_cmd clap_complete: https://docs.rs/clap_complete

返回排行榜