Парсим командную строку с Groovy CliBuilder

В этой заметке хочу снова затронуть тему Groovy. Эта заметка будет ярким дополнением к уже написанным ранее: о ресурсах, на которых можно найти много интересного про Groovy.

terminal md

Итак, начнем с постановки задачи! Приходилось ли вам когда-нибудь писать свои библиотеки? А какие-нибудь утилиты, которые нужно запускать из командной строки?

Вот мне приходилось! В частности JBehave reporter работает именно через командную строку. Теперь давайте подумаем, каким образом можно передавать параметры в наш jar файл, используя командную строку? Правильно - через аргументы командной строки, задавая VM options либо Program arguments. И вот если с VM options все более-менее понятно, то с вариантом аргументов приходится повозиться. Именно этот случай и рассмотрим.

Итак, давайте зададимся начальными условиями: чего хотим? Хотим передавать параметры в jar файл в любой последовательности и не переживать, что у нас что-то пойдет не так.

Будем смотреть на примере репортера. Раньше он запускался так:

java -jar reporter.jar D:\\jbehave D:\\report

На этом примере наглядно видно, что если поменять параметры местами, то все сломается; да и вообще человеку, который не писал эту штуку, будет непонятно, с какими аргументами ее запустить.

Чтобы исправить эти неудобства, я использовал библиотеку, которая называется Groovy CliBuilder. С ее помощью можно легко парсить аргументы командной строки.

В результате применения этой библиотеки у нас должно получиться такое вот:

java -jar reporter.jar -g D:\\jbehave -d D:\\report

Казалось бы, добавилось всего две буквы, но на самом деле изменилось многое. Харош говорить - смотрим в код.

private static parse(String[] args) {
        def cli = new CliBuilder(usage: 'reporter [options]')

        cli.with {
            h longOpt: 'help', 'Show usage information'
            g longOpt: 'generate report', required: true, args: 1, 'Generate report based on files from folder'
            d longOpt: 'report folder', args: 1, 'Generated report path'
        }

        def options = cli.parse(args)

        // print usage if -h, --help, or no argument is given
        if (!options || options.h) {
            cli.usage()
            System.exit(1);
        }

        options
    }

Этот кусок кода анализирует наш массив входных параметров и возвращает так называемые опции. На самом деле опции - не что иное, как Map ;). Но самая приятная вещь этой штуки скрывается вот в чем: если мы не передадим никаких параметров или передадим их неправильно, то вместо ужасного стектрейса у нас выведется такое вот сообщение:

image::/images/ter.png

Обратите внимание на понятность сообщения. Любой, прочитав его, сможет понять, какие параметры доступны и за что они отвечают.

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

def folderPath = options.d
def sourceFiles = options.g

Теперь вы можете не переживать за порядок передачи аргументов через командную строку.

P.S. Для чистой Java есть реализация подобной библиотеки, называется она Apache Commons Cli. На этом все. До новых заметок.