Search code examples
rustclap

How to print version and custom command line argument value using clap crate


I'm using clap crate to handle command line arguments. How do I print the the version number and a custom command line argument together? The below code when run with cargo run -- --name Harry --version only prints version number.

use clap::Parser;

/// Simple program to greet a person
#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
struct Args {
    /// Name of the person to greet
    #[arg(short, long)]
    name: String,

    /// Number of times to greet
    #[arg(short, long, default_value_t = 1)]
    count: u8,
}

fn main() {
    let args = Args::parse();

    for _ in 0..args.count {
        println!("Hello {}!", args.name);
    }
}

Current Output

clap_demo 0.1.0

Expected Output

Hello Harry!
clap_demo 0.1.0

Cargo.toml

[package]
name = "clap_demo"
version = "0.1.0"
edition = "2021"

[dependencies]
clap = { version = "4.5.26", features = ["derive", "env"] }

Solution

  • The auto-generated version has the action ArgAction::Version, which only shows the name and version.

    If you want to customize the behavior, you need to disable the auto-generated one and add a new one like this:

    use clap::{crate_name, crate_version, Parser};
    
    #[derive(Debug, Parser)]
    #[command(disable_version_flag = true)]
    struct Args {
        #[arg(short, long)]
        name: String,
    
        #[arg(short, long, default_value_t = 1)]
        count: u8,
    
        #[arg(short = 'V', long, help = "Print version")]
        version: bool,
    }
    
    fn main() {
        let args = Args::parse();
    
        if args.version {
            for _ in 0..args.count {
                println!("Hello, {}!", args.name);
            }
    
            println!("{} {}", crate_name!(), crate_version!());
        }
    }
    

    Notice: crate_name! and crate_version! needs clap's cargo feature.