Кобра Китайская документация

задняя часть Go
Кобра Китайская документация

Я не профессиональный переводчик и не профессиональный 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 mean app 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.Command API

Флаги

Флаг — это способ украшения поведения команды. Поддержка 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(&region, "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