7 个稳定版本

1.2.1 2019 年 5 月 2 日
1.2.0 2019 年 4 月 30 日

#592 in 命令行界面

每月 24 次下载

MIT 许可协议

1MB
1K SLoC

Rust 899 SLoC // 0.0% comments JavaScript 296 SLoC // 0.1% comments


代码片段

其他语言

中文文档

为什么是这个?

长期以来,在 Rust 中开发 CLI 很困难。社区提供了一系列解决方案。是的,它们很优秀,但并不简单。

commander.jsrocket.rs 的启发,这个 crate 诞生了。

特性

  • API 友好
  • 易于使用
  • 支持近似动态语言
  • 低性能损失
  • 自动支持 --version--help
  • 自动运行相应命令

限制

如果您想使用这个 crate,请确保您遵守以下规则:

  • 使用 Rust 2018(需要完整的 proc macro 支持,包括 [proc_macro] 和 [proc_macro_attribute])
  • 使用 cargocargo 会根据 Cargo.toml 生成一些环境变量,我们需要这些)
  • 熟悉 Rust(因为它是为 Rust 开发的)

以下是我的版本作为参考:

  • cargo: cargo 1.35.0-nightly (95b45eca1 2019-03-06)
  • rustc: rustc 1.35.0-nightly (e68bf8ae1 2019-03-11)
  • Linux 内核: 4.15.0-47-generic
  • Ubuntu: 16.04

使用方法

安装 commander-rust

支持两种安装方式:从 Githubcrates.io。它们的区别在于 Github 提供的是最新版本但不稳定,而 crates.io 提供的是稳定版本但可能不是最新版本。

Github 安装
[dependencies.commander_rust]
git = "https://github.com/MSDimos/commander_rust"
branch = "master"

crates.io 安装

[dependencies]
commander_rust = "1.1.3" # or other version you want to install

使用它

我们提供了一个简单但完整的示例,您可以通过它学习所有内容。是的,就是这样。非常简单!


// this is required! Beacuse we used `run!()`, it's a proc_macro
#![feature(proc_macro_hygiene)]

// Only five items you will use
use commander_rust::{ Cli, command, option, entry, run };


// what's option? what's command? 
// See `commander.js` and document of `commander-rust` for more!
// Note, types of parameters are not fixed, any type implemented `From<Raw>` is valid!
// So you can even use `rmdir(dir: i32, other_dirs: Vec<i32>, cli: Cli)` here.
// And `Cli` is not required! So you can miss it.
// See document of `commander-rust` for more details.
#[option(-s, --format <format>, "format output")]
#[option(-r, --recursive, "recursively")]
#[command(rmdir <dir> [otherDirs...], "remove files and directories")]
fn rmdir(dir: String, other_dirs: Option<Vec<String>>, cli: Cli) {

    // get value of no-parameter options, using `has`
    // get value if normal options, using `get`, `get_or`, `get_or_else`
    // `get_or` and `get_or_else` can be using for specifying default value 
    // for the most time, I suggest you using `get_or` and `has`.
    let format = cli.get_or("format", String::new("%s"));
    
    if !cli.has("recursive") {
        let silently = cli.get_or("silently", false);
        
        if silently {
            // delete all files silently
            // just like `rm -rf /`
        } else {
            // tell the world I'm going to delete the files
        }
    } else {
        // delete files recursively is slowly
        // so drink a cup of coffee, relax.
    }
}

// options here are public, options above `#[command]` are private
#[option(-s, --silently <silently>, "don't display anything")]
#[entry]
fn main() {
     // Run it now!!!!!
     let app = run!();
     // printing app is same as you inputting `--help`.
     println!("app is {:#?}", app);
}

试试吧

尝试输入 [pkg-name] --help

版本、描述和 CLI 名称是什么?

versiondescriptioncli-name 的应用程序来自 Cargo.toml

例如

# part of Cargo.toml
[package]
name = "example-test"
version = "0.1.0"
description = "Using for test"

直接

如果您不想定义子命令,可以使用 #[direct]。什么是 direct?在某些情况下,例如,如果您想开发一个像 rm ./* -rf 这样可以调用的 CLI。如果没有 direct,您只能使用子命令,看起来像 rm delete ./* -rf。来吧!delete 是多余的,我们不希望这样!它应该是 rm -rf ./* 而不是 rm delete ./* -rf。所以,现在是时候使用 #[direct]

/* 
    You can still define sub-command here
    suc-command can work together with direct-func well
 */

// function name is whatever you like
// last parameter can be `CLI`, it's not necessary like `command`.
// `cli` can only get public options here.
#[direct(<a> <b> [c] [d])]
fn whatever_you_like(a: String, b: String, cli: Cli) {
    println!("hello! {} {}", a, b);
}

现在,如果您输入 [pkg-name] 1 2 3,CLI 将打印 hello! 1 2。所以它允许您在某些简单情况下不再需要定义子命令。仅支持 1.2.x 或更高版本的 direct。可以很好地与子命令一起工作,您可以使用它们两个一起。

错误

我无法保证它将在所有情况下都能完美工作。我的能力非常有限,测试不是我的专长,对此表示歉意。我在学习。所以如果您发现任何 BUG,请告诉我。谢谢。

示例

这里有两个完整的示例。一个是 cargo-bp,另一个是 hash。还有一个简单示例展示了 commander-rust 的所有用法,更多信息请参阅 ./examples

主页

正在开发中。请参阅 ./homepage

规则

您应该遵循几个规则。

  1. 所有 #[options] 应定义在 #[command]#[entry] 之上。
  2. 不要定义重复选项!!!作为让步,您可以在不同的命令和入口处定义相同的选项。
  3. 私有选项对特定子命令可见。公共选项对所有子命令可见。

警告

此软件包是在使用 Ubuntu 16.04 开发的,我们无法假设所有平台都能很好地工作。如果您发现它在其他平台上无法很好地工作,请告诉我。

贡献

欢迎任何有用的贡献。您可以向我发送 pull 请求。

许可

GPL-3.0。因为开源是未来。

依赖项