Árboles de Comandos de cobra & urfave/cli
Las herramientas estilo kubectl necesitan subcomandos anidados, flags globales compartidos y texto de ayuda consistente.
Busca en todas las páginas de la documentación
Las herramientas estilo kubectl necesitan subcomandos anidados, flags globales compartidos y texto de ayuda consistente.
cobra (github.com/spf13/cobra) es la opción más común en el ecosistema Go.
urfave/cli v2 (github.com/urfave/cli/v2) ofrece una alternativa basada en structs con hooks y completado de bash.
Ambos compilan en el mismo modelo de binario único; elige basándote en el gusto por la API y la integración con el ecosistema (cobra se empareja naturalmente con viper y los scaffolds de controller-runtime).
Los árboles de comandos mapean argv a una función Run o RunE seleccionada.
Los comandos padre albergan flags persistentes (ruta de configuración, verbosidad) mientras que los comandos hoja declaran flags específicos de la acción.
Execute recorre el árbol, imprime ayuda en caso de errores y establece códigos de salida para scripts de shell.
Los generadores de completado de shell reducen los errores tipográficos para rutas de comandos largas como mytool db migrate up.
Tarjeta de referencia rápida - lista para copiar y pegar.
root := &cobra.Command{Use: "mytool"}
root.PersistentFlags().StringVar(&cfgFile, "config", "", "archivo de configuración")
root.AddCommand(&cobra.Command{
Use: "run",
Short: "iniciar worker",
RunE: func(cmd *cobra.Command, args []string) error { return runWorker(cfgFile) },
})
return root.Execute()Cuándo usar esto:
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: "utilidades de envío",
}
root.PersistentFlags().BoolVar(&verbose, "verbose", false, "logs detallados")
initCmd := &cobra.Command{
Use: "init",
Short: "inicializar espacio de trabajo",
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", ".", "directorio de destino")
root.AddCommand(initCmd)
if err := root.Execute(); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}Lo que esto demuestra:
PersistentFlags en root se aplican a init y a sus futuros hermanos.initCmd.RunE devuelve errores; Execute maneja la impresión y el estado de salida.cmd.Flags().GetString lee los valores analizados dentro del manejador.*cobra.Command en tiempo de inicialización.Execute analiza los flags globales, encuentra el comando coincidente más profundo, analiza los flags locales, valida Args, y luego llama a RunE.cmd.Help() es invocable desde el código.cli.App con []*cli.Command y hooks Before/After en lugar de flags persistentes en una struct.| Característica | cobra | urfave/cli v2 |
|---|---|---|
| Flags persistentes | PersistentFlags() | Flags en el padre + herencia a través de subcomandos |
| Validación de Args | Args: cobra.ExactArgs(1) | Action verifica cli.Context |
| Completado | GenBashCompletion / GenZshCompletion | EnableBashCompletion + Complete |
| Emparejamiento de Configuración | viper.BindPFlags | manual o de terceros |
| Ecosistema | kubebuilder, operator-sdk | CLIs independientes |
# ejemplo de bash después de generar el script de completado
mytool completion bash > /etc/bash_completion.d/mytoolRegisterFlagCompletionFunc.cmd/; pon la lógica de negocio en internal/.RunE sobre Run para que los errores se propaguen a Execute.SilenceUsage: true en los comandos cuando los errores de análisis no deban volcar la ayuda completa.Execute desde múltiples pruebas sin restablecer - Estado global en pflags. Solución: root.SetArgs([]string{"init", "--dir", "/tmp"}) por prueba./v2. Solución: fija github.com/urfave/cli/v2.Args faltantes - Los operadores pasan la aridad incorrecta y obtienen errores confusos. Solución: cobra.MinimumNArgs, ValidArgsFunction personalizado.| Alternativa | Usar Cuando | No Usar Cuando |
|---|---|---|
flag de stdlib + switch | Uno o dos subcomandos | El mantenimiento de completado y ayuda se resiente |
| kong | Definiciones de CLI con tags de struct | El equipo ya está estandarizado en cobra |
| análisis manual de argv | Herramienta interna de 10 líneas | Los usuarios necesitan un --help descubrible |
| binarios separados | Sensibilidad extrema al inicio | Los operadores esperan un único punto de entrada mytool |
Los scaffolds de kubebuilder y controller-runtime generan comandos cobra.
Los flags persistentes de kubeconfig y los verbos anidados coinciden con la forma en que kubectl modela los recursos.
Los flags persistentes se registran en los ancestros y se aplican a los descendientes.
Los flags locales existen solo en el comando que los define.
Llama a cmd.SetArgs([]string{...}) y cmd.Execute() o invoca RunE directamente con un *cobra.Command construido en la prueba.
Evita analizar os.Args reales en pruebas paralelas.
Establece Hidden: true en comandos de mantenimiento o alfa.
Todavía se ejecutan cuando se invocan directamente, pero desaparecen de las listas de ayuda predeterminadas.
viper.BindPFlags(cmd.Flags()) mapea los flags analizados a claves de viper.
Lee la configuración después de que Execute comience o en PersistentPreRunE.
Elige cobra cuando quieras patrones estilo kube y generadores de completado.
Elige urfave/cli cuando prefieras hooks centrados en la aplicación y una superficie conceptual más pequeña.
Agrega un subcomando version o usa cobra.Command.Version con SetVersionTemplate.
Estampa la versión con -ldflags en el momento de la compilación.
Usa cmd.Context() dentro de RunE (cobra lo establece en el comando).
Pasa ese contexto a las llamadas HTTP y de base de datos para cancelación.
Establece la cadena Deprecated en el comando; cobra imprime una advertencia cuando se usa.
Mantén el comando funcional hasta la versión de eliminación documentada.
El completado de PowerShell existe para cobra con scripts generados.
Prueba en los shells de destino que tus operadores usan realmente.
Versiones de Stack: Esta página fue escrita para Go 1.26.x (predeterminado GC de Green Tea, go fix modernizers - verifica el parche en la compilación), chi (última - verifica en la compilación), gin (última - verifica en la compilación), echo (última - verifica en la compilación), google.golang.org/grpc (última - verifica en la compilación), sigs.k8s.io/controller-runtime (última - verifica en la compilación), kubebuilder (última - verifica en la compilación), tinygo (última - verifica objetivos de placa en la compilación), wazero (última - verifica en la compilación), y golangci-lint (último - verifica el conjunto de linters en la compilación).
Revisado por Chris St. John·Última actualización: 16 jul 2026