以下部分介绍了在设计 CLI 时建议遵循的指南。 考虑你的应用在命令行中期望的内容,这与 REST API 服务器在 URL 中期望的类似。 REST API 的一致规则使它们可供客户端应用开发人员使用。 同样,如果 CLI 设计遵循常见模式,命令行应用的用户将拥有更好的体验。
创建 CLI 后,很难更改,尤其是在用户希望继续运行的脚本中使用 CLI 时。 此处的准则是在 .NET CLI 之后开发的,它并不总是遵循这些准则。 我们正在更新 .NET CLI,无需引入重大更改即可执行此作。 此工作的示例是 .NET 7 中 dotnet new
的新设计。
符号
命令和子命令
如果命令具有子命令,该命令应充当子命令的区域或分组标识符,而不是指定作。 调用应用时,可以指定分组命令及其子命令之一。 例如,尝试运行 dotnet tool
并收到错误消息,因为 tool
该命令仅标识一组与工具相关的子命令,例如 install
和 list
。 你可以运行 dotnet tool install
,但 dotnet tool
本身会不完整。
有一种定义区域的方法可以帮到你的用户,那就是整理帮助输出。
在 CLI 中,通常存在隐式区域。 例如,在 .NET CLI 中,隐式区域是项目,在 Docker CLI 中,它是映像。 因此,无需包括区域即可使用 dotnet build
。 请考虑 CLI 是否具有隐式区域。 如果这样做,请考虑是允许用户选择包含还是省略它,如在和docker image build
中docker build
一样。 如果你选择允许用户键入隐式区域,则对于这组命令,你还会自动获得帮助和 Tab 键补全功能。 通过定义执行相同作的两个命令来提供隐式组的可选用法。
作为参数的选项
选项应该为命令提供参数,而不是指定动作本身。 这是建议的设计原则,尽管它并不总是遵循 System.CommandLine
(--help
显示帮助信息)。
命名
短格式别名
一般情况下,我们建议尽量减少定义的短格式选项别名数。
具体而言,请避免使用与 .NET CLI 和其他 .NET 命令行应用中的常见用法不同的以下任何别名:
-i
表示--interactive
。此选项向用户发出信号,表明他们可能需要为命令所需回答的问题提供输入。 例如,提示输入用户名。 CLI 可以在脚本中使用,因此在提示未指定此开关的用户时要小心。
-o
表示--output
。某些命令由于执行而生成文件。 此选项应用于帮助确定这些文件应位于何处。 如果创建了单个文件,则此选项应为文件路径。 如果创建了多个文件,则此选项应是目录路径。
-v
表示--verbosity
。命令通常向用户提供控制台上的输出;此选项用于指定用户请求的输出量。 有关详细信息,请参阅
--verbosity
本文后面的选项。
也有一些别名,常见用法仅限于 .NET CLI。 可以将这些别名用于应用中的其他选项,但请注意混淆的可能性。
-c
用于--configuration
此选项通常指命名的生成配置,例如
Debug
或Release
。 可以使用配置所需的任何名称,但大多数工具都期望其中一个。 此设置通常用于以对配置有意义的方式配置其他属性,例如,在生成Debug
配置时执行更少的代码优化。 如果命令具有不同的作模式,请考虑此选项。-f
用于--framework
此选项用于选择要执行的单个目标框架名字对象 (TFM),因此,如果你的 CLI 应用程序根据所选择的 TFM 而有不同的行为,则应支持此标记。
-p
用于--property
如果应用程序最终调用 MSBuild,用户通常需要以某种方式自定义该调用。 此选项允许在命令行上提供 MSBuild 属性,并传递给基础 MSBuild 调用。 如果你的应用不使用 MSBuild,但需要一组键值对,请考虑使用相同的选项名称来利用用户的期望。
-r
用于--runtime
如果应用程序可以在不同的运行时上运行,或者具有特定于运行时的逻辑,请考虑将此选项作为指定 运行时标识符的方法。 如果应用支持
--runtime
,请考虑支持--os
和--arch
支持。 通过这些选项,您可以指定 RID 的操作系统或体系结构部分,未指定的部分将根据当前平台自动确定。 有关详细信息,请查看 dotnet publish。
短名称
把命令、选项和参数的名称尽量缩短,并使其易于拼写。 例如,如果 class
足够清楚,请不要发出命令 classification
。
小写名称
仅以小写形式定义名称,但可以创建大写别名以使命令或选项不区分大小写。
小写短横线式名称
使用小写短横线格式来区分词语。 例如,--additional-probing-path
。
复数形式
在应用中,单复数形式要保持一致。 例如,不要为可能具有多个值(最大元数大于1)的选项混合使用复数和单数名称:
选项名称 | 一致性 |
---|---|
--additional-probing-paths 和 --sources |
✔️ |
--additional-probing-path 和 --source |
✔️ |
--additional-probing-paths 和 --source |
❌ |
--additional-probing-path 和 --sources |
❌ |
谓词与名词
在引用动作的命令中使用动词,而不是名词(这些命令下没有子命令),例如:dotnet workload remove
,而不是dotnet workload removal
。 对选项使用名词而不是谓词,例如: --configuration
,而不是 --configure
。
--verbosity
选项
System.CommandLine
应用程序通常提供一个选项 --verbosity
,用于指定发送到控制台的输出量。 下面是标准五个设置:
Q[uiet]
M[inimal]
N[ormal]
D[etailed]
Diag[nostic]
这些是标准名称,但现有应用有时使用Silent
代替Quiet
,或者Trace
Debug
Verbose
代替Diagnostic
。
每个应用定义自己的条件,以确定每个级别显示的内容。 通常,应用只需要三个级别:
- 安静
- 正常
- 诊断
如果应用不需要五个不同的级别,该选项仍应定义相同的五个设置。 在这种情况下,Minimal
和Normal
将生成相同的输出,同时Detailed
和Diagnostic
也会生成相同的输出。 这样,用户就可以键入他们熟悉的内容,并且会使用最适合的内容。
对于Quiet
的期望是控制台上不显示任何输出。 但是,如果应用提供交互式模式,应用应执行以下作之一:
- 指定
--interactive
时显示输入提示,即使--verbosity
为Quiet
也是如此。 - 禁止使用
--verbosity Quiet
和--interactive
一起使用。
否则,应用将等待输入,而不告知用户正在等待的内容。 应用程序似乎已冻结,并且用户不知道应用程序正在等待输入。
如果定义别名,请使用 -v
为 --verbosity
,并将不带参数的 -v
作为 --verbosity Diagnostic
的别名。 使用 -q
代替 --verbosity Quiet
.
.NET CLI 和 POSIX 约定
.NET CLI 不一致地遵循所有 POSIX 约定。
双短划线
.NET CLI 中的多个命令具有双划线令牌的特殊实现。 在dotnet run
、dotnet watch
和dotnet tool run
情况下,紧随--
之后的令牌会传递给由命令运行的应用程序。 例如:
dotnet run --project ./myapp.csproj -- --message "Hello world!"
^^
在此示例中,--project
选项被传递给 dotnet run
命令,而 --message
选项及其参数作为命令行选项在 myapp 运行时传递。
将选项传递给通过使用 --
运行的应用时,不一定始终需要 dotnet run
令牌。 如果没有双短划线,dotnet run
命令会自动将未识别为应用到 dotnet run
自身或 MSBuild 的选项传递给正在运行的应用。 因此,下面的命令行是等效的,因为 dotnet run
无法识别参数和选项:
dotnet run -- quotes read --delay 0 --fg-color red
dotnet run quotes read --delay 0 --fg-color red
省略选项-自变量分隔符
.NET CLI 不支持 POSIX 约定,该约定允许在指定单字符选项别名时省略分隔符。
在不重复选项名称的情况下允许多个自变量
在不重复选项名称的情况下,.NET CLI 不接受一个选项的多个参数。
布尔选项
在 .NET CLI 中,某些布尔选项在传递false
时与传递true
时的行为相同。 当实现选项的 .NET CLI 代码仅检查选项的存在或缺失时,而忽略该值时,就会出现这种行为。 例如,--no-restore
命令的 dotnet build
。 传递 --no-restore false
,恢复操作将被跳过,就像指定 --no-restore true
或 --no-restore
时一样。
小写短横线格式
在某些情况下,.NET CLI 不会对命令、选项或自变量名称使用小写短横线格式。 例如,有一个名为--additionalprobingpath
而不是--additional-probing-path
的.NET CLI选项。