generated from hashblock/solana-cli-program-template
-
Notifications
You must be signed in to change notification settings - Fork 3
Open
Labels
Description
# [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.rsand related modules. - Use
claperror 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
clapderive macros - Full migration of
main.rsand all CLI commands to declarativeclapderive style - All previous CLI functionality preserved or enhanced (flags, subcommands, help messages)
- Centralized error handling integrated with
clapparse 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-clibinary 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
--helpand--versionoutput correctness and completeness.
📚 Documentation Updates
- Update the main
README.mdCLI usage section with new argument syntax and examples. - Add a new CONTRIBUTING.md section explaining how to add or modify CLI commands using
clapderive macros. - Inline code comments in
main.rsand 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
clapderive 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
claperrors into our centralized error types must be seamless to avoid confusing error messages.
📖 Resources & References
clapcrate docs & derive macrosclapGitHub repo- Example projects using
clapderive macros: - Rust CLI best practices:
- Related open issues or PRs:
- Add markdown rendering for AI responses in CLI #109 - markdown rendering & CLI improvements
- AI Development Plan Milestone fix installation 1 liner in readme #5
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! ⚡️🦀