clap-version-flag

Crates.ioclap-version-flag
lib.rsclap-version-flag
version1.0.7
created_at2025-12-11 18:04:25.338469+00
updated_at2025-12-12 02:12:53.910834+00
descriptioncolorful version handler for clap
homepagehttps://github.com/cumulus13/clap-version-flag
repositoryhttps://github.com/cumulus13/clap-version-flag
max_upload_size
id1980225
size162,904
cumulus13 (cumulus13)

documentation

README

clap-version-flag

Crates.io Documentation License

Adding colorful version output to clap applications.

Features

  • 🎨 Hex Color Support: Use hex color codes (#RRGGBB or #RGB) for all text elements
  • 🔧 clap Integration: Seamlessly works with clap's derive and builder APIs
  • 📦 Automatic Cargo.toml Detection: Reads package info from environment variables
  • 🚀 Production Ready: Comprehensive error handling, testing, and documentation
  • 🌈 Graceful Fallback: Works in terminals with and without color support
  • ⚙️ Feature Flags: Optional no-color feature for environments without color support 🔧 Flexible integration - Works with clap derive and builder patterns 🚀 Zero-config defaults - Beautiful colors out of the box

Installation

Add this to your Cargo.toml:

[dependencies]
clap = { version = "4.5", features = ["derive"] }
clap-version-flag = "1.0.5"

Quick Start

Basic Usage

use clap::Parser;
use clap_version_flag::colorful_version;

#[derive(Parser)]
#[command(name = "myapp")]
struct Cli {
    #[arg(short, long)]
    input: String,
}

fn main() {
    // Create version info from your Cargo.toml
    let version = colorful_version!();
    
    // Parse arguments
    let cli = Cli::parse();
    
    // Your app logic here
    println!("Input: {}", cli.input);
}

When a user runs myapp --version, they'll see:

myapp v1.0.0 by Your Name

With colors (when terminal supports it):

  • myapp: White text (#FFFFFF) on purple background (#AA00FF)
  • v1.0.0: Yellow text (#FFFF00)
  • by Author Name: Cyan text (#00FFFF)

Custom Colors

use clap_version_flag::colorful_version;

fn main() {
    // Custom hex colors: name_fg, name_bg, version, author
    let version = colorful_version!(
        "#FF0000",  // Red foreground for name
        "#0000FF",  // Blue background for name
        "#00FF00",  // Green for version
        "#FFFF00"   // Yellow for author
    );
    
    version.print();
}

Manual Version Creation

use clap_version_flag::ColorfulVersion;

fn main() {
    let version = ColorfulVersion::new("myapp", "1.0.0", "John Doe")
        .with_hex_colors("#FFFFFF", "#AA00FF", "#FFFF00", "#00FFFF")
        .expect("Invalid hex colors");
    
    version.print();
}

Using RGB Colors

use clap_version_flag::ColorfulVersion;

fn main() {
    let version = ColorfulVersion::new("myapp", "1.0.0", "John Doe")
        .with_rgb_colors(
            (255, 255, 255),  // White foreground
            (170, 0, 255),    // Purple background
            (255, 255, 0),    // Yellow version
            (0, 255, 255)     // Cyan author
        );
    
    version.print();
}

Integration with Clap

Method 1: Using parse_with_version (Recommended)

This automatically handles the --version flag:

use clap::{Parser, CommandFactory};
use clap_version_flag::{colorful_version, parse_with_version};

#[derive(Parser)]
struct Cli {
    #[arg(short, long)]
    name: String,
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let version = colorful_version!();
    let cli: Cli = parse_with_version(Cli::command(), &version)?;
    
    println!("Hello, {}!", cli.name);
    Ok(())
}

Method 2: Manual Flag Checking

use clap::{Parser, CommandFactory};
use clap_version_flag::{colorful_version, ColorfulVersionExt};

#[derive(Parser)]
struct Cli {
    #[arg(short, long)]
    name: String,
}

fn main() {
    let version = colorful_version!();
    
    let matches = Cli::command()
        .with_colorful_version(&version)
        .get_matches();
    
    // Check if version flag was used
    version.check_and_exit(&matches);
    
    // Continue with normal parsing
    let cli = Cli::from_arg_matches(&matches).unwrap();
    println!("Hello, {}!", cli.name);
}

Method 3: Builder Pattern

use clap::Command;
use clap_version_flag::{colorful_version, ColorfulVersionExt};

fn main() {
    let version = colorful_version!();
    
    let matches = Command::new("myapp")
        .with_colorful_version(&version)
        .arg(clap::arg!(-n --name <NAME> "Your name"))
        .get_matches();
    
    version.check_and_exit(&matches);
    
    if let Some(name) = matches.get_one::<String>("name") {
        println!("Hello, {}!", name);
    }
}

Default Colors

The default color scheme is designed for maximum readability:

  • Package Name: White text (#FFFFFF) on purple background (#AA00FF)
  • Version: Yellow text (#FFFF00)
  • Author: Cyan text (#00FFFF)

API Reference

colorful_version!()

Macro to create a ColorfulVersion using information from your Cargo.toml.

Important: This macro uses env!() which expands at the caller's location, so it correctly picks up your package information, not this library's.

// With default colors
let version = colorful_version!();

// With custom colors
let version = colorful_version!("#FFFFFF", "#AA00FF", "#FFFF00", "#00FFFF");

ColorfulVersion

Main struct for version configuration.

Methods

  • new(name, version, author) - Create with custom values
  • with_hex_colors(name_fg, name_bg, version, author) - Set colors using hex codes
  • with_rgb_colors(name_fg, name_bg, version, author) - Set colors using RGB tuples
  • print() - Print colored version to stdout
  • print_and_exit() - Print and exit with code 0
  • as_plain_string() - Get plain text version
  • to_colored_string() - Get colored version with ANSI codes
  • package_name(), version(), author() - Getters

ColorfulVersionExt

Trait extension for clap::Command.

use clap_version_flag::ColorfulVersionExt;

let cmd = Command::new("myapp").with_colorful_version(&version);

parse_with_version()

Helper function to parse command-line arguments with automatic version handling.

use clap_version_flag::parse_with_version;

let cli: YourCli = parse_with_version(YourCli::command(), &version)?;

Color Format Support

Hex Colors

  • 6-digit: #RRGGBB (e.g., #FF0000 for red)
  • 3-digit: #RGB (e.g., #F00 for red, expands to #FF0000)
  • Without #: RRGGBB (automatically prepended)

RGB Tuples

(255, 0, 0)  // Red
(0, 255, 0)  // Green
(0, 0, 255)  // Blue

Testing

Run tests:

cargo test

Run tests with output:

cargo test -- --nocapture

Examples

Check the examples/ directory for complete working examples:

cargo run --example basic
cargo run --example custom_colors
cargo run --example derive_helper
cargo run --example full_integration

Why This Crate?

Clap's built-in --version flag outputs plain text. This crate enhances the user experience with:

  1. Professional appearance - Colored output makes your CLI tool stand out
  2. Consistent branding - Use your brand colors in the version output
  3. Zero boilerplate - Automatic extraction from Cargo.toml
  4. Terminal compatibility - Uses colored crate with proper terminal detection

Comparison

Without clap-version-flag:

$ myapp --version
myapp 1.0.0

With clap-version-flag:

$ myapp --version
myapp v1.0.0 by Your Name

(But with beautiful colors that respect your terminal theme!)

How It Works

The colorful_version!() macro uses Rust's env!() macro which expands at compile time at the caller's location. This means:

  1. When you use colorful_version!() in your project
  2. The macro expands to read CARGO_PKG_NAME, CARGO_PKG_VERSION, and CARGO_PKG_AUTHORS
  3. These environment variables are set by Cargo during compilation
  4. They contain your project's information, not this library's

This is why the macro correctly picks up your package information!

Common Issues

Issue: Wrong package name displayed

Cause: Using an old version that had the bug.

Solution: Update to version 1.0.4 or later:

clap-version-flag = "1.0.4"

Issue: Version flag not working

Cause: Need to disable clap's built-in version flag.

Solution: The with_colorful_version() extension trait automatically calls .disable_version_flag(true).

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

This project is dual-licensed under either:

at your option.

Acknowledgments

  • clap - Command Line Argument Parser for Rust
  • colored - Coloring terminal output

Author

Hadi Cahyadi

Buy Me a Coffee

Donate via Ko-fi

Support me on Patreon

Commit count: 0

cargo fmt