Парсинг флагов и аргументов в языке Go
27 ноября 2019
В этой небольшой заметке мы поговорим о том, как парсить флаги и аргументы командной строки в языке Go. Казалось бы, в стандартной библиотеке есть пакет flag — берешь и используешь. Но он плох тем, что заставляет пользователя указывать флаги в стиле -config
, вместо всем привычных -c
и --config
. То есть, когда два знака минус используются для полного имени флага, и один знак для короткого. Кроме того, pflag не помогает обрабатывать сложные команды вроде тех, что использует утилита kubectl — get nodes
, describe pods
, и так далее.
Поэтому вместо стандартного flag многие используют spf13/pflag:
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
. Пример использования:
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
Метки: Go.
Вы можете прислать свой комментарий мне на почту, или воспользоваться комментариями в Telegram-группе.