Я не профессиональный переводчик и не профессиональный Go разработчик, если в документе есть ошибки, просьба не строиться и напрямуюредактировать. оригинал документа пожалуйстанажмитеПроверять.
о
Cobra — это CLI-фреймворк для Go. Он включает библиотеку для создания мощных современных приложений CLI и инструмент для быстрого создания приложений и командных файлов на основе Cobra.
Участник проекта Cobra by Go и автор Хьюгоspf13Создан, был принят многими популярными проектами Go, такими какGitHub CLIиDocker CLI.
характеристика
- Простые CLI на основе подкоманд:
app server
,app fetch
Ждать; - полностью совместимыйPOSIX (интерфейс переносимой операционной системы)логотип (как короткий, так и длинный)
- Вложенные подкоманды
- Флаги для глобальных, локальных и каскадных
- использовать
cobra init appname
иcobra add cmdname
Легко создавать приложения и команды - Умные советы (
app srver
...did you meanapp server
) - Справка по автоматически сгенерированным командам и флагам
- Автоматическая идентификация
-h
,--help
знак помощи - Автоматически сгенерированное автодополнение bash для вашего приложения
- Автоматически создавать справочные страницы для вашего приложения
- Псевдонимы команд, чтобы вы могли что-то менять, не нарушая их
- Гибкость для определения собственной помощи, использования и т. д.
- опционально сviperТесно интегрированный для12factorприменение
Установить
Cobra очень проста в использовании, первое использованиеgo get
команда для установки последней версии. Эта команда установитcobra
Исполняемый файл генератора и его зависимости:
$ go get -u github.com/spf13/cobra/cobra
концепция
Cobra построена на командах, аргументах и флагах.
Commandsпредставлять действие,Argsвещи,Flagsявляются модификаторами этих действий.
Лучшие приложения при использовании читаются как предложения. Пользователи будут знать, как использовать приложение, потому что они, естественно, поймут, как его использовать.
Шаблон, которому нужно следовать,APPNAME VERB NOUN --ADJECTIVE
. илиAPPNAME COMMAND ARG --FLAG
Некоторые примеры из реальной жизни могут лучше проиллюстрировать это.
В следующем примереserver
это команда,port
это флаг:
hugo server --port=1313
В этой команде мы говорим Git клонировать содержимое URL-адреса:
git clone URL --bare
Команда
Команды — это сердце приложения. Каждое взаимодействие, предоставляемое приложением, содержится в команде. Команда может иметь подкоманды и при необходимости запускать действие.
В приведенном выше примереserver
это команда.
Флаги
Флаг — это способ украшения поведения команды. Поддержка Cobra полностью соответствуетPOSIX (интерфейс переносимой операционной системы)Логотип и впередflagСумка.
Команда Cobra может определять флаги, зарезервированные для подкоманд, и флаги, доступные только для этой команды.
В приведенном выше примереport
это знак.
Функция флагаpflagПредоставляется библиотекой, которая является ответвлением стандартной библиотеки и совместима на основе сохранения того же интерфейса.POSIX (интерфейс переносимой операционной системы).
начиная
Вы можете предоставить свою собственную организационную структуру проекта, но, как правило, приложение на основе Cobra будет следовать следующей организационной структуре.
-
cmd
Папка для размещения команды
- add.go
- your.go
- commands.go
- here.go
- main.go запись приложения
В приложении Cobra обычноmain.go
Документация очень. У него одна цель: инициализировать Cobra.
package main
import (
"{pathToYourApp}/cmd"
)
func main() {
cmd.Execute()
}
Использование генератора Кобры
Cobra предоставляет интерфейс командной строки для создания вашего приложения и добавления любых команд, которые вы хотите. Это самый простой способ интегрировать Cobra в ваше приложение.
здесьПодробнее о генераторах можно прочитать .
Использование библиотеки Кобры
Чтобы вручную получить доступ к Cobra, вам необходимо создатьmain.go
документы иrootCmd
документ. Вы можете предоставить другие команды по мере необходимости.
создать rootCmd
Cobra не требует специальных конструкторов. Просто создайте свою команду.
В идеале поместите его в/cmd/root.go
середина:
// rootCmd 代表没有调用子命令时的基础命令
var rootCmd = &cobra.Command{
Use: "hugo",
Short: "Hugo is a very fast static site generator",
Long: `A Fast and Flexible Static Site Generator built with
love by spf13 and friends in Go.
Complete documentation is available at http://hugo.spf13.com`,
// 如果有相关的 action 要执行,请取消下面这行代码的注释
// Run: func(cmd *cobra.Command, args []string) { },
}
// Execute 将所有子命令添加到root命令并适当设置标志。
// 这由 main.main() 调用。它只需要对 rootCmd 调用一次。
func Execute() {
if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
Вы такжеinit()
Функция определяет флаги и обрабатывает конфигурацию. Примеры следующие:
// cmd/root.go
package cmd
import (
"fmt"
"os"
"github.com/spf13/cobra"
homedir "github.com/mitchellh/go-homedir"
"github.com/spf13/viper"
)
var cfgFile string
var projectBase string
var userLicense string
// rootCmd 代表没有调用子命令时的基础命令
var rootCmd = &cobra.Command{
Use: "hugo",
Short: "Hugo is a very fast static site generator",
Long: `A Fast and Flexible Static Site Generator built with
love by spf13 and friends in Go.
Complete documentation is available at http://hugo.spf13.com`,
// 如果有相关的 action 要执行,请取消下面这行代码的注释
// Run: func(cmd *cobra.Command, args []string) { },
}
// Execute 将所有子命令添加到root命令并适当设置标志。会被 main.main() 调用一次。
func Execute() {
if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
func init() {
cobra.OnInitialize(initConfig)
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.cobra.yaml)")
rootCmd.PersistentFlags().StringVarP(&projectBase, "projectbase", "b", "", "base project directory eg. github.com/spf13/")
rootCmd.PersistentFlags().StringP("author", "a", "YOUR NAME", "Author name for copyright attribution")
rootCmd.PersistentFlags().StringVarP(&userLicense, "license", "l", "", "Name of license for the project (can provide `licensetext` in config)")
rootCmd.PersistentFlags().Bool("viper", true, "Use Viper for configuration")
viper.BindPFlag("author", rootCmd.PersistentFlags().Lookup("author"))
viper.BindPFlag("projectbase", rootCmd.PersistentFlags().Lookup("projectbase"))
viper.BindPFlag("useViper", rootCmd.PersistentFlags().Lookup("viper"))
viper.SetDefault("author", "NAME HERE <EMAIL ADDRESS>")
viper.SetDefault("license", "apache")
}
func initConfig() {
// Don't forget to read config either from cfgFile or from home directory!
if cfgFile != "" {
// Use config file from the flag.
viper.SetConfigFile(cfgFile)
} else {
// Find home directory.
home, err := homedir.Dir()
if err != nil {
fmt.Println(err)
os.Exit(1)
}
// Search config in home directory with name ".cobra" (without extension).
viper.AddConfigPath(home)
viper.SetConfigName(".cobra")
}
if err := viper.ReadInConfig(); err != nil {
fmt.Println("Can't read config:", err)
os.Exit(1)
}
}
создать main.go
С командой root вам нужна основная функция для ее выполнения. Для ясности,Execute
Должен запускаться в корневом каталоге, хотя его можно вызвать любой командой.
В приложении Кобраmain.go
очень просто. У него всего одна функция - инициализировать Кобру.
// main.go
package main
import (
"{pathToYourApp}/cmd"
)
func main() {
cmd.Execute()
}
Создайте дополнительные команды
Дополнительные команды могут быть определены и обычноcmd/
Каталог предоставляет каждой команде свой собственный файл.
Если вы хотите создатьversion
команда, вы можете создатьcmd/version.go
и заполните его:
// cmd/version.go
package cmd
import (
"fmt"
"github.com/spf13/cobra"
)
func init() {
rootCmd.AddCommand(versionCmd)
}
var versionCmd = &cobra.Command{
Use: "version",
Short: "Print the version number of Hugo",
Long: `All software has versions. This is Hugo's`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("Hugo Static Site Generator v0.9 -- HEAD")
},
}
использовать логотип
Флаги предоставляют модификаторы для управления работой команды.
Поскольку флаги определены и используются в разных местах, нам нужно определить переменную с правильной областью действия снаружи, чтобы назначить флаг, который будет использоваться.
var verbose bool
var source string
Здесь есть два разных способа назначения флагов.
непреходящий знак
Флаг может быть «постоянным», что означает, что флаг будет доступен команде, которой он назначен, и каждой команде под этой командой. Для глобальных флагов назначьте флаг в качестве постоянного флага в корне.
rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "verbose output")
местный знак
Также можно локально назначить флаг, который применяется только к этой конкретной команде.
rootCmd.Flags().StringVarP(&source, "source", "s", "", "Source directory to read from")
локальный флаг родительской команды
По умолчанию Cobra анализирует только локальные флаги целевой команды, игнорируя любые локальные флаги родительской команды. путем включенияCommand.TraverseChildren
, Cobra будет анализировать локальные флаги для каждой команды перед выполнением целевой команды.
command := cobra.Command{
Use: "print [OPTIONS] [COMMANDS]",
TraverseChildren: true,
}
привязать флаг к конфигу
Вы также можете использовать флаг сviperСвязывать:
var author string
func init() {
rootCmd.PersistentFlags().StringVar(&author, "author", "YOUR NAME", "Author name for copyright attribution")
viper.BindPFlag("author", rootCmd.PersistentFlags().Lookup("author"))
}
В этом примере постоянный тегauthor
Привязка к гадюке. Обратите внимание, что когда пользователь не предоставляет--author
Когда флаги, переменнаяauthor
не будет установленоconfig
значение в .
Для получения дополнительной информации см.viper.
Требуемый флаг
Флаги являются необязательными по умолчанию. Если вы хотите, чтобы команда сообщала об ошибке, если флаг отсутствует, установите для флага обязательное значение:
var region string
rootCmd.Flags().StringVarP(®ion, "region", "r", "", "AWS region (required)")
rootCmd.MarkFlagRequired("region")
Местоположение и пользовательские параметры
Проверка позиционных аргументов может быть указана с помощью поля Args команды.
Встроены следующие валидаторы:
-
NoArgs
- При наличии позиционных аргументов команда сообщит об ошибке. -
ArbitraryArgs
- команда будет принимать произвольные аргументы -
OnlyValidArgs
- если командаValidArgs
Если позиционный параметр отсутствует в поле, команда сообщит об ошибке. -
MinimumNArgs(int)
- Если не будет хотя бы N позиционных аргументов, команда сообщит об ошибке. -
MaximumNArgs(int)
- Если позиционных аргументов больше N, команда сообщит об ошибке. -
ExactArgs(int)
- Если нет N позиционных аргументов, команда сообщит об ошибке. -
ExactValidArgs(int)
- Если нет точных N позиционных аргументов или если позиционные аргументы отсутствуют в поле ValidArgs команды, команда выдаст сообщение об ошибке. -
RangeArgs(min, max)
- Если количество аргументов не находится между ожидаемым минимальным и максимальным количеством аргументов, команда выдаст сообщение об ошибке.
Примеры использования встроенных валидаторов:
var cmd = &cobra.Command{
Use: "hello",
Short: "hello",
Args: cobra.MinimumNArgs(2),
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("Hello, World!")
},
}
Если передан только один позиционный параметр, он сообщит
Error: requires at least 2 arg(s), only received 1
предупреждение.
Пример настройки пользовательского валидатора:
var cmd = &cobra.Command{
Short: "hello",
Args: func(cmd *cobra.Command, args []string) error {
if len(args) < 1 {
return errors.New("requires at least one arg")
}
if myapp.IsValidColor(args[0]) {
return nil
}
return fmt.Errorf("invalid color specified: %s", args[0])
},
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("Hello, World!")
},
}
Пример
В приведенном ниже примере мы определяем три команды. Два на верхнем уровне, один(cmdTimes
) является подкомандой. В этом случае корневой каталог не является исполняемым, что означает, что требуется подкоманда. не дляrootCmd
поставкаRun
реализовать.
Мы определяем только один флаг для одной команды.
Документация по флагам находится в [pflag]GitHub.com/commodity13/P флаг…
package main
import (
"fmt"
"strings"
"github.com/spf13/cobra"
)
func main() {
var echoTimes int
var cmdPrint = &cobra.Command{
Use: "Print [string to print]",
Short: "Print anything to the screen",
Long: `print is for printing anything back to the screen.
For many years people have printed back to the screen.`,
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("Print: " + strings.Join(args, " "))
},
}
var cmdEcho = &cobra.Command{
Use: "echo [string to echo]",
Short: "Echo anything to the screen",
Long: `echo is for echoing anything back.
Echo works a lot like print, except it has a child command.`,
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("Print: " + strings.Join(args, " "))
},
}
var cmdTimes = &cobra.Command{
Use: "times [# times] [string to echo]",
Short: "Echo anyting to the screen more times",
Long: `echo things multiple times back to the user y providing
a count and a string.`,
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
for i := 0; i < echoTimes; i++ {
fmt.Println("Echo: " + strings.Join(args, " "))
}
},
}
cmdTimes.Flags().IntVarP(&echoTimes, "times", "t", 1, "times to echo the input")
// 设置根命令
var rootCmd = &cobra.Command{Use: "app"}
rootCmd.AddCommand(cmdPrint, cmdEcho)
cmdEcho.AddCommand(cmdTimes)
// 初始化应用
rootCmd.Execute()
}
Для более сложных приложений см.HugoилиGitHub CLI.
команда справки
Когда вы добавляете подкоманды, Cobra автоматически добавит некоторые команды справки. когда вы выполняетеapp help
При выполнении команды отображается справочное сообщение. Кроме того,help
Дополнительные команды также поддерживаются в качестве входных параметров. Например, у вас естьcreate
Заказ,app help create
Это эффективно. Каждая команда также автоматически получает--help
логотип.
Пример
Следующий вывод автоматически генерируется Cobra. Ничего не требуется, кроме определений команд и флагов.
help
Как и любая другая команда. Никакой особой логики или поведения. На самом деле, вы можете предоставлять свои собственные услуги по мере необходимости.
определить свою собственную помощь
Вы можете предоставить свои собственные команды справки или шаблоны, используя методы, описанные ниже.
cmd.SetHelpCommand(cmd *Command)
cmd.setHelpCommand(f func(*Command, []string))
cmd.setHelpTemplate(s string)
Последние две также применяются ко всем подкомандам.
информация об использовании
Когда пользователь указывает недопустимый флаг или недопустимую команду, Cobra покажет пользователюusage
отвечать.
Определите свою собственную информацию об использовании
Вы можете предоставить свою собственную функцию использования или шаблон. рисунокhelp
Точно так же функции и шаблоны можно переопределить с помощью общедоступных методов:
cmd.SetUsageFunc(f func(*Command) error)
cmd.SetUsageTemplate(s string)
может относиться кGitHub CLIписьма.
флаг версии
Если установлена корневая командаVersion
поле, Cobra добавит верхний уровень--version
логотип. бежать с–version
Подписанное приложение, которое будет использовать шаблон версии для печати версии на стандартный вывод. Можно использовать шаблоныcmd.SetVersionTemplate(s string)
Настройка функций.
SetVersionTemplate
Использование может относиться кGitHub CLI
Хуки PreRun и PostRun
Функция может быть запущена до и после выполнения команды.PersistentPreRun
иPreRun
функция будет вRun
выполнял раньше.PersistentPostRun
иPostRun
Будет вRun
беги после этого. Если ребенок не заявляет о себеPersistent * Run
функция, потомок наследует функцию родителя. Последовательность выполнения этих функций следующая:
- PersistentPreRun
- PreRun
- Run
- PostRun
- PersistentPostRun
В следующем примере двух команд используются эти функции. Когда подкоманда выполняется, она запускает корневую командуPersistentPreRun
, но не будет запускать команду rootPersistentPostRun
:
package main
import (
"fmt"
"github.com/spf13/cobra"
)
func main() {
var rootCmd = &cobra.Command{
Use: "root [sub]",
Short: "My root command",
PersistentPreRun: func(cmd *cobra.Command, args []string) {
fmt.Printf("Inside rootCmd PersistentPreRun with args: %v\n", args)
},
PreRun: func(cmd *cobra.Command, args []string) {
fmt.Printf("Inside rootCmd PreRun with args: %v\n", args)
},
Run: func(cmd *cobra.Command, args []string) {
fmt.Printf("Inside rootCmd Run with args: %v\n", args)
},
PostRun: func(cmd *cobra.Command, args []string) {
fmt.Printf("Inside rootCmd PostRun with args: %v\n", args)
},
PersistentPostRun: func(cmd *cobra.Command, args []string) {
fmt.Printf("Inside rootCmd PersistentPostRun with args: %v\n", args)
},
}
subCmd := &cobra.Command{
Use: "sub [no options!]",
Short: "My subcommand",
PreRun: func(cmd *cobra.Command, args []string) {
fmt.Printf("Inside subCmd PreRun with args: %v\n", args)
},
Run: func(cmd *cobra.Command, args []string) {
fmt.Printf("Inside subCmd Run with args: %v\n", args)
},
PostRun: func(cmd *cobra.Command, args []string) {
fmt.Printf("Inside subCmd PostRun with args: %v\n", args)
},
PersistentPostRun: func(cmd *cobra.Command, args []string) {
fmt.Printf("Inside subCmd PersistentPostRun with args: %v\n", args)
},
}
rootCmd.AddCommand(subCmd)
rootCmd.SetArgs([]string{""})
rootCmd.Execute()
fmt.Println()
rootCmd.SetArgs([]string{"sub", "arg1", "arg2"})
rootCmd.Execute()
}
вывод:
Inside rootCmd PersistentPreRun with args: []
Inside rootCmd PreRun with args: []
Inside rootCmd Run with args: []
Inside rootCmd PostRun with args: []
Inside rootCmd PersistentPostRun with args: []
Inside rootCmd PersistentPreRun with args: [arg1 arg2]
Inside subCmd PreRun with args: [arg1 arg2]
Inside subCmd Run with args: [arg1 arg2]
Inside subCmd PostRun with args: [arg1 arg2]
Inside subCmd PersistentPostRun with args: [arg1 arg2]
Подскажите "неизвестная команда"
когда"unknown command"
При возникновении ошибки Cobra автоматически распечатывает предупреждение. Это согласуется с поведением команды git. Например
$ hugo srever
Error: unknown command "srever" for "hugo"
Did you mean this?
server
Run 'hugo --help' for usage.
Система автоматически генерирует предложения на основе каждой зарегистрированной подкоманды и используетРасстояние Левенштейнареализация. Каждая зарегистрированная команда, которая соответствует минимальному расстоянию 2 (без учета регистра), будет отображаться как предложение.
Если вам нужно отключить предложения или настроить расстояние между строками в команде, используйте:
cmd.DisableSuggestions = true
или
cmd.SuggestionsMinimumDistance = 1
Вы также можете использоватьSuggestFor
свойство явно устанавливает предлагаемое имя для данной команды. Это позволяет предлагать строки, которые не очень близки, но имеют смысл для вашего набора команд и для команд, которым не нужны псевдонимы. Например:
$ kubectl remove
Error: unknown command "remove" for "kubectl"
Did you mean this?
delete
Run 'kubectl help' for usage.
Создание документации для ваших команд
Cobra может генерировать документацию на основе подкоманд, флагов и т. д. Доступные форматы:
Создание дополнений Bash для вашей команды
Cobra может генерировать файлы завершения bash. Если вы добавите больше информации в свою команду, анализ этих самовнушений может быть очень мощным и гибким. Больше информации, пожалуйста, прочитайтеBash Completions
У Tuya Smart большое количество качественных НС, присоединяться могут все желающие, нужно добавить меня в WeChat yang_jun_ning, или прислать свое резюме прямо на почтуyoungjuning@aliyun.com