Класс CliBuilder для быстрой и лаконичной сборки приложений командной строки был обновлен в Apache Groovy 2.5.
Это вторая статья из двух частей, в которой рассказывается, что нового. В случае, если вы пропустили это, часть 1 здесь.
В этой статье показаны некоторые расширенные функции базовых библиотек из CliBuilder.
Краткий groovy.util.CliBuilder
части 1 : класс groovy.util.CliBuilder
устарел. Вместо этого теперь есть две реализации CliBuilder в разных модулях, одна с Apache Commons CLI в качестве базовой библиотеки синтаксического анализатора, и новая, основанная на анализаторе picocli.
Рекомендуется, чтобы приложения явно импортировали либо groovy.cli.picocli.CliBuilder
либо groovy.cli.commons.CliBuilder
. Класс groovy.util.CliBuilder
устарел и делегируется версии CLI Commons для обратной совместимости.
Новые функции, скорее всего, будут добавлены только в версию picocli, и groovy.util.CliBuilder
может быть удален в будущей версии Groovy. Версия Commons CLI предназначена для приложений, которые полагаются на внутреннюю часть реализации Commons CLI в CliBuilder и не могут легко перейти на версию picocli.
Далее, давайте взглянем на некоторые расширенные функции, предлагаемые этими базовыми библиотеками синтаксического анализа командной строки.
Apache Commons CLI Особенности
Иногда вы можете захотеть использовать расширенные функции базовой библиотеки синтаксического анализа. Например, у вас может быть приложение командной строки с взаимоисключающими параметрами. В приведенном ниже коде показано, как этого добиться с помощью API-интерфейса Apache Commons CLI OptionGroup
:
01
02
03
04
05
06
07
08
09
10
11
12
|
import groovy.cli.commons.CliBuilder import org.apache.commons.cli.* def cli = new CliBuilder() def optionGroup = new OptionGroup() optionGroup.with { addOption cli.option( 's' , [longOpt: 'silent' ], 's option' ) addOption cli.option( 'v' , [longOpt: 'verbose' ], 'v option' ) } cli.options.addOptionGroup optionGroup assert !cli.parse( '--silent --verbose' .split()) ( 1 ) |
- Синтаксический анализ этого ввода завершится неудачно, так как были указаны две взаимоисключающие опции.
Picocli CliBuilder Особенности
Сильно типизированные списки
Параметры с несколькими значениями часто используют массив или список для захвата значений. Массивы могут быть строго типизированы, то есть содержать элементы, отличные от String. Версия CliBuilder для Picocli позволяет делать то же самое со списками. auxiliaryType
указывает тип, в который элементы должны быть преобразованы. Например:
1
2
3
4
5
6
7
|
import groovy.cli.picocli.CliBuilder def cli = new CliBuilder() cli.T(type: List, auxiliaryTypes: Long, 'typed list' ) ( 1 ) def options = cli.parse( '-T 1 -T 2 -T 3' .split()) ( 2 ) assert options.Ts == [ 1L, 2L, 3L ] ( 3 ) |
- Определите параметр, который может иметь несколько целочисленных значений.
- Пример командной строки.
- Значения параметра представлены в виде
List<Integer>
.
Сильно типизированные карты
Версия CliBuilder для picocli предлагает встроенную поддержку параметров карты. Это так же просто, как указать карту в качестве типа параметра. По умолчанию ключи и значения хранятся в виде строк на карте, но можно использовать auxiliaryType
тип, чтобы указать типы, в которые должны быть преобразованы ключи и значения.
01
02
03
04
05
06
07
08
09
10
11
|
import groovy.cli.picocli.CliBuilder def cli = new CliBuilder() cli.D(args: 2 , valueSeparator: '=' , 'Commons CLI style map' ) ( 1 ) cli.X(type: Map, 'picocli style map support' ) ( 2 ) cli.Z(type: Map, auxiliaryTypes: [TimeUnit, Integer].toArray(), 'typed map' ) ( 3 ) def options = cli.parse( '-Da=b -Dc=d -Xx=y -Xi=j -ZDAYS=2 -ZHOURS=23' .split()) ( 4 ) assert options.Ds == [ 'a' , 'b' , 'c' , 'd' ] ( 5 ) assert options.Xs == [ 'x' : 'y' , 'i' : 'j' ] ( 6 ) assert options.Zs == [ (DAYS as TimeUnit): 2 , (HOURS as TimeUnit): 23 ] ( 7 ) |
- CLI Commons имеет параметры, подобные карте, указав, что каждый параметр должен иметь два параметра с некоторым разделителем.
- Версия CliBuilder для picocli имеет встроенную поддержку параметров карты.
- Тип ключа и тип значения могут быть указаны для строго типизированных карт.
- Пример командной строки.
- Опция стиля CLI Commons дает список объектов [ключ, значение, ключ, значение,…].
- Опция стиля picocli дает результат в виде
Map<String, String>
. - Если указаны
auxiliaryTypes
типы, ключи и значения карты преобразуются в указанные типы, получаяMap<TimeUnit, Integer>
.
Справка по использованию с подробным резюме
CliBuilder всегда поддерживал свойство use для отображения справки по использованию команды:
1
2
|
// the old way new CliBuilder(usage: 'myapp [options]' ).usage() |
Вышеприведенная программа печатает:
1
|
Usage: myapp [options] |
Это все еще работает, но у версии picocli есть лучшая альтернатива со свойством name
. Если вы укажете name
вместо usage
, picocli покажет все параметры в кратком резюме с квадратными скобками [
и ]
для необязательных элементов и многоточие …
элементов, которые могут повторяться один или несколько раз. Например:
1
2
3
4
5
|
def cli = new CliBuilder(name: 'myapp' ) // detailed synopsis cli.a( 'option a description' ) cli.b( 'option b description' ) cli.c(type: List, 'option c description' ) cli.usage() |
Вышеприведенная программа печатает:
1
2
3
4
5
|
Usage: myapp [-ab] [-c=PARAM]... the new way -a option a description -b option b description -c= PARAM option c description |
Используйте любые названия опций
Ранее, если у опции было несколько имен с одним дефисом, у вас не было выбора, кроме как объявить опцию несколько раз:
1
2
3
4
|
// before: split -cp, -classpath into two options def cli = new CliBuilder(usage: 'groovyConsole [options] [filename]' ) cli.classpath( 'Where to find the class files' ) cli.cp(longOpt: 'classpath' , 'Aliases for ' -classpath') |
Версия CliBuilder для picocli поддерживает свойство names
которое может иметь любое количество имен параметров, которые могут принимать любой префикс. Например:
1
2
3
|
// after: an option can have many names with any prefix def cli = new CliBuilder(usage: 'groovyConsole [options] [filename]' ) cli._(names: [ '-cp' , '-classpath' , '--classpath' ], 'Where to find the class files' ) |
Мелкозернистое Справочное сообщение об использовании
Picocli предлагает детальный контроль над форматом сообщения справки об использовании, и эта функциональность предоставляется через свойство usageMessage
CliBuilder.
Сообщение об использовании имеет несколько разделов: заголовок, краткий обзор, описание, параметры, параметры и, наконец, нижний колонтитул. Каждый раздел имеет заголовок, который предшествует первой строке его раздела. Например:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
import groovy.cli.picocli.CliBuilder def cli = new CliBuilder() cli.name = "groovy clidemo" cli.usageMessage.with { ( 1 ) headerHeading( "Header heading:%n" ) ( 2 ) header( "header 1" , "header 2" ) ( 3 ) synopsisHeading( "%nUSAGE: " ) descriptionHeading( "%nDescription heading:%n" ) description( "description 1" , "description 2" ) optionListHeading( "%nOPTIONS:%n" ) footerHeading( "%nFooter heading:%n" ) footer( "footer 1" , "footer 2" ) } cli.a(longOpt: 'aaa' , 'a-arg' ) ( 4 ) cli.b(longOpt: 'bbb' , 'b-arg' ) cli.usage() |
- Используйте
usageMessage
CliessMuageMessage для настройки сообщения справки об использовании. - Заголовки могут содержать спецификаторы формата строки, такие как символ новой строки
%n
. - Разделы многострочные: каждая строка будет отображаться на отдельной строке.
- Определите некоторые варианты.
Это печатает следующий вывод:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
Header heading: header 1 header 2 USAGE: groovy clidemo [-ab] Description heading: description 1 description 2 OPTIONS: -a, --aaa a-arg -b, --bbb b-arg Footer heading: footer 1 footer 2 |
Справка по использованию с цветами ANSI
Из коробки имя команды, имена опций и метки параметров в сообщении помощи по использованию отображаются со стилями и цветами ANSI . Цветовая схема для этих элементов может быть настроена с помощью системных свойств.
Кроме этого, вы можете использовать цвета и стили в описаниях и других разделах справочного сообщения об использовании, используя простую запись разметки . Пример ниже демонстрирует:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
def cli = new groovy.cli.picocli.CliBuilder(name: 'myapp' ) cli.usageMessage.with { headerHeading( "@|bold,red,underline Header heading|@:%n" ) header($/@|bold,green \ ___ _ _ ___ _ _ _ / __| (_) _ )_ _(_) |__| |___ _ _ | (__| | | _ \ || | | / _` / -_) '_| \___|_|_|___/\_,_|_|_\__,_\___|_| |@/$) synopsisHeading( "@|bold,underline Usage|@: " ) descriptionHeading( "%n@|bold,underline Description heading|@:%n" ) description( "Description 1" , "Description 2" ) // after the synopsis optionListHeading( "%n@|bold,underline Options heading|@:%n" ) footerHeading( "%n@|bold,underline Footer heading|@:%n" ) footer($/@|bold,blue \ ___ ___ ___ / __|_ _ ___ _____ ___ _ |_ ) | __| | (_ | '_/ _ \/ _ \ V / || | / / _|__ \ \___|_| \___/\___/\_/ \_, | /___(_)___/ |__/ |@/$) } cli.a( 'option a description' ) cli.b( 'option b description' ) cli.c(type: List, 'option c description' ) cli.usage() |
Код выше дает следующий вывод:
(Благодарим http://patorjk.com/software/taag/ за искусство ASCII.)
Новое свойство errorWriter
Когда пользователь предоставил неверный ввод, версия CliBuilder для picocli записывает сообщение об ошибке и сообщение помощи по использованию в новое свойство errorWriter
(по умолчанию установлено значение System.err
). Когда пользователь запрашивает помощь, а приложение вызывает CliBuilder.usage()
, сообщение об использовании использования CliBuilder.usage()
по умолчанию System.out
).
Предыдущие версии CliBuilder использовали свойство writer
как для неверного ввода, так и для запрашиваемой пользователем справки.
Почему это изменение? Это помогает авторам приложений командной строки следовать стандартной практике и отделять выходные данные диагностики от выходных данных программы. Если выходные данные программы Groovy передаются по конвейеру в другую программу, отправка сообщений об ошибках в STDERR предотвращает непреднамеренную попытку исходящей программы проанализировать выходные данные ошибок. С другой стороны, когда пользователи запрашивают помощь с --help
или --version
, вывод должен быть отправлен в STDOUT, потому что пользователь может захотеть передать вывод в утилиту, такую как less
или grep
.
Для обратной совместимости установка свойства writer
в другое значение также установит errorWriter
в то же значение. (Вы все равно можете установить errorWriter
на другое значение, если errorWriter
.)
Вывод
Groovy 2.5 CliBuilder предлагает множество новых интересных функций. Попробуйте и дайте нам знать, что вы думаете!
Это вторая часть статьи из двух частей. Если вы пропустили это, вот часть 1 .
Для получения дополнительной информации посетите сайт Groovy и проект GitHub, а также сайт picocli и проект GitHub picocli . Пожалуйста, отметьте проекты, если вам нравится то, что вы видите!
Смотреть оригинальную статью здесь: Groovy 2.5 CliBuilder Renewal (часть 2)
Мнения, высказанные участниками Java Code Geeks, являются их собственными. |