[英]Two interdependant command line options with CommandLineUtils
我正在更新一個使用CommandLineUtils來解析命令行選項的項目。 選項是通過獲取CommandLineApplication
並對其調用cmd.Option()
來定義的,而不是將選項作為 class 中的屬性。例如:
public void Configure(CommandLineApplication cmd)
{
var aOpt = cmd.Option("-a", "Option A", CommandOptionType.SingleValue).IsRequired();
var bOpt = cmd.Option("-b", "Option B", CommandOptionType.SingleValue);
cmd.Command("subCommand1", subcmd =>
{
var cOpt = subcmd.Option("-c", "Option C", CommandOptionType.SingleValue).IsRequired();
var dOpt = subcmd.Option("-d", "Option D", CommandOptionType.SingleValue).IsRequired();
});
cmd.Command("subCommand2", subcmd =>
{
var fOpt = subcmd.Option("-f", "Option F", CommandOptionType.SingleValue).IsRequired();
});
}
我添加了一個案例,其中需要兩個選項之一,但不是兩個。 例如,如果這兩個選項是-a
和-c
,那么:
這些是有效的選項集:
cmd -a
或者
cmd-c
這些不是有效的選項集:
cmd -a -b
或者
cmd
我如何指定兩個選項是相關的,以至於至少需要其中一個選項? 我知道.IsRequired()
但這看起來不靈活。
(我的情況有點復雜,因為需要-c
,或者同時需要-a -d
)
可以通過將ICommandValidator
添加到cmd.Validators
來將自定義驗證添加到命令。
cmd.Validators.Add(new MyCommandValidator());
...
private class MyCommandValidator: ICommandValidator
{
public ValidationResult GetValidationResult(CommandLineApplication command, ValidationContext context)
{
return ValidationResult.Success;
}
}
在示例問題中,有一個帶有子命令的命令。 如果將其添加到多個命令,此驗證器可以檢查正在使用command.Name
處理哪個命令。 但它只會執行添加到的命令。
if (command.Name == "subCommand1") { ... }
要訪問選項,請使用cmd.GetOptions()
。 這將提供所有可用選項的列表,並包括它們的值。 cmd.Options
也可以訪問,但僅限於用戶指定的選項。
可以通過ShortName
或LongName
查找特定選項。
var aOpt = command.GetOptions().First(o => o.ShortName == "a");
HasValue()
或Value()
可用於查看設置了哪些選項以及它們是否具有用戶設置的值。 如果選項無效,則返回一個new ValidationResult("Custom error");
把它們放在一起:
// In subCommand1 definition
subcmd.Validators.Add(new MyCommandValidator());
...
private class MyCommandValidator: ICommandValidator
{
public ValidationResult GetValidationResult(CommandLineApplication command, ValidationContext context)
{
var allOpts = command.GetOptions();
var aOpt = allOpts.First(o => o.ShortName = "a");
var cOpt = allOpts.First(o => o.ShortName = "c");
var dOpt = allOpts.First(o => o.ShortName = "d");
// Either -a or -c is required
if (!cOpt.HasValue())
{
if (!aOpt.HasValue())
{
return new ValidationResult("Either -a or -c is required.");
}
// If -a is provided, -d is required
aOpt.IsRequired();
dOpt.IsRequired();
}
// If -c is provided, -a and -d are not allowed
else if (aOpt.HasValue() || dOpt.HasValue())
{
return new ValidationResult($"{cOpt.LongName} should not be used with {aOpt.LongName} or {dOpt.LongName}.");
}
// Options are valid
return ValidationResult.Success;
}
}
請注意,如果 subCommand2 沒有復雜的驗證並且始終需要-a
,則在其命令定義中添加aOpt.IsRequired()
就足夠了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.