Данный пакет облегчает создание консольных приложений на Oscript
Command Line Interface для OScriptКороткое название библиотеки cli
Данная библиотека для языка OScript, позволяет создавать консольные приложения с разбором и проверкой аргументов.
Документация и описание публичного API
#Использовать cli
Перем Лог;
///////////////////////////////////////////////////////////////////////////////
Процедура ВыполнитьПриложение()
    Приложение = Новый КонсольноеПриложение(ПараметрыПриложения.ИмяПриложения(), "Помощник генерации приложения на основании шаблона cli");
    Приложение.Версия("v version", ПараметрыПриложения.Версия());
    Приложение.УстановитьОсновноеДействие(ЭтотОбъект)
    Приложение.Запустить(АргументыКоманднойСтроки);
КонецПроцедуры // ВыполнениеКоманды()
Процедура ВыполнитьКоманду(Знач Команда) Экспорт
    Сообщить("Полезная работа");
КонецПроцедуры
///////////////////////////////////////////////////////
Попытка
    ВыполнитьПриложение();
Исключение
    Сообщить(ОписаниеОшибки());
КонецПопытки;
#Использовать cli
///////////////////////////////////////////////////////////////////////////////
Процедура ВыполнитьПриложение()
    Приложение = Новый КонсольноеПриложение("cli", "Помощник генерации приложения на основании шаблона cli", ЭтотОбъект);
    Приложение.Версия("v version","1.0.0");
    Приложение.ДобавитьКоманду("i init", "Инициализация структуры нового приложения", Новый КомандаInit);
    Приложение.ДобавитьКоманду("g generate", "Генерация элементов структуры приложения", Новый КомандаGenerate);
    Приложение.Запустить(АргументыКоманднойСтроки);
КонецПроцедуры // ВыполнениеКоманды()
Процедура ВыполнитьКоманду(Знач КомандаПриложения) Экспорт
    КомандаПриложения.ВывестиСправку();
КонецПроцедуры
///////////////////////////////////////////////////////
Попытка
    ВыполнитьПриложение();
Исключение
    Сообщить(ОписаниеОшибки());
КонецПопытки;
#Использовать cli
///////////////////////////////////////////////////////////////////////////////
Процедура ВыполнитьПриложение()
    Приложение = Новый КонсольноеПриложение("cli", "Помощник генерации приложения на основании шаблона cli");
    Приложение.Версия("v version","1.0.0");
    Приложение.ДобавитьКоманду("i init", "Инициализация структуры нового приложения", Новый КомандаInit);
    Приложение.ДобавитьКоманду("g generate", "Генерация элементов структуры приложения", Новый КомандаGenerate);
    Приложение.Запустить(АргументыКоманднойСтроки);
КонецПроцедуры // ВыполнениеКоманды()
///////////////////////////////////////////////////////
Попытка
    ВыполнитьПриложение();
Исключение
    Сообщить(ОписаниеОшибки());
КонецПопытки;
Класс КомандаGenerate
Для добавления подкоманды в любую команду используются методы ДобавитьПодкоманду или ДобавитьКоманду
Процедура ОписаниеКоманды(Команда) Экспорт
    // Метод <ДобавитьПодкоманду>
    Команда.ДобавитьПодкоманду("c command", "Генерация дополнительной вложенной команды", Новый КомандаGenerateCommand);
    
    // Метод <ДобавитьКоманду>
    Команда.ДобавитьКоманду("o option", "Генерация опции для команды", Новый КомандаGeneratOption);
Процедура ВыполнитьКоманду(Знач Команда) Экспорт
КонецПроцедуры
Для PR в cmdline слишком большие изменения в API, т.е. обеспечить совместимость очень трудоемко. Сравнительная таблица возможностей:
| cli | cmdline | |
|---|---|---|
| Встроенная команда help | ✓ | ✓ | 
| Автоматическая генерация справки по приложению и командам | ✓ | ✓ | 
| Встроенная команда version | ✓ | ✓ | 
| Команды | ✓ | ✓ | 
| Подкоманды | ✓ | |
| Совмещение булевых (флаговых) опций -xyz | ✓ | |
| Совмещение опции и значения -fValue | ✓ | |
| Взаимоисключающие опции: --start ❘ --stop | ✓ | |
| Необязательные опции : [-a -b]or[-a [-b]] | ✓ | |
| Проверка аргументов : FILE PATH | ✓ | |
| Необязательные аргументы : SRC [DST] | ✓ | |
| Повторение аргументов : SRC... DST | ✓ | |
| Зависимость опций и аргументов друг от друга : SRC [-f DST] | ✓ | |
| Формирование своей строки выполнения: [-d ❘ --rm] FILE [КОМАНДА [АРГУМЕНТЫ...]] | ✓ | 
Для установки необходимо:
$ opm install -f <ПутьКФайлу>
Либо, скачать библиотеку с помощью opm:
opm install cli
При создании приложения необходимо указать имя приложения и описание:
Приложение = Новый КонсольноеПриложение("cli", "Помощник генерации приложения на основании шаблона cli");
Каждый возможный вариант выполнения - это "Команда". Команды могут создаваться явно, кроме того, само Приложение содержит в себе корневую (Основную) команду.
Каждая команда реализуется в виде отдельного класса. Каждый такой класс обязан иметь экспортную процедуру
Процедура ВыполнитьКоманду(Знач Команда) Экспорт
КонецПроцедуры
Для установки основной функции выполнения приложения в приложении надо установить основное действие. В простейшем случае основным действием может выступать сам стартовый сценарий:
Передать данный класс через процедуру:
Приложение.УстановитьОсновноеДействие(ЭтотОбъект)
Для добавления отображения версии через опции: -v, --version надо добавить строчку:
Приложение.Версия("v version", "1.2.3");
Это позволит запускать приложение с ключом v или --version:
my-app --version
Для запуска приложения необходимо добавить строчку:
Приложение.Запустить(АргументыКоманднойСтроки);
Этот вызов является "точкой входа" в консольное приложение. В общем случае, после него уже не идет никакого дополнительного кода. Парсер анализирует аргументы и запускает команды автоматически.
Все параметры разделяются на два типа:
В общем случае, Опции имеют имена, аргументы являются позиционными. Кроме того, по умолчанию указание опций необязательно, а аргументов - обязательно. Это можно переопределить, но дефолтное поведение именно такое. Аргумент - обязателен, опция - нет.
Опция может быть следующих простых типов:
Также опция может принимать массивы данных типов, например:
Для простых типов поддерживается определение типа по значение по умолчанию. Пример,
Отладка = Команда.Опция("f force", ,"Описание опция")
    .ТБулево() // тип опции Булево
    ;
// Можно заменить на вызов
Отладка = Команда.Опция("f force", Ложь ,"Описание опция");
Пример булево опции:
Отладка = Команда.Опция("v debug", ложь ,"Описание опции")
    .Флаговый() // тип опции булево
    .ВОкружении("ИМЯ_ПЕРЕМЕННОЙ")
    .ПоУмолчанию(Ложь)
    .СкрытьВСправке(); // Любой тип
ВОкружении Возможна передача нескольких переменных окружения разделенных через пробел
Пример перечисления опции:
ЦветКонсоли = Команда.Опция("c color", "green" ,"Описание опции")
    .ТПеречисление() // тип опции перечисление
    .Перечисление("green", Новый ЗеленыйЦвет(), "Консоль будет зеленого цвета")
    .Перечисление("red", Цвета.Красный, "Консоль будет красного цвета")
    .Перечисление("Случайный", СлучайныйЦвет(), "Консоль будет случайного цвета")
    ;
Перечисление ограничивает пользователя в выборе значения опции, при этом разработчик для каждой опции может задавать свой тип значения
Подробное описание возможностей параметров команд и приложения
-f : одно тире для коротких имен-f=false : одно тире для коротких имен и значение булево (true/false)--force : двойное тире для длинных имен-it : группировка булевых опций, будет эквивалентно: -i -t-e=value : одно тире для коротких имен, через равно значение опции-e value : одно тире для коротких имен, через пробел значение опции-Ivalue : одно тире для коротких имен, и сразу значение опции--extra=value : двойное тире для длинных имен, через равно значение опции--extra value : двойное тире для длинных имен, через пробел значение опцииповторение опции создаст массив данных указанного типа опций:
-e PATH:/bin -e PATH:/usr/bin : Массив, содержащий ["/bin", "/usr/bin"]-ePATH:/bin -ePATH:/usr/bin : Массив, содержащий ["/bin", "/usr/bin"]-e=PATH:/bin -e=PATH:/usr/bin : Массив, содержащий ["/bin", "/usr/bin"]--env PATH:/bin --env PATH:/usr/bin : Массив, содержащий ["/bin", "/usr/bin"]--env=PATH:/bin --env=PATH:/usr/bin : Массив, содержащий ["/bin", "/usr/bin"]Аргументы могут быть следующих простых типов:
Для простых типов поддерживается определение типа по значение по умолчанию. Пример,
Отладка = Команда.Аргумент("PATH", "" ,"Описание аргумента")
    .ТСтрока() // тип опции Строка
    ;
// Можно заменить на вызов
Отладка = Команда.Аргумент("PATH", "" ,"Описание аргумента");
Также аргументы могут принимать массивы данных типов, например:
Пример Строки аргумента:
Отладка = Команда.Аргумент("PATH", "" ,"Описание аргумента")
    .ТСтрока() // тип опции Строка
    .ВОкружении("ИМЯ_ПЕРЕМЕННОЙ")
    .ПоУмолчанию(Ложь)
    .СкрытьВСправке(); // Любой тип
ВОкружении Возможна передача нескольких переменных окружения разделенных через пробел
Подробное описание возможностей параметров команд и приложения
Оператор -- устанавливает метку завершению любых опций.
Все, что следует за данным оператором, будет считаться аргументом, даже если начинается с тире
Для примера, если команда "ХочуФайл" принимает в качестве аргумента имя файла, но начинающегося с -, тогда строка запуска данной программы будет выглядеть так:
ИмяФайла = Команда.Аргумент("FILE", "", "имя файла для создания")
Допустим, нужное нам имя файла равно -f, тогда если выполнить нашу команду:
ХочуФайл -f
то будет выдана ошибка, т.к. -f распознано как опция, а не аргумент.
Для того, чтобы решить данную проблему, необходимо объявить окончание опций через оператор --
ХочуФайл -- -f
Тогда определение аргументов будет работать корректно.
cli поддерживает создание команд и подкоманд. Неограниченное количество вложенных подкоманд. А также установки синонимов для команд и подкоманд.
Приложение = Новый КонсольноеПриложение("testapp", "Выполняет полезную работу");
КомандаAve = Приложение.ДобавитьКоманду("a ave", "Команда ave", КлассРеализацииПодкоманды);
cli поддерживает указание псевдонимов команд. Для примера:
КомандаAve = Приложение.ДобавитьКоманду("start run r", "Команда start", КлассРеализацииПодкоманды);
Псевдонимы для команды будут start, run, иr - можно использовать любой из них.
cli поддерживает автоматическую инициализацию параметров команд. Переданный класс должен реализовывать процедуру:
Процедура ОписаниеКоманды(Команда) Экспорт
    Путь = Команда.Аргумент("PATH", "" ,"Описание аргумента")
        .ТСтрока() / тип опции Строка
        .ВОкружении("ИМЯ_ПЕРЕМЕННОЙ")
        .ПоУмолчанию(Ложь)
        .СкрытьВСправке(); // Любой тип
    Отладка = Команда.Опция("o opt", Ложь ,"Описание опции")
        .ТСтрока() / тип опции Строка
        .ВОкружении("ИМЯ_ПЕРЕМЕННОЙ")
        .ПоУмолчанию(Ложь)
        .СкрытьВСправке(); // Любой тип
КонецПроцедуры
Синтаксис спек базируется на POSIX. Спек является грамматикой парсера аргументов и определяет порядок следования аргументов и опций в командной строке, а также вариативность параметров. Спек формируется либо вручную через указание в поле Спек, либо автоматически в момент вызова выполнения приложения / или команды.
Для определения опций можно использовать длинные и короткие имена опций:
Команда.Спек = "-f";
И/или:
Команда.Спек = "--force";
Пример добавления аргументов в команду:
Команд.Опция("f force", ...);
Правила наименования аргументов, имя должно содержать только символы в верхнем регистре:
Пример, использования аргументов в определении строки использования приложения
Команда.Спек="SRC DST"
Пример добавления аргументов в команду:
Команда.Аргумент("SRC", ...);
Команда.Аргумент("DST", ...);
cli позволяет произвольно настраивать порядок использования опций и аргументов:
Команда.Спек = "-f -g NAME -h PATH";
В примере выше задана грамматика: в командой строке могут идти сначала опции -f и -g, затем аргумент NAME, затем опция -h, затем аргумент PATH.
Для того, чтобы сделать аргументы или опции необязательными, их необходимо заключить в [...]:
Команда.Спек = "[-x]";
Для отражения выбора между несколькими опциями или аргументами используется символ |:
Команда.Спек = "--server | --agent";
Команда.Спек = "-H | -L | -P";
Команда.Спек = "-f | PATH";
Для повторения аргументов или опций необходимо использовать оператор ...:
Команда.Спек = "PATH...";
Команда.Спек = "-f...";
Возможна логическая группировка опций и аргументов. Данную группировку стоит использовать и комбинировать с такими символами как | и ...:
Команда.Спек = "(-e КОМАНДА)... | (-x|-y)";
Приведенный пример настраивает строку использования следующим образом:
Все короткие опции (типа булево) можно группировать в любом порядке вместе:
Команда.Спек = "-abcd";
Для определение любой опции приложения:
Команда.Спек = "[OPTIONS]";
Для примера, для команды с опциями a, b, c и d, указание [OPTIONS] или [ОПЦИИ] будет аналогично указанию:
Команда.Спек = "[-a | -b | -c | -d]...";
Можно задавать в строке использования =<очень хороший текст> аннотации после указания опции в длинной или короткой форме, для того чтобы определить дополнительное описание или значение по умолчанию.
Для примера:
Команда.Спек = "[ -a=<абсолютный путь к файлу> | --timeout=<в секундах> ] ARG";
Данные аннотации игнорируются парсером, и не влияют на работу приложения
Оператор -- устанавливает метку завершению любых опций.
Все что следует за данным оператором считается аргументами.
Более, сложный пример:
Приложение.Спек = "work -lp [-- CMD [ARG...]]";
Используется упрощенная (EBNF grammar) грамматика при создании строки использования:
| Описание символа | Символ и использование | Проверка | 
|---|---|---|
| Короткая опция | '-' | [A-Za-z] | 
| Длинная опция | '--' | [A-Za-z][A-Za-z0-9]* | 
| Соединенные опции | '-' | [A-Za-z]+ | 
| Все опции | '[OPTIONS]' или [ОПЦИИ] | |
| Логическая группа | '(' любые другие символы ')' | |
| Необязательная | '[' любые другие символы ']' | |
| Повтор аргумента | '...' | |
| Конец повтора аргументов | '--' | 
Можно комбинировать в указанные символы как хочется, для того чтобы добиться любых необходимых проверок опций и аргументов.
По умолчанию, если не установлена разработчиком иная, cli автоматически создает для приложения и каждой команды строки использования, используя следующую логику:
[OPTIONS] или [ОПЦИИ] к текущей строке использованияДля примера, при добавлении в команду следующих опций и аргументов:
ИнициализацияГит = Команда.Опция("g git-init", Ложь, "инициализировать создание git репозитория").Флаговый();
ИнтерактивныйРежим = Команда.Опция("interactive", Ложь, "интерактивный режим ввода информации о приложении").Флаговый();
ИспользоватьПодкоманды = Команда.Опция("s support-subcommads", Ложь, "шаблон с поддержкой подкоманд").Флаговый();
ФайлКонфига = Команда.Опция("c config-file", "", "файл настроек генерации приложения");
НаименованиеПриложения = Команда.Аргумент("NAME", "", "наименование приложения");
ПутьКПапкеГенерации = Команда.Аргумент("PATH", "", "Путь к папке для генерации нового приложения");
Будет автоматически создана следующая строка использования данной команды:
[OPTIONS] NAME PATH
Доработка проводится по git-flow. Жду ваших PR.
Смотри файл LICENSE.