簡體   English   中英

CommandLineUtils 的兩個相互依賴的命令行選項

[英]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也可以訪問,但僅限於用戶指定的選項。

可以通過ShortNameLongName查找特定選項。

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM