4个稳定版本

2.0.15 2022年12月2日
2.0.14 2022年11月30日
2.0.12 2022年7月29日
2.0.10 2022年6月20日
0.1.14 2021年8月30日

#74Cargo插件 中排名

Download history 14/week @ 2024-03-08 13/week @ 2024-03-15 15/week @ 2024-03-22 13/week @ 2024-03-29 4/week @ 2024-04-05 2/week @ 2024-04-19

95 每月下载量

自定义许可证

1.5MB
963

Cargo Commander

运行命令的简单方式

Crates.io GitHub Sponsors GitHub last commit (branch) Build and test Website

简介

Cargo Commander旨在填补Cargo命令功能上的空白,即无法像npm脚本那样以类似的方式运行命令。但在做这件事的过程中,我决定给它添加一些额外的功能。

新功能:除了可以在Commands.tomlCargo.tomlpackage.json中指定的命令外,还在开发与cargo-script类似的脚本执行功能。您可以运行本地脚本,使用cargo cmd script.rs,或者运行远程脚本,使用cargo cmd https://url.to.script。目前这还处于早期测试阶段,通过运行rustc input -o output,然后执行输出,所以目前仅限于使用标准库,且脚本必须包含在该单个文件中。更多功能即将到来!

入门

您可以在 [commands][package.metadata.commands] 部分下创建您的命令,或者在 Cargo.toml 中创建一个新的 Commands.toml 文件。它们都使用相同的语法。如果存在,Cargo Commander 也会解析 scripts 部分内的 package.json。通常情况下,package.json 中的脚本只允许是字符串,但 Cargo Commander 通过将 json 转换为 toml 来解析 package.json,这意味着您可以在 json 中添加与 toml 中相同的所有选项。

# Install cargo-commander
cargo install cargo-commander
# Run your command
cargo cmd COMMAND

# Output of 'cargo cmd --help'
cargo-commander 2.0.15
A powerful tool for managing project commands

USAGE:
    cargo cmd [OPTIONS] [COMMAND/URL/FILE] [<ARGUMENTS>...]

ARGS:
    COMMAND              Name of the command to run
    URL                  Downloads a script, compiles then runs it
    FILE                 Compiles a file then runs it
    <ARGUMENTS>...       Arguments to the command

OPTIONS:
    -h, --help           Print help information
    -f, --file PATH      Custom path to command file to parse
    -p, --parallel       Forces all commands to run in parallel

命令

命令可以是字符串,也可以是使用以下字段自定义其行为的命令对象。

cmd = String or Array, where an array can either contain string commands or other command objects
parallel = true/false, only makes a difference if the command object contains an array, makes all commands run in parallel
shell = String, the syntax is simply "program arg arg arg"
env = Array, an array of strings in the format "VAR=SOMETHING"
args = Array, an array of strings in the format "ARG=Default value", if no default is given an empty string is used
working_dir = String, path to the directory to use as working directory either relative to the command file or the current directory

cmd

这可以是字符串、命令对象或命令对象的数组。

如果 cmd 是多行字符串,则命令的内容将保存到临时文件中,该文件在程序完成后安全删除。然后使用参数替换字符串中的内容,并且只将临时文件的路径发送到 shell。我们可以使用这种行为结合 shell 选项来创建一个文件,该文件的绝对路径将被传递为参数,以供您指定的任何程序作为 shell。请参阅示例以了解其外观。

command = "echo Basic usage"
command = ["echo As an array"]
command = { cmd = "echo Hello" }
command = { cmd = ["echo Hello", "echo World"] }
command = { cmd = [{ cmd = "echo And hello again" }] }
command = { cmd = { cmd = "echo Hello again" } }

parallel

布尔值,默认为 false。如果命令对象的 cmd 是一个数组,则所有子命令将同时运行。

command = { cmd = ["echo first", "echo second", "echo third"], parallel = true }

working_dir

字符串。命令应执行的路径。

command = { cmd = "ls", working_dir = "src" }
command = { cmd = "ls", working_dir = "path/to/folder" }

args

字符串数组,格式为 args=["arg","argument=Default"]。如果参数是一个未设置默认值的字符串,则它将被简单地替换为空字符串。

command = { cmd = "echo $name", args = ["name=World"] }

env

字符串数组,格式为 env=["variable=Value"]。在命令中设置环境变量。这与 args 的工作方式类似,但不同之处在于 env 会更改环境变量。从广义上讲,此选项不是特别有用,您可能想使用 load_dotenv 代替。

# Unix
command = { cmd = "echo $HELLO", env = ["HELLO=World"] }
# Windows
command = { cmd = "echo %HELLO%", env = ["HELLO=World"] }

load_dotenv

布尔值,默认为 false。允许您从 .env 文件加载环境变量。.env 文件应位于包含正在运行的命令的文件的同一文件夹中。此选项不受 working_dir 选项的影响。

# Create a .env file with the contents "HELLO=World"
# Unix
command = { cmd = "echo $HELLO", load_dotenv = true }
# Windows
command = { cmd = "echo %HELLO%", load_dotenv = true }

until

整数。哪个状态码被视为成功的运行。通常我们不检查命令的状态码,但使用此选项,我们可以指示命令重复执行,直到达到特定的退出码。如果您将其设置为 until=0,则表示您会一直运行命令,直到达到状态码 0 的退出码。使用 until=404,它会一直运行,直到达到代码 404。如果您想避免无限循环,应同时设置 max_repeat

command = { cmd = "echo Hello", until = 0 }

repeat

整数。命令预期运行的最少次数。如果您与 until 一起运行,则命令至少会运行此次数。

command = { cmd = "echo Hello", repeat = 2 }

延迟

整数或浮点数。在运行命令之前休眠的时间。如果您与任何基于重复的选项一起使用,此延迟将在每次运行命令之前添加。

command = { cmd = "echo Hello", delay = 2 }
command = { cmd = "echo Hello", delay = 3.7 }

max_repeat

整数。设置命令允许重试的最大次数。这主要在与 until 一起使用时有用。

command = { cmd = "echo Hello", repeat = 5, max_repeat = 1 }
command = { cmd = "echo Hello", until = 0, max_repeat = 1000 }

示例

打开文档

我倾向于为记录我的项目创建多个 mdbook 书籍。这真的很方便,但逐个打开它们可能有点麻烦。所以我会把打开每个文档的命令放在一个 docs 部分,然后使用 -p 标志并行运行该部分,而不是每个单独的页面。

# Commands.toml
[docs]
crate_one = { cmd = "mdbook serve --open --port 9001", working_dir = "crates/one/docs" }
crate_two = { cmd = "mdbook serve --open --port 9002", working_dir = "crates/two/docs" }
crate_three = { cmd = "mdbook serve --open --port 9003", working_dir = "crates/three/docs" }
crate_four = { cmd = "mdbook serve --open --port 9004", working_dir = "crates/four/docs" }

现在我们可以使用单个命令打开所有文档了!

cargo cmd -p docs

传递自定义参数

假设您想在不知道 pod 名称的情况下在 Kubernetes pod 中获取运行中的 shell,可能是因为 pod 是由例如 deployment 或 cronjob 创建的。您知道有一个 kubectl 命令可以在 pod 中获取运行中的 shell,问题是这个命令很长,每次都写起来很烦人,而且每次从别处复制粘贴命令都会很快变得重复。

# Commands.toml
shell = { cmd = "kubectl exec --stdin --tty $pod -- /bin/bash", args = ["pod"] }

现在我们可以通过简单地运行以下简化语法来始终获取 pod 的 shell。现在,您不需要同时找到 pod 名称并将其复制到较长的 kubectl 命令中,您现在可以轻松地记住您有一个 shell 命令,它接受 pod 参数。

cargo cmd shell pod=my-pod-123-654

运行脚本

通过结合 shell 选项和当命令是多行字符串时的行为,我们可以直接在您的命令中运行脚本。

# Using python -c
hello_py_c = { cmd = "print('Hello')", shell = "python -c" }
# Using python and multiline string and an argument
hello_py = { cmd = """import os
print("Hello")
print("$name")
""", args = ["name=World"], shell = "python" }

您可以按以下方式运行它

cargo cmd hello_py_c
Hello
# Or multiline
cargo cmd hello_py
Hello
World
# ... With argument
cargo cmd hello_py name=Commander
Hello
Commander

持续重试直到命令成功

有时您运行程序或编写脚本可能会失败。没关系,每个人都会遇到这种情况。也许它正在尝试连接的网络资源,也许是你电脑上的文件。无论什么原因,程序有时会以成功的代码 0 退出,有时会以代码 404 退出,因为它尝试访问的页面未找到。

我们可以使用 until 创建一个简单的重试循环,结合 delay 以确保程序运行不要太频繁,以及 max_repeat 以确保我们不永远尝试。

command = { cmd = "python script.py", until = 0, delay = 3, max_repeat = 1000 }

运行该命令会在每次重试之间有 3 秒的延迟,直到它得到 0 状态返回,或者最多重试 1000 次。

注意

环境变量不会持久化

我尝试让它按预期工作,但现在我觉得还是放弃算了,因为这要么是不可能实现的,要么是真的很烦人。所以每个命令都会有一组“新鲜”的环境变量,如果一个命令改变了环境变量,另一个命令不会接收到这些改变,它们在不同的shell中运行。你可以使用env选项,或者在每个命令中运行一个设置环境变量的脚本,或者使用load_dotenv.env文件中加载变量。我认为这些选项已经足够了,如果你真的想让变量跨命令持久存在,你必须提交一个包含你更改的pull请求,或者等待我愿意深入研究这个问题。

依赖关系

~5–48MB
~732K SLoC