Важный
Этот репозиторий переехал на https://github.com/dart-lang/core/tree/main/pkgs/args.
Разбирает необработанные аргументы командной строки в набор параметров и значений.
Эта библиотека поддерживает параметры стиля GNU и POSIX и работает как в серверных, так и в клиентских приложениях.
Сначала создайте ArgParser:
var parser = ArgParser();
Затем определите набор опций для этого анализатора, используя addOption() и addFlag(). Вот минимальный способ создания опции с именем «имя»:
parser.addOption('name');
Если параметр можно только установить или снять (в отличие от строкового значения), используйте флаг:
parser. addFlag ( 'name' );
Параметры флага по умолчанию принимают префикс «нет-», чтобы отменить параметр. Вы можете отключить префикс «no-», используя negatable
параметр:
parser. addFlag ( 'name' , negatable : false );
Примечание. Здесь и далее «опция» относится как к обычным опциям, так и к флагам. В тех случаях, когда различие имеет значение, мы будем использовать вариант «без флага».
Опции могут иметь необязательное односимвольное сокращение, указанное с помощью параметра abbr
:
parser. addOption ( 'mode' , abbr : 'm' );
parser. addFlag ( 'verbose' , abbr : 'v' );
Параметры также могут иметь значение по умолчанию, указанное с помощью параметра defaultsTo
. Значение по умолчанию используется, когда аргументы не указывают этот параметр.
parser. addOption ( 'mode' , defaultsTo : 'debug' );
parser. addFlag ( 'verbose' , defaultsTo : false );
Значением по умолчанию для параметров без флагов может быть любая строка. Для флагов это должно быть bool
.
Чтобы проверить опцию без флага, вы можете использовать параметр allowed
, чтобы предоставить разрешенный набор значений. Когда вы это сделаете, анализатор выдаст исключение ArgParserException
, если значение параметра не входит в разрешенный набор. Вот пример указания допустимых значений:
parser. addOption ( 'mode' , allowed : [ 'debug' , 'release' ]);
Вы можете использовать параметр callback
, чтобы связать функцию с опцией. Позже, когда происходит синтаксический анализ, вызывается функция обратного вызова со значением опции:
parser. addOption ( 'mode' , callback : (mode) => print ( 'Got mode $ mode ' ));
parser. addFlag ( 'verbose' , callback : (verbose) {
if (verbose) print ( 'Verbose' );
});
Обратные вызовы для всех параметров вызываются всякий раз, когда анализируется набор аргументов. Если опция не указана в аргументах, ее обратному вызову передается значение по умолчанию или null
, если значение по умолчанию не установлено.
Если опция является mandatory
, но не указана, объект результатов выдает [ ArgumentError
][ArgumentError] при получении.
parser. addOption ( 'mode' , mandatory : true );
После настройки ArgParser с некоторыми параметрами и флагами вы можете использовать его, вызывая ArgParser.parse() с набором аргументов:
var results = parser. parse ([ 'some' , 'command' , 'line' , 'args' ]);
Эти аргументы обычно берутся из аргументов функции main()
. Например:
main(List<String> args) {
// ...
var results = parser.parse(args);
}
Однако вы можете передать любой список строк. Метод parse()
возвращает экземпляр ArgResults, объекта, похожего на карту, который содержит значения анализируемых параметров.
var parser = ArgParser ();
parser. addOption ( 'mode' );
parser. addFlag ( 'verbose' , defaultsTo : true );
var results = parser. parse ([ '--mode' , 'debug' , 'something' , 'else' ]);
print (results. option ( 'mode' )); // debug
print (results. flag ( 'verbose' )); // true
По умолчанию метод parse()
позволяет передавать дополнительные флаги и параметры после позиционных параметров, если только --
не используется для указания того, что все дальнейшие параметры будут позиционными. Позиционные аргументы передаются в ArgResults.rest.
print (results.rest); // ['something', 'else']
Чтобы остановить анализ параметров, как только будет найден позиционный аргумент, allowTrailingOptions: false
при создании ArgParser.
Чтобы передать параметры и флаги в командной строке, используйте стиль GNU или POSIX. Рассмотрите этот вариант:
parser. addOption ( 'name' , abbr : 'n' );
Вы можете указать его значение в командной строке, используя любой из следующих способов:
--name=somevalue
--name somevalue
-nsomevalue
-n somevalue
Рассмотрим этот флаг:
parser. addFlag ( 'name' , abbr : 'n' );
Вы можете установить для него значение true, используя одно из следующих действий:
--name
-n
Вы можете установить значение false, используя следующее:
--no-name
Несколько сокращений флагов можно объединить в один аргумент. Допустим, вы определяете эти флаги:
parser
.. addFlag ( 'verbose' , abbr : 'v' )
.. addFlag ( 'french' , abbr : 'f' )
.. addFlag ( 'iambic-pentameter' , abbr : 'i' );
Вы можете установить все три флага одновременно:
-vfi
По умолчанию параметр имеет только одно значение, причем более поздние значения параметра переопределяют более ранние; например:
var parser = ArgParser ();
parser. addOption ( 'mode' );
var results = parser. parse ([ '--mode' , 'on' , '--mode' , 'off' ]);
print (results. option ( 'mode' )); // prints 'off'
Несколько значений можно проанализировать с помощью addMultiOption()
. С помощью этого метода опция может встречаться несколько раз, а метод parse()
возвращает список значений:
var parser = ArgParser ();
parser. addMultiOption ( 'mode' );
var results = parser. parse ([ '--mode' , 'on' , '--mode' , 'off' ]);
print (results. multiOption ( 'mode' )); // prints '[on, off]'
По умолчанию значения многозначного параметра также могут быть разделены запятыми:
var parser = ArgParser ();
parser. addMultiOption ( 'mode' );
var results = parser. parse ([ '--mode' , 'on,off' ]);
print (results. multiOption ( 'mode' )); // prints '[on, off]'
Это можно отключить, передав splitCommas: false
.
Помимо опций , вы также можете определять команды . Команда — это именованный аргумент, имеющий собственный набор параметров. Например, рассмотрим эту команду оболочки:
$ git commit -a
Исполняемый файл — git
, команда — commit
, а опция -a
— это опция, передаваемая команде. Вы можете добавить команду, используя метод addCommand:
var parser = ArgParser ();
var command = parser. addCommand ( 'commit' );
Он возвращает другой ArgParser, который затем можно использовать для определения параметров, специфичных для этой команды. Если у вас уже есть ArgParser для параметров команды, вы можете передать его:
var parser = ArgParser ();
var command = ArgParser ();
parser. addCommand ( 'commit' , command);
Затем ArgParser для команды может определять параметры или флаги:
command. addFlag ( 'all' , abbr : 'a' );
Вы можете добавить несколько команд в один и тот же анализатор, чтобы пользователь мог выбрать одну из диапазона возможных команд. При анализе списка аргументов вы можете определить, какая команда была введена и какие параметры для нее были предоставлены.
var results = parser. parse ([ 'commit' , '-a' ]);
print (results.command.name); // "commit"
print (results.command[ 'all' ]); // true
Параметры команды должны располагаться после команды в списке аргументов. Например, для приведенного выше парсера "git -a commit"
недопустим . Анализатор пытается найти самую правую команду, которая принимает опцию. Например:
var parser = ArgParser ();
parser. addFlag ( 'all' , abbr : 'a' );
var command = parser. addCommand ( 'commit' );
command. addFlag ( 'all' , abbr : 'a' );
var results = parser. parse ([ 'commit' , '-a' ]);
print (results.command[ 'all' ]); // true
Здесь и парсер верхнего уровня, и команда "commit"
могут принимать "-a"
(что, по общему признанию, вероятно, является плохим интерфейсом командной строки). В этом случае, когда после "commit"
появляется "-a"
, он применяется к этой команде. Если он отображается слева от "commit"
, он передается парсеру верхнего уровня.
Если вы пишете приложение на основе команд, вы можете использовать классы CommandRunner и Command, чтобы структурировать его. CommandRunner имеет встроенную поддержку отправки команд на основе аргументов командной строки, а также обработки флагов --help
и недопустимых аргументов.
При использовании CommandRunner он заменяет ArgParser.
В следующем примере мы создаем приложение dgit под названием dgit
, которое принимает команды commit
и stash
.
CommandRunner принимает executableName
, которое используется для создания справочного сообщения.
например, dgit commit -a
Файл dgit.dart
void main ( List < String > args) {
var runner = CommandRunner ( "dgit" , "A dart implementation of distributed version control." )
.. addCommand ( CommitCommand ())
.. addCommand ( StashCommand ())
.. run (args);
}
Когда приведенная выше строка run(args)
выполняется, она анализирует аргументы командной строки в поисках одной из команд ( commit
или stash
).
Если CommandRunner находит соответствующую команду, то CommandRunner вызывает переопределенный метод run()
для соответствующей команды (например, CommitCommand().run).
Команды определяются путем расширения класса Command. Например:
class CommitCommand extends Command {
// The [name] and [description] properties must be defined by every
// subclass.
final name = "commit" ;
final description = "Record changes to the repository." ;
CommitCommand () {
// we can add command specific arguments here.
// [argParser] is automatically created by the parent class.
argParser. addFlag ( 'all' , abbr : 'a' );
}
// [run] may also return a Future.
void run () {
// [argResults] is set before [run()] is called and contains the flags/options
// passed to this command.
print (argResults. flag ( 'all' ));
}
}
CommandRunner позволяет вам указывать как глобальные аргументы, так и аргументы, специфичные для команды (и даже аргументы, специфичные для подкоманды).
Добавьте аргументы непосредственно в CommandRunner, чтобы указать глобальные аргументы:
Добавление глобальных аргументов
var runner = CommandRunner ( 'dgit' , "A dart implementation of distributed version control." );
// add global flag
runner.argParser. addFlag ( 'verbose' , abbr : 'v' , help : 'increase logging' );
Добавьте аргументы к каждой команде, чтобы указать аргументы, специфичные для команды.
CommitCommand () {
// we can add command specific arguments here.
// [argParser] is automatically created by the parent class.
argParser. addFlag ( 'all' , abbr : 'a' );
}
Команды также могут иметь подкоманды, которые добавляются с помощью команды addSubcommand. Команда с подкомандами не может запускать собственный код, поэтому реализацию run не требуется. Например:
class StashCommand extends Command {
final String name = "stash" ;
final String description = "Stash changes in the working directory." ;
StashCommand () {
addSubcommand ( StashSaveCommand ());
addSubcommand ( StashListCommand ());
}
}
CommandRunner автоматически добавляет команду help
, которая отображает информацию об использовании команд, а также поддерживает флаг --help
для всех команд. Если он обнаруживает ошибку при анализе аргументов или обработке команды, он выдает UsageException; ваш метод main()
должен их перехватывать и печатать соответствующим образом. Например:
runner. run (arguments). catchError ((error) {
if (error is ! UsageException ) throw error;
print (error);
exit ( 64 ); // Exit code 64 indicates a usage error.
});
Вы можете автоматически генерировать красивый текст справки, подходящий для использования в качестве вывода --help
. Чтобы отобразить полезную информацию об использовании, вам следует предоставить некоторый справочный текст при создании параметров.
Чтобы определить текст справки для всей опции, используйте параметр help:
::
parser. addOption ( 'mode' , help : 'The compiler configuration' ,
allowed : [ 'debug' , 'release' ]);
parser. addFlag ( 'verbose' , help : 'Show additional diagnostic info' );
Для параметров без флага вы также можете предоставить строку справки для параметра:
parser. addOption ( 'out' , help : 'The output path' , valueHelp : 'path' ,
allowed : [ 'debug' , 'release' ]);
Для параметров без флага вы также можете предоставить подробную справку для каждого ожидаемого значения, используя параметр allowedHelp:
::
parser. addOption ( 'arch' , help : 'The architecture to compile for' ,
allowedHelp : {
'ia32' : 'Intel x86' ,
'arm' : 'ARM Holding 32-bit chip'
});
Чтобы отобразить справку, используйте геттер использования:
print (parser.usage);
Результирующая строка выглядит примерно так:
--mode The compiler configuration
[debug, release]
--out=<path> The output path
--[no-]verbose Show additional diagnostic info
--arch The architecture to compile for
[arm] ARM Holding 32-bit chip
[ia32] Intel x86