Árvores de Comandos cobra & urfave/cli
Ferramentas no estilo kubectl precisam de subcomandos aninhados, flags globais compartilhadas e texto de ajuda consistente.
Busque em todas as páginas da documentação
Ferramentas no estilo kubectl precisam de subcomandos aninhados, flags globais compartilhadas e texto de ajuda consistente.
cobra (github.com/spf13/cobra) é a escolha mais comum no ecossistema Go.
urfave/cli v2 (github.com/urfave/cli/v2) oferece uma alternativa orientada a structs com hooks e completação bash.
Ambos compilam no mesmo modelo de binário único; escolha com base no gosto pela API e integração com o ecossistema (cobra se integra naturalmente com viper e scaffolds do controller-runtime).
Árvores de comandos mapeiam argv para uma função Run ou RunE selecionada.
Comandos pais detêm flags persistentes (caminho de configuração, verbosidade), enquanto comandos folha declaram flags específicas da ação.
Execute percorre a árvore, imprime ajuda em caso de erros e define códigos de saída para scripts de shell.
Geradores de completação de shell reduzem erros de digitação para caminhos de comando longos como mytool db migrate up.
Cartão de receita de referência rápida - pronto para copiar e colar.
root := &cobra.Command{Use: "mytool"}
root.PersistentFlags().StringVar(&cfgFile, "config", "", "arquivo de configuração")
root.AddCommand(&cobra.Command{
Use: "run",
Short: "inicia worker",
RunE: func(cmd *cobra.Command, args []string) error { return runWorker(cfgFile) },
})
return root.Execute()Quando usar isso:
get, describe, delete).--kubeconfig, --namespace).package main
import (
"fmt"
"os"
"github.com/spf13/cobra"
)
var verbose bool
func main() {
root := &cobra.Command{
Use: "ship",
Short: "utilitários de envio",
}
root.PersistentFlags().BoolVar(&verbose, "verbose", false, "logs verbosos")
initCmd := &cobra.Command{
Use: "init",
Short: "inicializa workspace",
RunE: func(cmd *cobra.Command, args []string) error {
dir, _ := cmd.Flags().GetString("dir")
if verbose {
fmt.Println("init", dir)
}
return nil
},
}
initCmd.Flags().String("dir", ".", "diretório de destino")
root.AddCommand(initCmd)
if err := root.Execute(); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}O que isso demonstra:
PersistentFlags em root se aplicam a init e futuros irmãos.initCmd.RunE retorna erros; Execute lida com a impressão e o status de saída.cmd.Flags().GetString lê valores analisados dentro do manipulador.*cobra.Command no momento da inicialização.Execute analisa flags globais, encontra o comando correspondente mais profundo, analisa flags locais, valida Args e, em seguida, chama RunE.cmd.Help() pode ser chamado a partir do código.cli.App com []*cli.Command e hooks Before/After em vez de flags persistentes em uma struct.| Recurso | cobra | urfave/cli v2 |
|---|---|---|
| Flags persistentes | PersistentFlags() | Flags no pai + herança via subcomandos |
| Validação de Args | Args: cobra.ExactArgs(1) | Action verifica cli.Context |
| Completação | GenBashCompletion / GenZshCompletion | EnableBashCompletion + Complete |
| Integração com Config | viper.BindPFlags | manual ou de terceiros |
| Ecossistema | kubebuilder, operator-sdk | CLIs autônomas |
# exemplo bash após gerar o script de completação
mytool completion bash > /etc/bash_completion.d/mytoolRegisterFlagCompletionFunc.cmd/; coloque a lógica de negócios em internal/.RunE em vez de Run para que os erros se propaguem para Execute.SilenceUsage: true em comandos quando erros de análise não devem despejar a ajuda completa.Execute de múltiplos testes sem resetar - Estado global em pflags. Correção: root.SetArgs([]string{"init", "--dir", "/tmp"}) por teste./v2. Correção: fixe github.com/urfave/cli/v2.Args ausente - Operadores passam aridade errada e obtêm erros confusos. Correção: cobra.MinimumNArgs, ValidArgsFunction personalizado.| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
flag do stdlib + switch | Um ou dois subcomandos | Manutenção de completação e ajuda se torna difícil |
| kong | Definições de CLI com tags de struct | Equipe já padronizada em cobra |
| análise manual de argv | Ferramenta interna de 10 linhas | Usuários precisam de --help descobrível |
| binários separados | Sensibilidade extrema à inicialização | Operadores esperam um único ponto de entrada mytool |
Scaffolds do kubebuilder e controller-runtime geram comandos cobra.
Flags persistentes de kubeconfig e verbos aninhados correspondem à forma como kubectl modela recursos.
Flags persistentes se registram em ancestrais e se aplicam a descendentes.
Flags locais existem apenas no comando que as define.
Chame cmd.SetArgs([]string{...}) e cmd.Execute() ou invoque RunE diretamente com um *cobra.Command construído no teste.
Evite analisar os.Args real em testes paralelos.
Defina Hidden: true em comandos de manutenção ou alfa.
Eles ainda são executados quando invocados diretamente, mas desaparecem das listas de ajuda padrão.
viper.BindPFlags(cmd.Flags()) mapeia flags analisadas para chaves viper.
Leia a configuração após Execute iniciar ou em PersistentPreRunE.
Escolha cobra quando quiser padrões estilo kube e geradores de completação.
Escolha urfave/cli quando preferir hooks centrados no aplicativo e uma superfície conceitual menor.
Adicione um subcomando version ou use cobra.Command.Version com SetVersionTemplate.
Carimbe a versão com -ldflags no momento da compilação.
Use cmd.Context() dentro de RunE (cobra o define no comando).
Passe esse contexto para chamadas HTTP e de banco de dados para cancelamento.
Marque a string Deprecated no comando; cobra imprime um aviso quando usado.
Mantenha o comando funcional até a versão de remoção documentada.
A completação do PowerShell existe para cobra com scripts gerados.
Teste nos shells de destino que seus operadores realmente usam.
Versões da Stack: Esta página foi escrita para Go 1.26.x (padrão Green Tea GC, go fix modernizers - verifique o patch na compilação), chi (última versão - verifique na compilação), gin (última versão - verifique na compilação), echo (última versão - verifique na compilação), google.golang.org/grpc (última versão - verifique na compilação), sigs.k8s.io/controller-runtime (última versão - verifique na compilação), kubebuilder (última versão - verifique na compilação), tinygo (última versão - verifique os alvos de placa na compilação), wazero (última versão - verifique na compilação) e golangci-lint (última versão - verifique o conjunto de linters na compilação).
Revisado por Chris St. John·Última atualização: 16 de jul. de 2026