Интерфейс командной строки (CLI) — это отдельный тип приложений, которые выполняются исключительно в терминале командной строки.
Как правило, такие программы используются для управления различными рабочими инструментами, связанными с разработкой и поддержкой сетевой инфраструктуры.
Алгоритм взаимодействия прост:
- Пользователь вводит в терминал название CLI-приложения, имя команды, параметры и иногда дополнительные флаги
- CLI-приложение выполняет запрошенное пользователем действие и выдает текстовый ответ обратно в терминал
CLI-приложения выглядят устаревшими из-за отсутствия какого либо графического интерфейса (GUI), однако по-прежнему считаются наиболее универсальным, быстрым и удобным способом системного администрирования.
Для создания CLI в Golang есть специальный пакет Cobra, созданный сторонними разработчикам. Он построен на основе пакета flag (парсер флагов командной строки) из стандартной библиотеки языка и предоставляет более высокий уровень абстракций.
VDS и VPS
биллингом по всему миру: Россия, Азия и Европа.
Подробнее о пакете Cobra
Cobra — это полноценная CLI-платформа для языка Go, в состав которой входит два базовых компонента:
- Библиотека для создания современных CLI-приложений
- CLI-инструмент для быстрого создания приложений на основе стандартных (для Cobra) файлов-обработчиков команд
Кстати, Cobra был разработан одним из членов команды Go, Стивом Франсом (spf13), изначально для проекта Hugo — специального фреймворка для создания веб-сайтов. Спустя время Cobra стала одним из самых популярных пакетов Golang.
Возможности Cobra
Cobra предоставляет ряд довольно простых функций для создания современных интерфейсов командной строки. Помимо этого в Cobra есть высокоуровневый контроллер, помогающий организовать код разрабатываемого CLI-приложения.
Cobra реализует:
- Иерархию обработки команд
- Мощный анализ аргументов и флагов
- Иерархию флагов (глобальные и локальные)
- Проверку подкоманд
- Совместимость со стандартом POSIX
- Автоматическое создание справки для команд и флагов
Кстати, такие крупные проекты, как Kubernetes, Hugo или CockroachDB имеют кодовую базу на Golang и для обработки команд используют именно пакет Cobra.
CLI-команды имеют довольно стандартную схему:
Например, команды в реальных проектах могут выглядеть как-то так:
Или так:
Архитектура Cobra
Рабочие сущности можно поделить на три типа — все они так или иначе репрезентируют структуру команд в консольном терминале:
- Команды (Commands). Указывают на конкретные действия, которые необходимо выполнить. Впрочем, как в и любом классическом CLI-приложении.
- Аргументы (Args). Это некоторые вещи или сущности, которые передаются в команду, после чего она работает с ними и возвращает результат.
- Флаги (Flags). Короткие модификаторы команд (то есть конкретных действий), которые вносят определенные корректировки в выполнение работ и влияют на конечный результат работы CLI-приложения.
Немного о POSIX-совместимости
В стандарте POSIX есть соглашение о паттерне (схеме) организации аргументов и флагов, которому должны следовать CLI-приложения.
Это тот самый классический формат, с которым знакомо большинство разработчиков — многочисленные служебные программы Linux (например, «ls», «cp», «useradd») и сторонние приложения следуют именно ему.
Важно помнить, что схема команд четко формализована в стандарте и представляет собой следующий вид:
У каждого приложения может быть несколько версий одной и той же опции — длинная и короткая. При этом есть четкое правило, что короткая версия должна состоять только из одного символа.
1. Настройка окружения
Проверка Go
На всякий случай проверьте наличие компилятора Golang в вашей системе. Это можно сделать с помощью команды запроса версии:
Если Golang действительно установлен, то в консоли появится версия Go и короткое название операционной системы.
Создание директории проекта
Далее мы создадим отдельный каталог под наш Cobra-проект:
После этого перейдем в него:
Golang имеет свои особенности в работе его модульной системы, необходимой для подключения пакетов. Поэтому предварительно директорию с проектом необходимо проинициализировать с помощью специальной команды:
После этого каталог превратится в полноценный модуль Go — в консоли появится соответствующее сообщение о создании модуля с именем CobraProject.
2. Подключение пакета Cobra
Загрузка пакета из официального репозитория
Начиная с версии Go 1.18 в Golang существует специальная команда go install, автоматически выполняющая установку удаленных модулей.
Поэтому мы воспользуемся именно ей, загрузив пакет Cobra из официального репозитория на github:
Обратите внимание, что в конце есть указатель latest — мы устанавливаем самый последний релиз.
Инициализация CLI
В терминале нам станет доступен исполняемый файл cobra-cli. С помощью него мы инициализируем проект Cobra в нашем рабочей каталоге — к этому моменту вы должны находиться уже в нем:
После этого в рабочем каталоге появятся файлы, содержащие некий стандартный код пакета Cobra с названием проекта — CobraProject.
Структура файлов будет иметь следующий вид:
Файл main.go является входной точкой (entry point) в CLI-приложение. Его стандартное содержимое примерно такое:
Все команды размещаются в виде отдельных файлов в каталоге /cmd. При этом файл root.go является корневым обработчиком команд — по сути это базовая команда любого консольного интерфейса.
Например, рассмотрим следующую команду:
Здесь go является корневой командой, которая обрабатывается root.go, get — дочерняя команда, обработчик которой размещен в отличном от root.go файле.
Сборка CLI
Для сборки CLI-приложения используется та же самая команда, что и для создания обычного двоичного файла проекта Go:
Стандартно исполняемый файл появится в рабочем каталоге проекта.
Чтобы использовать собранное CLI-приложение, его также необходимо установить:
После этого CLI-приложение станет доступно для вызова из терминала командной строки. Чтобы воспользоваться им достаточно написать в консоль название проекта:
Если все работает корректно, то в консоле появится стандартный вывод для команды без параметров. Разумеется, в дальнейшем стандартный вывод можно будет изменять — это делается в файле root.go.
3. Создание функции для команды
Каждая введенная в консоль команда вызывает соответствующую функцию Go, которая выполняет логику этой команды. При этом любые параметры и флаги, указанные в консоли, передаются в функцию.
В качестве простого примера мы реализуем небольшую функцию, которая отсчитывает время в текущем часовом поясе. Для этого мы задействуем пакет time.
После инициализации CLI в рабочем каталоге должна была появиться директория cmd. Перейдем в нее:
Теперь создадим файл, который будет содержать нашу функцию:
Код внутри такой:
Как можно видеть, функция возвращает два значения — результат и данные о возможной ошибке.
4. Добавление команды в CLI
Теперь, когда функциональная часть нашего приложения готова, мы можем «зарегистрировать» команду в CLI-приложении для доступа извне.
Для этого существует отдельная команда add:
После этого в папке cmd появится файл timefromzone.go со стандартным кодом внутри.
Кстати, в этой же папке у вас уже расположен файл root.go отвечающий за «корневую» обработку команды — то есть команды без каких-либо параметров.
Несложно догадаться, что «обработчики» консольных команд формируются в файловой системе операционной системы в виде отдельных go-исходников.
Давайте откроем новый файл и наполним его следующим кодом:
Разберемся, что означает каждое поле:
Use. Название, под которым будет доступна команда из терминалаShort. Краткое описание команды, которое будет доступно пользователю из консолиLong. Полное описание команды, которое будет доступно пользователю из консолиArgs. Точное количество аргументов, необходимое для работы командыRun. Функция-обработчик, внутри которой мы вызываем и обрабатываем ранее созданную функциюgetTimeFromZone.
На самом деле в некоторых случаях вы могли бы упростить кодовую базу, написав нужную логику прямо внутри функции-обработчика команды:
Все! Команда добавлена. Остается только заново переустановить наше CLI-приложение:
Теперь мы можем обратиться к нашему приложению через консоль, указав название команды и передав в качестве аргумента кодовое имя часового пояса:
Консольный вывод будет примерно таким:
Кстати, полный список существующих часовых поясов и их кодовые названия можно посмотреть на соответствующей странице в Википедии.
5. Добавление флагов в CLI
Как правило, при выполнении консольных помимо параметров можно также указывать флаги.
Флаги — это опции, которые вносят некоторые изменения в поведение конкретных команд. Флаг легко определить по предшествующему ему дефису (или двух).
Наличие флагов в CLI-приложении добавляет вариативность и гибкость в поведение команд. Без флагов пришлось бы создавать множество сложных функций с большим количеством повторяющегося кода.
В этом смысле флаги позволяют унифицировать консольное приложение. При этом в Cobra флаги можно поделить на два условных типа:
- Локальные. Действуют только в рамках конкретной команды.
- Постоянные. Могут применяться сразу ко всем командам и их подкомандам.
Давайте перейдем в ранее созданный файл timefromzone.go и изменим в конце функцию инициализации, добавив обработку флагов:
Теперь мы можем воспользоваться флагом в функции Run определенной команды. В этом случае полный код файла timefromzone.go окажется таким:
Повторно переустановим наше CLI-приложение:
И выполним созданную команду, но уже с флагом:
Теперь за счет флага команда «видит» явно указанный формат даты (ГГГГ-ММ-ДД) и выводит следующий результат:
Подготовили для вас выгодные тарифы на облачные серверы
477 ₽/мес
657 ₽/мес
Заключение
Пакет Cobra для языка программирования Golang — отличное решение, помогающее абстрагироваться от сложных низкоуровневых функций парсинга командной строки, которые предоставляет стандартная библиотека.
Можно сказать, Cobra — своего рода фреймворк для CLI-приложений, который снимает с разработчика «головную боль» при работе с консольным терминалом и фокусирует ресурсы преимущественно на бизнес-логике.
Каждая команда представляет собой отдельный файл в директории /cmd, который можно параметризировать с помощью флагов.
Это удобно, ведь можно в явном виде выстраивать иерархию команд и контролировать процесс их обработки за счет редактирования hook-функций, вроде init или run.
Благодаря такой особенности Cobra CLI-приложение приобретает более структурный вид и имеет меньше беспорядка, формируя определенный фреймворк.
Помните, что Cobra создана сторонними разработчиками, поэтому размещена в отдельном репозитории на GitHub и не является частью стандартной библиотеки Golang.
Также на официальном сайте Cobra можно найти инструкции по установке и использованию парсера командной строки.
