В этом руководстве мы обсудим, как написать справочное сообщение с помощью пакета Cobra.
›Кратко о Cobra
Cobra - мощный пакет командной строки для Golang. Полный список проектов, использующих Cobra, находится здесь.
> Прежде чем вы начнете
Установите Cobra на свой компьютер:
go get -u -v github.com/spf13/cobra
Тем не менее, вам не нужно создавать файлы нашего приложения. Есть генератор, с помощью которого очень легко создать рабочий каталог.
Для установки генератора используйте эту команду:
go get -u -v github.com/spf13/cobra/cobra
Прежде чем мы начнем писать код, давайте рассмотрим справочное сообщение, которое мы собираемся создать с помощью пакета Cobra.
›Написание справочного сообщения
Справочное сообщение (или сообщение об использовании, или документ) - это то, что видят пользователи, когда
- вызвать программу,
- введите флаг, например
--h
или-h
, - введите недопустимые аргументы.
Это сообщение включает в себя название программы, ее использование и параметры. Если вы используете командную строку, вы уже знакомы со справочными сообщениями или сообщениями об использовании. В Linux обычно можно набрать program --help
, чтобы получить список допустимых аргументов программы.
В этом руководстве мы пишем справочное сообщение для программы, которая выводит:
- список случайных чисел указанного количества и диапазона, или
- список случайных букв определенного количества и языка.
Это наше сообщение об использовании:
Давайте проанализируем команду, числа из предыдущего сообщения:
randx numbers --count <count> [--range <range>...]
randx
- название программы,numbers
- команда,--count
- вариант команды,<count>
- значение опции - количество,[--range <range>…]
- необязательный параметр, для которого требуется значение или несколько значений,[--verbose]
- необязательный флаг.
У нас есть две команды, numbers
и letters
(bool), для включения режима цифр или букв соответственно. Если один из них true, другой - false.
Параметр — count
(int) требуется для команд numbers
иletters
. Программа выводит список цифр или букв указанного количества.
$ randx numbers --count 1
$ randx letters --count 1
Чтобы объявить необязательный аргумент --range
([] строка), мы используем квадратные скобки. Три точки в квадратных скобках означают, что вы можете передать в командную строку несколько аргументов. Например,
--range 1,10 --range 1,11
or
--range 1-10 --range 1-11
or
--range 1:10 --range 1:11
Эта опция устанавливает диапазон случайных чисел. Если есть два аргумента, программа выводит два списка с указанными диапазонами.
Необязательный аргумент --lang
(строка), также заключен в квадратные скобки . Параметр принимает язык. Поэтому программа выводит буквы указанного языка.
Программа должна возвращать справочное сообщение, если необходимая опция не установлена и / или аргументы недействительны. Оба параметра --range
и --lang
можно не указывать.
Кроме того, у нас есть три варианта (или просто флаги) без операндов в сообщении об использовании:
-h / --help
- вывести сообщение об использовании,--verbose
- выводить подробную информацию о том, что делает программа; флаг используется для информирования пользователя о том, что программа на самом деле делает, включая ошибки при выполнении требуемого действия. Это может быть полезно для устранения неполадок.--version
- выведите версию используемой программы.
›Создание структуры проекта
- Создайте и перейдите в каталог:
mkdir -p ~/go/src/github.com/your_username/app && cd ~/go/src/github.com/your_username/app
2. Создайте структуру проекта с помощью cobra init
:
cobra init --pkg-name ~/go/src/github.com/your_username/app
После этого у нас будет следующая структура проекта:
— — cmd — — — root.go — — LICENSE — — main.go
Файл root.go содержит rootCmd
command, который инициализирует все команды и флаги (или параметры).
›Создание команд
Чтобы добавить новую команду, просто используйте cobra add commandName
в каталоге проекта. Для нашего справочного сообщения нам нужно создать две команды numbers
и letters
:
$ cobra add numbers $ cobra add letters
После этого пакет cobra создает два файла, а именно numbers.go и letter.go в каталоге cmd. Теперь у нас есть следующая структура проекта:
— — cmd — — — root.go — — — numbers.go — — — letters.go — — LICENSE — — main.go
›Как выглядит main.go
В файле main.go мы выполняем наши команды с cmd.Execute()
. Полный код выглядит так:
package main import “github.com/your_user_name/app/cmd” func main() { cmd.Execute() }
Здесь нет необходимости добавлять дополнительный код. Давайте создадим подкоманды и параметры в файлах numbers.go и letter.go.
›Команда чисел
Cobra сгенерировала часть следующего кода. Мы объявили переменные countFlagNumbers
и rangeFlagNumbers
для хранения значений из --count
и --range
flags соответственно. Кроме того, мы инициализировали необходимые флаги (--count
и --range
) в функции init()
.
// beginning of numbers.go package cmd import ( "fmt" "github.com/spf13/cobra" ) var ( countFlagNumbers int rangeFlagNumbers []string ) var numbersCmd = &cobra.Command{ Use: "numbers", Short: "Returns random numbers", Run: func(cmd *cobra.Command, args []string) { fmt.Println("numbers mode") fmt.Println("--count:", countFlagNumbers) fmt.Println("--range:", rangeFlagNumbers) fmt.Println("--verbose:", verbose) }, } // here is init()
Мы вызываем метод arootCmd.AddCommand()
для инициализации команды numbers
.
//beginning of init() func init() { rootCmd.AddCommand(numbersCmd) ...
Объявление каждого флага имеет следующий шаблон:
commandName.Flags().TypeOfValuesP( where to store, long flag name, short flag name, default value, explanation, )
Объявить флаг --count
:
... numbersCmd.Flags().IntVarP( &countFlag, "count", "c", 0, "A count of random numbers", ) ...
И сделайте этот флаг обязательным:
... numbersCmd.MarkFlagRequired("count") ...
Когда мы делаем флаг обязательным, это означает, что пользователь не может выполнить программу без установленного флага. Произойдет ошибка.
Объявите флаг --range
:
... numbersCmd.Flags().StringSliceVarP( &rangeFlag, "range", "r", []string{"1:100"}, "Range of numbers. Optional", ) } // end of init() // end of numbers.go
›Письма команды
Так же, как и в numbers.go, был сгенерирован некоторый из следующего кода. Здесь мы объявили переменные countFlagLetters
и langFlagLetters
для хранения полученных значений от флагов --count
и --lang
соответственно.
// beginning of letters.go package cmd import ( “fmt” “github.com/spf13/cobra” ) var ( countFlagLetters int langFlagLetters string )
Команда lettersCmd
имеет ту же структуру, что и numbersCmd
. Все флаги инициализируются так же, как в файле numbers.go.
var lettersCmd = &cobra.Command{ Use: "letters", Short: "Returns random letters", Run: func(cmd *cobra.Command, args []string) { fmt.Println("letters mode") fmt.Println("--count:", countFlagLetters) fmt.Println("--lang:", langFlagLetters) fmt.Println("--verbose:", verbose) }, } func init() { rootCmd.AddCommand(lettersCmd) lettersCmd.Flags().IntVarP( &Count, "count", "c", 0, "A count of random letters", ) lettersCmd.MarkFlagRequired("count") lettersCmd.Flags().StringVarP( &Lang, "lang", "l", "en", "A language. Optional", ) } // end of letters.go
›Добавление флагов версии и подробного вывода
В root.go мы обновляем использование нашей программы, добавляем --version
и --verbose
flags.
package cmd import ( "fmt" "os" "github.com/spf13/cobra" )
Объявите подробную переменную. Имеет тип bool.
var ( verbose bool )
Чтобы показать версию нашей программы, добавьте параметр Version
и укажите текущую версию в кавычках.
var rootCmd = &cobra.Command{ Use: "randx", Version: "1.0.1", Short: "Returns random numbers or letters.", } func Execute() { if err := rootCmd.Execute(); err != nil { fmt.Println(err) os.Exit(1) } }
The--verbose
flag является постоянным и глобальным. Это означает, что вы можете указать программе, чтобы она показывала вам подробности выполнения программы с любой установленной командой и флагом.
func init() { rootCmd.PersistentFlags().BoolVarP( &verbose, "verbose", "v", false, "Verbose output", ) }
> Использование
В этом разделе вы можете найти несколько примеров использования Cobra в командной строке.
›› Буквенный режим
$ go run main.go letters --count 9 $ go run main.go letters -c 9 letters mode --count: 9 --lang: en // this is a default value --verbose: false $ go run main.go letters --count 9 --lang en $ go run main.go letters -c 9 -l en letters mode --count: 9 --lang: en --verbose: false
›› Режим чисел
$ go run main.go numbers --count 9 $ go run main.go numbers -c 9 numbers mode --count: 9 --range: [1:100] // this is a default value --verbose: false $ go run main.go numbers --count 10 --range 9,10 $ go run main.go numbers -c 10 -r 9,10 numbers mode --count: 10 --range: [9 10] --verbose: false $ go run main.go numbers --count 10 --range 9,10 --range 0,15 numbers: true --count: 10 --range: [9 10 0 15] --verbose: false
Несколько комментариев по поводу разделителей. Если вы используете запятую в качестве разделителя во флаге --range
, вы получите только список чисел. Как обсуждалось ранее, вы можете использовать двоеточие:
для разделения этих чисел. Например:
$ go run main.go numbers --count 10 --range 9:10 --range 10:11 numbers mode --count: 10 --range: [9:10 10:11] --verbose: false
>> Подробный
$ go run main.go numbers --count 18 --range 9,19 --verbose $ go run main.go numbers -c 18 -r 9,19 --verbose numbers mode --count: 18 --range: [9 19] --verbose: true
›Об авторе
Джейн - программист на Go и технический писатель в области разработки программного обеспечения. В течение 5 лет она писала технические материалы на английском и русском языках. Она закончила Новосибирский государственный технический университет по специальности Информационная безопасность по специальности Информационная безопасность автоматизированных систем. Вы можете подписаться на нее в Твиттере и увидеть другие ее письменные работы на publishing.enthusiastic.io.