Skip to content

[FEATURE] Introduce declarative CLI argument definitions using clap de... #200

@devwif

Description

@devwif
# [FEATURE] Fully Adopt Declarative CLI Argument Definitions Using `clap` Derive Macros

---

## 🚀 Problem Statement

Our current CLI argument parsing in `osvm-cli` is largely manual and boilerplate-heavy, leading to verbose, error-prone code that’s hard to maintain and extend. This technical debt slows down feature development and onboarding of new contributors. We want to **introduce a fully declarative approach to CLI argument definitions by leveraging `clap`’s derive macros** (`#[derive(Parser)]`, `#[clap(...)]`), which dramatically reduce boilerplate, improve readability, and enforce argument validation at compile time.

This effort will modernize our CLI codebase, improve developer experience, and set a solid foundation for future extensibility and robust error handling.

---

## 🧠 Technical Context & Background

- **Current State:**  
  - `main.rs` and command modules use manual `clap` builder patterns or even custom parsing logic.
  - Argument validation and help text are scattered and inconsistent.
  - The codebase suffers from unsafe argument extraction patterns leading to potential panics.

- **Why `clap` Derive Macros?**  
  - The [`clap` crate](https://docs.rs/clap/latest/clap/) offers a powerful derive macro API that lets you define CLI arguments as Rust structs with attributes.
  - Benefits include:
    - Compile-time validation of argument types and structures.
    - Automatic generation of help and usage messages.
    - Cleaner, more maintainable code with less boilerplate.
    - Seamless support for subcommands, default values, argument groups, and custom validators.

- **Related Work:**  
  - Current roadmap includes refactoring `main.rs` for modular subcommand handling and safe argument extraction.
  - Centralized error handling strategies will synergize with this refactor.
  - Testing coverage will be expanded alongside this implementation.

---

## 🛠️ Detailed Implementation Steps

1. **Research & Design**  
   - Review `clap` derive macros documentation and examples: https://docs.rs/clap/latest/clap/derive/index.html  
   - Analyze current CLI argument definitions across the repo, especially `main.rs` and subcommand modules.  
   - Draft a technical design doc outlining:
     - Struct layout for top-level CLI args and subcommands.
     - Attribute usage for argument options (e.g., `long`, `short`, `default_value`, `value_parser`).
     - Error handling integration with our centralized error types.
     - Backwards compatibility plan or migration strategy if needed.

2. **Prototype MVP**  
   - Create a minimal working example converting 1-2 simple commands to `clap` derive macros.  
   - Validate that all existing argument features work (flags, positional args, multiple values).  
   - Ensure help/usage output looks correct and consistent.

3. **Full Implementation**  
   - Refactor `main.rs` to use a single top-level `Cli` struct with `#[derive(Parser)]` and nested subcommand enums/structs.  
   - Replace all manual argument parsing and builder usage with declarative struct definitions.  
   - Add comprehensive `#[clap(...)]` attributes to cover:
     - Aliases and short/long flags
     - Required and optional arguments
     - Default values and environment variable fallbacks
     - Custom validators where applicable  
   - Leverage `clap` features such as `flatten` for reusable argument groups if needed.

4. **Error Handling & Validation**  
   - Integrate parse errors with our centralized error handling system.  
   - Add custom validation logic via `value_parser` or `validator` functions for domain-specific checks.

5. **Testing**  
   - Expand unit tests to cover all CLI argument parsing scenarios.  
   - Add integration tests that invoke CLI commands with various argument combinations and verify expected behavior and errors.  
   - Ensure test coverage improves or at least doesn't regress.

6. **Documentation**  
   - Update CLI usage docs in the repository (README, docs folder) to reflect new argument syntax and features.  
   - Document the new CLI argument struct layout and guidance for contributors.  
   - Add comments in codebase explaining the `clap` derive usage patterns.

7. **Feedback & Iteration**  
   - Release the refactor in an MVP form to internal users or early adopters.  
   - Collect feedback on usability, missing features, or bugs.  
   - Iterate to polish ergonomics, error messages, and edge cases.

---

## ⚙️ Technical Specifications

- Use [`clap` crate v4+](https://crates.io/crates/clap) with derive feature enabled in `Cargo.toml`:
  ```toml
  [dependencies]
  clap = { version = "4", features = ["derive"] }
  • Define a top-level CLI struct using:
    use clap::{Parser, Subcommand};
    
    #[derive(Parser)]
    #[command(name = "osvm-cli", about = "Manage your Solana Virtual Machines")]
    struct Cli {
        #[command(subcommand)]
        command: Commands,
    }
    
    #[derive(Subcommand)]
    enum Commands {
        Deploy(DeployArgs),
        Monitor(MonitorArgs),
        // ... other subcommands
    }
    
    #[derive(Parser)]
    struct DeployArgs {
        #[arg(short, long, help = "Path to deployment config file")]
        config: PathBuf,
        #[arg(long, default_value = "mainnet")]
        network: String,
        // ...
    }
  • Replace all builder-style argument definitions in main.rs and related modules.
  • Use clap error types but wrap or convert to internal error enums for consistency.
  • Maintain backward-compatible CLI interface or communicate breaking changes clearly.

✅ Acceptance Criteria

  • Technical design document approved by core maintainers
  • MVP prototype converting at least 2 commands using clap derive macros
  • Full migration of main.rs and all CLI commands to declarative clap derive style
  • All previous CLI functionality preserved or enhanced (flags, subcommands, help messages)
  • Centralized error handling integrated with clap parse errors
  • Unit and integration tests cover all CLI parsing scenarios with 90%+ coverage
  • CLI usage documentation updated to reflect new argument definitions
  • User feedback collected and at least one iteration completed post-MVP release

🔍 Testing Requirements

  • Unit Tests: Validate argument parsing logic for each subcommand struct with various argument combinations.
  • Integration Tests: Run osvm-cli binary with CLI args in CI workflows, assert correct output, error messages, and exit codes.
  • Edge Cases: Test missing required args, invalid values, conflicting flags.
  • Regression: Ensure existing commands behave identically or better after refactor.
  • Help Output: Verify --help and --version output correctness and completeness.

📚 Documentation Updates

  • Update the main README.md CLI usage section with new argument syntax and examples.
  • Add a new CONTRIBUTING.md section explaining how to add or modify CLI commands using clap derive macros.
  • Inline code comments in main.rs and command modules describing the new declarative approach.
  • Update changelog to reflect CLI refactor and new feature introduction.

⚠️ Potential Challenges & Risks

  • Breaking Changes: Subtle changes in CLI argument parsing behavior might break existing user workflows. Mitigate by careful migration and communication.
  • Learning Curve: Contributors unfamiliar with clap derive macros may need ramp-up time.
  • Complex Commands: Some commands with intricate parsing logic might require custom validators or manual overrides, complicating pure derive macro usage.
  • Error Handling Integration: Wrapping clap errors into our centralized error types must be seamless to avoid confusing error messages.

📖 Resources & References


Let's crush this technical debt monster and make osvm-cli a shining beacon of Rust CLI elegance!
If you have questions or want to pair on design, ping me anytime. Happy hacking! ⚡️🦀

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions