golang-pflag-cobra/

В этой небольшой заметке мы поговорим о том, как парсить флаги и аргументы командной строки в языке Go . Казалось бы, в стандартной библиотеке есть пакет flag — берешь и используешь. Но он плох тем, что заставляет пользователя указывать флаги в стиле -config , вместо всем привычных -c и --config . То есть, когда два знака минус используются для полного имени флага, и один знак для короткого. Кроме того, pflag не помогает обрабатывать сложные команды вроде тех, что использует утилита kubectl get nodes , describe pods , и так далее.

Поэтому вместо стандартного flag многие используют spf13/pflag :

package main

import (
log «github.com/sirupsen/logrus»
«github.com/spf13/pflag»
)

func main () {
var showHelp bool
var configPath string
pflag . StringVarP ( &configPath , «config» , «c» , «» ,
«Config file path» )
pflag . BoolVarP ( & showHelp , «help» , «h» , false ,
«Show help message» )
pflag . Parse ()
if showHelp {
pflag . Usage ()
return
}

log . Infof ( «configPath == %s» , configPath )
}

Библиотека предельно проста в использовании, поэтому не будем подробно на ней останавливаться. Стоит только отметить, что в ней нет понятия «обязательного аргумента». Дело в том, что библиотека работает с флагами, а все флаги по определению опциональны. Зато в spf13/pflag есть проверка множества разных форматов . Например, можно убедиться, что пользователь указал правильный IP-адрес, и всякое в таком духе.

Аргументы часто парсятся с помощью spf13/cobra . Cobra позиционируется как фреймворк для написания CLI с интерфейсом в стиле kubectl get pods . Пример использования:

package main

import (
log «github.com/sirupsen/logrus»
«github.com/spf13/cobra»
)

func main () {
var configPath string

rootCmd := cobra . Command {
Use : «rest-service-example» ,
Version : «v1.0» ,
Run : func ( cmd * cobra . Command , args [] string ) {
log . Infof ( «configPath == %s» , configPath )
},
}

rootCmd . Flags () . StringVarP ( & configPath , «config» , «c» , «» ,
«Config file path» )
err := rootCmd . MarkFlagRequired ( «config» )
if err != nil {
panic ( «rootCmd.MarkFlagRequired() failed» )
}

err = rootCmd . Execute ()
if err != nil {
// Required arguments are missing, etc
return
}
}

Заметьте, что флаг --config теперь стал обязательным.

Больше примеров вы найдете в документации . Например, из нее вы узнаете, как сделать поддержку нескольких команд в одной утилите и построить из этих команд иерархию. А еще, что cobra имеет безумный функционал типа генерации автокомплишена для Bash и Zsh .

Интересно, что kubectl реально написан с использованием данных библиотек.

А чем вы парсите флаги и аргументы в Go?

Дополнение: Парсинг конфигов в Go с помощью Viper

EnglishRussianUkrainian