Skip to content
/ dcli Public

Dynamic CLI is an experimental tool in Rust for dynamic management of command line interfaces.

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT
Notifications You must be signed in to change notification settings

biface/dcli

dynamic-cli

Crates.io Documentation License

A powerful Rust framework for creating configurable CLI and REPL applications via YAML/JSON files.

Define your command-line interface in a configuration file, not in code. ✨


English | FranΓ§ais


🎯 Features

  • πŸ“ Configuration-Driven : Define commands, arguments and options in YAML/JSON
  • πŸ”„ CLI & REPL Modes : Support for both command-line and interactive modes
  • βœ… Automatic Validation : Built-in type checking and constraint validation
  • 🎨 Rich Error Messages : Colorful and informative messages with suggestions
  • πŸ”Œ Extensible : Easy addition of custom command handlers
  • πŸ“š Well Documented : Complete API documentation and examples
  • πŸ§ͺ Thoroughly Tested : >80% test coverage with 345+ tests
  • ⚑ Performance : Zero-cost abstractions with efficient parsing

πŸš€ Quick Start

Installation

Add to your Cargo.toml:

[dependencies]
dynamic-cli = "0.1.1"

Basic Example

1. Create a configuration file (commands.yaml):

metadata:
  version: "1.0.0"
  prompt: "myapp"
  prompt_suffix: " > "

commands:
  - name: greet
    aliases: [hello, hi]
    description: "Greet someone"
    required: false
    arguments:
      - name: name
        arg_type: string
        required: true
        description: "Name to greet"
        validation: []
    options:
      - name: loud
        short: l
        long: loud
        option_type: bool
        required: false
        description: "Use uppercase"
        choices: []
    implementation: "greet_handler"

global_options: []

Note :

The proper syntax for the configuration file is available in the project repository.

2. Implement your command handlers:

use dynamic_cli::prelude::*;
use std::collections::HashMap;

// Define your application context
#[derive(Default)]
struct MyContext {
    // Your application state
}

impl ExecutionContext for MyContext {
    fn as_any(&self) -> &dyn std::any::Any { self }
    fn as_any_mut(&mut self) -> &mut dyn std::any::Any { self }
}

// Implement the command handler
struct GreetCommand;

impl CommandHandler for GreetCommand {
    fn execute(
        &self,
        _context: &mut dyn ExecutionContext,
        args: &HashMap<String, String>,
    ) -> dynamic_cli::Result<()> {
        let name = args.get("name").unwrap();
        let loud = args.get("loud").map(|v| v == "true").unwrap_or(false);
        
        let greeting = format!("Hello, {}!", name);
        println!("{}", if loud { greeting.to_uppercase() } else { greeting });
        
        Ok(())
    }
}

fn main() -> dynamic_cli::Result<()> {
    CliBuilder::new()
        .config_file("commands.yaml")
        .context(Box::new(MyContext::default()))
        .register_handler("greet_handler", Box::new(GreetCommand))
        .build()?
        .run()
}

3. Run your application:

# CLI mode
$ myapp greet Alice
Hello, Alice!

$ myapp greet Bob --loud
HELLO, BOB!

# REPL mode
$ myapp
myapp > greet Alice
Hello, Alice!
myapp > help
Available commands:
  greet [name] - Greet someone
myapp > exit

πŸ“– Documentation


πŸŽ“ Examples

The examples directory contains complete examples:

Run any example:

cargo run --example simple_calculator

πŸ— Architecture

dynamic-cli is organized into focused modules:

  • config - Configuration loading and validation
  • context - Execution context trait
  • executor - Command execution engine
  • registry - Command and handler registry
  • parser - CLI and REPL argument parsing
  • validator - Argument validation
  • interface - CLI and REPL interfaces
  • error - Error types and display
  • builder - Fluent API for building applications

πŸ§ͺ Tests

# Run all tests
cargo test --all-features

# Run with coverage
cargo tarpaulin --out Html

# Check code quality
cargo clippy --all-features -- -D warnings

Current test statistics:

  • 345+ unit tests βœ…
  • 126+ documentation tests
  • 80-90% code coverage
  • Zero clippy warnings

🀝 Contributing

We welcome contributions from everyone! Here's how you can help:

Ways to Contribute

  • πŸ› Report bugs - Found a bug? Open an issue
  • πŸ’‘ Suggest features - Have an idea? Start a discussion
  • πŸ“ Improve documentation - Fix typos, clarify, add examples
  • πŸ”§ Submit code - Fix bugs, implement features, improve performance
  • πŸ§ͺ Add tests - Increase coverage, add edge cases

Getting Started

# Fork and clone
git clone https://github.com/biface/dcli.git
cd dynamic-cli

# Create a branch
git checkout -b feature/my-feature

# Make your changes and test
cargo test --all-features
cargo clippy --all-features

# Commit and push
git commit -am "Add awesome feature"
git push origin feature/my-feature

Development Guidelines

Before submitting a pull request:

  • Code follows Rust style guidelines (cargo fmt)
  • All tests pass (cargo test --all-features)
  • No clippy warnings (cargo clippy --all-features -- -D warnings)
  • Documentation is updated
  • New tests added for new features
  • Commit messages are clear and descriptive

Code of Conduct

This project follows a Code of Conduct to ensure a welcoming environment:

  • βœ… Be respectful to others
  • βœ… Welcome newcomers and help them learn
  • βœ… Constructive criticism helps us move forward and improveβ€”let's embrace it
  • βœ… Focus on what's best for the community
  • ❌ No harassment, trolling or personal attacks

Read the complete contributing guide β†’


πŸ“œ License

Licensed under your choice of:

Contribution Licensing

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.


πŸ™ Acknowledgments

  • Rust Community - For the amazing tools and libraries developed
  • Contributors - Everyone who has contributed to this project
  • clap - Inspiration for CLI design
  • rustyline - REPL functionality
  • serde - Serialization support

πŸ“ž Support

Need help?

Found a security vulnerability?
Please report it privately to the maintainers.


🌟 Show Your Support

If you find dynamic-cli useful, please:

  • ⭐ Star the repository on GitHub
  • πŸ“’ Share it with others who might find it useful
  • πŸ“ Write a blog post or tutorial!

Last updated: 2026-01-12

About

Dynamic CLI is an experimental tool in Rust for dynamic management of command line interfaces.

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages