4个稳定版本
2.0.15 | 2022年12月2日 |
---|---|
2.0.14 | 2022年11月30日 |
2.0.12 | 2022年7月29日 |
2.0.10 |
|
0.1.14 |
|
#74 在 Cargo插件 中排名
95 每月下载量
1.5MB
963 行
简介
Cargo Commander旨在填补Cargo命令功能上的空白,即无法像npm脚本那样以类似的方式运行命令。但在做这件事的过程中,我决定给它添加一些额外的功能。
新功能:除了可以在Commands.toml
、Cargo.toml
或package.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