le mie informazioni di contatto
Posta[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Quando ho aperto il codice k8s, ho scoperto che fondamentalmente i servizi principali utilizzano la libreria cobra come funzionalità di elaborazione della riga di comando.Pertanto, per comprendere più a fondo l'apprendimento del codice dietro il codice, scriviamo prima una demo basata su questa libreria per approfondire la nostra comprensione di questa libreria.
Pagina inizialeGitHub - spf13/cobra: un comandante per le interazioni moderne con la CLI Go Eccolo, Cobra è uno strumento da riga di comando implementato nel linguaggio Go. E ora viene utilizzato da molti progetti, come Kubernetes, Hugo e Github CLI, ecc.Utilizzando Cobra possiamo creare rapidamente strumenti a riga di comando, particolarmente adatti alla scrittura测试脚本
, servizi vari Admin CLI
Aspettare.
A causa dei parametri della riga di comando, Golang stesso viene fornito con la libreria "flag". Come utilizzare la libreria flag?
- flag.Parse()
-
- args := flag.Args()
Dopo l'analisi, ogni comando deve essere giudicato, il che è molto problematico.
Ma quando la usiamo, dobbiamo fare varie analisi e giudizi sulla riga di comando, ma con questa libreria possiamo ridurre questo codice ridondante.
Senza ulteriori indugi, spieghiamo direttamente come utilizzare questo progetto. Il mio ambiente è su macos.
Esecuzione della riga di comando
go get -u github.com/spf13/cobra@latest
$ go install github.com/spf13/cobra-cli@latest
Poiché ho già creato la directory bin nel mio percorso del codice golang, quindi dopo aver eseguito questo comando, è il seguente
Abbiamo visto il file eseguibile di cobra-cli.
Qui possiamo usare questa cosa nel comando per inizializzarlo.I passaggi collettivi sono i seguenti
- xxx@MBP src % mkdir greet
- xxx@MBP src % cd greet
- xxx@MBP test % ls
- xxx@MBP greet % cobra-cli init
- Error: Please run `go mod init <MODNAME>` before `cobra-cli init`
- xxx@MBP greet % go mod init greet
- go: creating new go.mod: module greet
- xxx@MBP greet % ls
- go.mod
- xxx@MBP greet % cobra-cli init
- Your Cobra application is ready at
- /Users/XXX/workspace/golang/src/greet
- xxx@MBP greet % ls
- LICENSE cmd go.mod go.sum main.go
- xxx@MBP greet %
Il primo passaggio è creare una directory di test, quindi eseguire go mod init test, quindi eseguire la riga di comando cobra-cli init e verrà generato il file di scaffolding.
Nella directory verranno generati i seguenti file:
- main.go cmd LICENSE go.mod go.sum
- ├── LICENSE
- ├── cmd
- │ └── root.go
- └── main.go
- go.mod
- go.sum
Il file appena generato potrebbe non essere di grande utilità perché non ci sono opzioni di comando specifiche, quindi continuiamo ad eseguirlo e aggiungiamo una parola di comando
cobra-cli add [command]
In questo modo genererà un altro file.
Ad esempio, esegui
cobra-cli aggiungi saluto
- // Package cmd /*
- package cmd
-
- import (
- "fmt"
-
- "github.com/spf13/cobra"
- )
-
- // greetCmd represents the greet command
- var greetCmd = &cobra.Command{
- Use: "greet",
- Short: "A brief description of your command",
- Long: `A longer description that spans multiple lines and likely contains examples
- and usage of using your command. For example:
-
- Cobra is a CLI library for Go that empowers applications.
- This application is a tool to generate the needed files
- to quickly create a Cobra application.`,
- Run: func(cmd *cobra.Command, args []string) {
- // 这段代码是我加的。
- if len(args) < 1 {
- cmd.Help()
- return
- }
- name := args[0]
- fmt.Println("greet called:", name)
- },
- }
-
- func init() {
- rootCmd.AddCommand(greetCmd)
-
- // Here you will define your flags and configuration settings.
-
- // Cobra supports Persistent Flags which will work for this command
- // and all subcommands, e.g.:
- // greetCmd.PersistentFlags().String("foo", "", "A help for foo")
-
- // Cobra supports local flags which will only run when this command
- // is called directly, e.g.:
- greetCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
- }
Pertanto possiamo vedere che è stato aggiunto il comando greet.
Quindi lo compiliamo e generiamo il file di destinazione, quindi eseguiamo quanto segue
- ./greet
-
- A longer description that spans multiple lines and likely contains
- examples and usage of using your application. For example:
-
- Cobra is a CLI library for Go that empowers applications.
- This application is a tool to generate the needed files
- to quickly create a Cobra application.
-
- Usage:
- greet [command]
-
- Available Commands:
- completion Generate the autocompletion script for the specified shell
- greet A brief description of your command
- help Help about any command
- mockMsg A brief description of your command
-
- Flags:
- -h, --help help for greet
- -t, --toggle Help message for toggle
-
- Use "greet [command] --help" for more information about a command.
-
Dal contenuto restituito sopra, possiamo vedere che esiste un ulteriore sottocomando gree.
E puoi aggiungere flag, come -h
L'esecuzione sopra può contenere la logica aziendale che vogliamo elaborare.
Se vogliamo aggiungere alcuni valori flag, dobbiamo solo aggiungere il seguente codice in run
- g, _ := cmd.Flags().GetInt32("goroutine")
- p, _ := cmd.Flags().GetInt32("packet")
- fmt.Println("mockmsg called,flags:g=", g, ",p=", p, ",args:", args)
Ad esempio, implementiamo quanto segue:
- Run: func(cmd *cobra.Command, args []string) {
- if len(args) < 1 {
- cmd.Help()
- return
- }
- name := args[0]
- fmt.Println("greet called:", name)
-
- g, _ := cmd.Flags().GetInt32("goroutine")
- p, _ := cmd.Flags().GetInt32("packet")
- fmt.Println("mockmsg called,flags:g=", g, ",p=", p, ",args:", args)
- },
In questo modo, può essere utilizzato in questo modo
- ./greet greet xx -p 10 -g 100
- greet called: xx
- greetCmd called,flags:g= 100 ,p= 10 ,args: [xx]
-
Ho esaminato principalmente il codice del modulo kubctl e ho scoperto che questo modulo ha un incapsulamento più ricco di cmd per supportare scenari più complessi.
Tra questi partiamo dal principale di kubectl
un metodo di immissione
- // NewDefaultKubectlCommand creates the `kubectl` command with default arguments
- func NewDefaultKubectlCommand() *cobra.Command {
- ioStreams := genericiooptions.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr}
- return NewDefaultKubectlCommandWithArgs(KubectlOptions{
- PluginHandler: NewDefaultPluginHandler(plugin.ValidPluginFilenamePrefixes),
- Arguments: os.Args,
- ConfigFlags: defaultConfigFlags().WithWarningPrinter(ioStreams),
- IOStreams: ioStreams,
- })
- }
Poiché kubectl può elaborare file e flag, è necessario impostare vari parametri per questa situazione. Abbiamo riscontrato che ogni campo nella struttura cmd è stato completamente utilizzato.
Questi due metodi sono i metodi principali, che sono sostanzialmente inizializzati e assegnati alla struttura dei comandi.
- // NewDefaultKubectlCommandWithArgs creates the `kubectl` command with arguments
- func NewDefaultKubectlCommandWithArgs(o KubectlOptions) *cobra.Command {
- cmd := NewKubectlCommand(o)
Tra questi, NewKubectlCommand viene utilizzato per le nuove istanze cmd.
- func NewKubectlCommand(o KubectlOptions) *cobra.Command {
- warningHandler := rest.NewWarningWriter(o.IOStreams.ErrOut, rest.WarningWriterOptions{Deduplicate: true, Color: term.AllowsColorOutput(o.IOStreams.ErrOut)})
- warningsAsErrors := false
- // Parent command to which all subcommands are added.
- cmds := &cobra.Command{
- Use: "kubectl",
Qui è dove vediamo l'uso dei comandi kubectl Poiché questo articolo parla principalmente dell'uso del comando, non entreremo nei dettagli sugli altri comandi get di k8s, ne parleremo nel prossimo articolo.
Di seguito è riportata una spiegazione dettagliata degli specifici campi correlati di Comando.
以下是对 `Command` 结构体中每个字段的详细解释:
- 1. `Use`:这是一个字符串,用于描述命令的基本使用方式。它规定了命令所需的参数和可选参数的格式,为用户提供了简洁明了的使用指导。
- - 例如:`"add [-F file | -D dir]... [-f format] profile"` 表示 `add` 命令可以有可选的 `-F` 和 `-D` 参数,其中 `-F` 后跟一个文件,`-D` 后跟一个目录,这两个参数是互斥的,并且可以多次出现,还有一个可选的 `-f` 参数后跟格式信息,最后需要一个 `profile` 参数。
-
- 2. `Aliases`:一个字符串切片,存储了该命令的别名。这使得用户可以通过不同的名称来调用同一个命令,增加了命令使用的灵活性。
- - 比如:`["add_item", "insert"]` 是 `add` 命令的别名。
-
- 3. `SuggestFor`:也是一个字符串切片,其中包含了此命令可能被建议替代的其他命令名称。这有助于在用户输入类似但不完全准确的命令时提供相关的建议。
-
- 4. `Short`:一个简短的字符串,用于在帮助输出中提供命令的简短描述,让用户快速了解命令的主要功能。
- - 例如:"添加新的项目"
-
- 5. `GroupID`:指定该子命令在其父命令的“帮助”输出中所属的组标识,便于对命令进行分组展示和管理。
-
- 6. `Long`:详细的长字符串,在“帮助 <此命令>”输出中提供更全面和深入的命令描述,包括更多的功能细节、使用示例、注意事项等。
-
- 7. `Example`:包含命令使用的示例字符串,通过实际的例子帮助用户更好地理解如何正确使用该命令。
-
- 8. `ValidArgs`:一个字符串切片,列出了在外壳自动补全中所有有效的非标志参数。
-
- 9. `ValidArgsFunction`:一个函数,动态地提供有效的非标志参数用于外壳自动补全,是一种更灵活的参数提供方式。
-
- 10. `Args`:定义了预期的参数的相关规则和处理方式。
-
- 11. `ArgAliases`:一个字符串切片,列出了有效参数的别名,这些别名不会在外壳自动补全中被提示,但手动输入时会被接受。
-
- 12. `BashCompletionFunction`:用于传统 Bash 自动补全生成器的自定义 Bash 函数,为特定的 Bash 环境提供定制的自动补全功能。
-
- 13. `Deprecated`:如果命令已被弃用,存储了使用该命令时将显示的提示信息,告知用户该命令不应再被使用。
-
- 14. `Annotations`:一个键值对映射,允许应用程序为命令添加自定义的标识、分组或特殊选项等元数据。
-
- 15. `Version`:存储命令的版本信息,用于版本控制和显示。
-
- 16. 各种 `Run` 函数:
- - `PersistentPreRun` 和 `PersistentPreRunE`:在命令执行前被调用,且子命令会继承并执行,用于进行一些持久的预处理操作。
- - `PreRun` 和 `PreRunE`:在命令执行前被调用,但子命令不会继承,用于特定于当前命令的预处理。
- - `Run` 和 `RunE`:实际的工作函数,实现命令的主要逻辑。
- - `PostRun` 和 `PostRunE`:在 `Run` 函数执行后被调用,用于进行后续的处理操作。
-
- 17. `commandgroups`:一个指针切片,指向子命令所属的组对象。
-
- 18. `args`:实际从标志解析得到的参数切片。
-
- 19. `flagErrorBuf`:一个字节缓冲区,用于存储来自 `pflag` 的错误消息。
-
- 20. `flags`:一个 `flag.FlagSet` 对象,包含了所有的标志。
-
- 21. `pflags`:存储持久的标志。
-
- 22. `lflags`:本地标志的缓存,用于优化 `LocalFlags` 函数调用。
-
- 23. `iflags`:继承的标志的缓存,用于优化相关函数调用。
-
- 24. `parentsPflags`:父命令的所有持久标志。
-
- 25. `globNormFunc`:一个全局的标准化函数,用于处理标志名称的标准化。
-
- 26. `usageFunc`:用户定义的使用函数,用于自定义命令的使用说明。
-
- 27. `usageTemplate`:用户定义的使用模板。
-
- 28. `flagErrorFunc`:用户定义的标志错误处理函数。
-
- 29. `helpTemplate`:用户定义的帮助模板。
-
- 30. `helpFunc`:用户定义的帮助函数。
-
- 31. `helpCommand`:具有“帮助”用途的命令,如果用户未定义,则使用默认的帮助命令。
-
- 32. `helpCommandGroupID`:帮助命令所属的组标识。
-
- 33. `completionCommandGroupID`:自动完成命令所属的组标识。
-
- 34. `versionTemplate`:用户定义的版本模板。
-
- 35. `errPrefix`:用户定义的错误消息前缀。
-
- 36. `inReader`:用户定义的输入读取器,替代标准输入。
-
- 37. `outWriter`:用户定义的输出写入器,替代标准输出。
-
- 38. `errWriter`:用户定义的错误输出写入器,替代标准错误输出。
-
- 39. `FParseErrWhitelist`:要忽略的标志解析错误的列表。
-
- 40. `CompletionOptions`:用于控制外壳自动完成的选项。
-
- 41. `commandsAreSorted`:一个布尔值,指示命令切片是否已排序。
-
- 42. `commandCalledAs`:一个结构体,记录命令被调用时的名称和是否被调用的状态。
-
- 43. `ctx`:上下文对象,用于传递和管理命令执行的上下文信息。
-
- 44. `commands`:一个指针切片,包含此命令支持的子命令。
-
- 45. `parent`:指向该命令的父命令的指针。
-
- 46. `Max lengths` 相关字段:记录命令相关字符串的最大长度,用于格式化和展示。
-
- 47. `TraverseChildren`:一个布尔值,决定是否在执行子命令之前解析所有父命令的标志。
-
- 48. `Hidden`:如果为真,该命令将在可用命令列表中隐藏,不向用户显示。
-
- 49. `SilenceErrors`:一个布尔值,用于控制是否静默处理错误。
-
- 50. `SilenceUsage`:一个布尔值,用于控制在发生错误时是否静默使用信息。
-
- 51. `DisableFlagParsing`:如果为真,将禁用标志解析,所有标志将作为参数传递给命令。
-
- 52. `DisableAutoGenTag`:如果为真,在生成文档时将禁用自动生成的标签。
-
- 53. `DisableFlagsInUseLine`:如果为真,将在使用行中禁用标志的添加。
-
- 54. `DisableSuggestions`:如果为真,将禁用基于编辑距离的建议功能。
-
- 55. `SuggestionsMinimumDistance`:定义显示建议的最小编辑距离,必须大于 0 。
Questo articolo è principalmente una spiegazione passo passo di come utilizzare la libreria cobra. Quando utilizziamo questa libreria, possiamo comprendere meglio il suo principio di funzionamento e quindi in base a come utilizzare i k8 specifici e l'uso di campi specifici A. dare pieno gioco alle capacità e al valore di cmd