Подтвердить что ты не робот

Командный синтаксический анализатор с взаимоисключающими требуемыми параметрами

Я начал использовать библиотеку Python CommandLine для инструмента, который будет иметь как графический интерфейс, так и выполнение командной строки. Запуск графического интерфейса выполняется с помощью опции командной строки.

Поэтому мне хотелось бы иметь необходимые параметры, если программа выполняется в режиме командной строки. В принципе, я бы хотел, чтобы опция 1 и вариант 2 требовались, если параметр "Gui" не установлен.

Я попытался объединить атрибуты MutuallyExclusiveSet и Required, как показано ниже, но он не работает, как я думал. Не понял ли я концепцию "MutuallyExclusiveSet" или просто неправильно ее использовал? Или это то, что библиотека еще не поддерживает?

public class CommandLineOptions : CommandLineOptionsBase
{
    [Option(null, "gui", Required = false, HelpText = "Launch the GUI", MutuallyExclusiveSet = "Gui")]
    public bool Gui { get; set; }

    [Option(null, "opt1", HelpText = "Option 1", MutuallyExclusiveSet = "CommandLine", Required = true)]
    public string Option1 { get; set; }

    [Option(null, "opt2", HelpText = "Option 2", MutuallyExclusiveSet = "CommandLine", Required = true)]
    public string Option2 { get; set; }
}
4b9b3361

Ответ 1

Все параметры, принадлежащие взаимоисключающему набору, взаимно исключают друг друга. Следуйте этому примеру:

class Options {
  [Option("a", null, MutuallyExclusiveSet="zero")] 
  public string OptionA { get; set; }
  [Option("b", null, MutuallyExclusiveSet="zero")] 
  public string OptionB { get; set; }
  [Option("c", null, MutuallyExclusiveSet="one")] 
  public string OptionC { get; set; }
  [Option("d", null, MutuallyExclusiveSet="one")] 
  public string OptionD { get; set; }
}

С этими правилами допустимы следующие строки:

$ app -a foo -c bar
$ app -a foo -d bar
$ app -b foo -c bar
$ app -b foo -d bar

и это не так:

$ app -a foo -b bar
$ app -c foo -d bar
$ app -a foo -b bar -c foo1 -d foo2

Как вы можете видеть, вы не можете указывать вместе параметры, принадлежащие одному набору. Помните также, что предварительно построенный синглтон (CommandLineParser.Default) не работает с атрибутом MutualliyExclusiveSet. Вам нужно нарядить парсер самостоятельно:

if (new CommandLineParser(new CommandLineParserSettings {
                            MutuallyExclusive = true,
                            CaseSensitive = true,
                            HelpWriter = Console.Error}).ParseArguments(args, opts) {
  // consume values here
  Console.WriteLine(opts.OptionA);
}

Вот как работают взаимоисключающие опции в командной строке Parser Library. В любом случае, чтобы решить вашу конкретную проблему, я предлагаю вам определить все параметры, как в обычном консольном приложении. Затем добавьте булевский переключатель Gui. Если указан этот параметр, игнорируйте другие. Если вы не ведете себя как обычное консольное приложение.

(Другое дело: в следующей версии будет функция подкоманд, которая позволит вам управлять несколькими типами параметров, это может быть подходящим для этой предстоящей функции.)

EDIT 2015-08-30:

Функция, реализованная в 1.9.x stable, всегда создавала путаницу, была отключена по умолчанию и потребовала, чтобы разработчик активировал ее с помощью экземпляра настроек.

Версия 2.0.x, где ядро ​​было полностью переписано, функция всегда активна, и я попытаюсь показать простой пример (помните, что публичный API изменен, так как 2.0.x является основным выпуском обновления).


class Options {
  [Option(SetName = "web")]
  public string WebUrl { get; set; }
  [Option(SetName = "web")]
  public int MaxLinks { get; set; }

  [Option(SetName = "ftp")]
  public string FtpUrl { get; set; }
  [Option(SetName = "ftp")]
  public int MaxFiles { get; set; }

  [Option]
  public bool Verbose { get; set; }
}

Установить из набора ftp несовместимые с тегами web, --verbose (который не принадлежит к набору или лучше принадлежит к стандарту "", является нейтральным и может смешиваться в будем). Действительно:


$ app --weburl http://stackoverflow.com --maxlinks 99
$ app --ftpurl ftp://ftp.myoffice.files.com --maxfiles 1234
$ app --verbose --weburl http://twitter.com --maxlinks 777
$ app --ftpurl ftp://ftp.xyz.org --maxfiles 44 --verbose
$ app --verbose

Недействительно:


$ app --weburl http://stackoverflow.com --maxlinks 99 --ftpurl ftp://ftp.xyz.org
$ app --ftpurl ftp://ftp.myoffice.files.com --maxfiles 1234 --maxlinks 777
$ app --verbose --weburl http://twitter.com --maxfiles 44
$ app --maxfiles 44 --maxlinks 99