From b5d1d89a377e38762a75c2042dcc50a370ba6707 Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Sun, 31 May 2020 17:35:59 +0200 Subject: Add shell completion with cobra Allow automatic generation for shell completion scripts with the internal cobra functions (requires v1.0.0+). This should replace the handwritten completion scripts and even adds support for fish. With this approach it is less likley that completions and code are out of sync. We can now create the scripts with - podman completion bash - podman completion zsh - podman completion fish To test the completion run: source <(podman completion bash) The same works for podman-remote and podman --remote and it will complete your remote containers/images with the correct endpoints values from --url/--connection. The completion logic is written in go and provided by the cobra library. The completion functions lives in `cmd/podman/completion/completion.go`. The unit test at cmd/podman/shell_completion_test.go checks if each command and flag has an autocompletion function set. This prevents that commands and flags have no shell completion set. This commit does not replace the current autocompletion scripts. Closes #6440 Signed-off-by: Paul Holzinger --- cmd/podman/system/connection/add.go | 20 ++++++++++++---- cmd/podman/system/connection/default.go | 2 ++ cmd/podman/system/connection/list.go | 6 +++-- cmd/podman/system/connection/remove.go | 2 ++ cmd/podman/system/connection/rename.go | 2 ++ cmd/podman/system/df.go | 18 +++++++++----- cmd/podman/system/events.go | 35 ++++++++++++++++++++------- cmd/podman/system/info.go | 42 ++++++++++++++++++++------------- cmd/podman/system/migrate.go | 17 ++++++++----- cmd/podman/system/prune.go | 14 ++++++----- cmd/podman/system/renumber.go | 2 ++ cmd/podman/system/reset.go | 12 ++++++---- cmd/podman/system/service.go | 20 ++++++++++------ cmd/podman/system/unshare.go | 2 ++ cmd/podman/system/varlink.go | 22 ++++++++++------- cmd/podman/system/version.go | 16 +++++++++---- 16 files changed, 157 insertions(+), 75 deletions(-) (limited to 'cmd/podman/system') diff --git a/cmd/podman/system/connection/add.go b/cmd/podman/system/connection/add.go index 0d81a64ca..b3a23bffd 100644 --- a/cmd/podman/system/connection/add.go +++ b/cmd/podman/system/connection/add.go @@ -10,6 +10,7 @@ import ( "os/user" "regexp" + "github.com/containers/common/pkg/completion" "github.com/containers/common/pkg/config" "github.com/containers/podman/v2/cmd/podman/registry" "github.com/containers/podman/v2/cmd/podman/system" @@ -34,7 +35,8 @@ var ( "destination" is of the form [user@]hostname or an URI of the form ssh://[user@]hostname[:port] `, - RunE: add, + RunE: add, + ValidArgsFunction: completion.AutocompleteNone, Example: `podman system connection add laptop server.fubar.com podman system connection add --identity ~/.ssh/dev_rsa testing ssh://root@server.fubar.com:2222 podman system connection add --identity ~/.ssh/dev_rsa --port 22 production root@server.fubar.com @@ -57,9 +59,19 @@ func init() { }) flags := addCmd.Flags() - flags.IntVarP(&cOpts.Port, "port", "p", 22, "SSH port number for destination") - flags.StringVar(&cOpts.Identity, "identity", "", "path to SSH identity file") - flags.StringVar(&cOpts.UDSPath, "socket-path", "", "path to podman socket on remote host. (default '/run/podman/podman.sock' or '/run/user/{uid}/podman/podman.sock)") + + portFlagName := "port" + flags.IntVarP(&cOpts.Port, portFlagName, "p", 22, "SSH port number for destination") + _ = addCmd.RegisterFlagCompletionFunc(portFlagName, completion.AutocompleteNone) + + identityFlagName := "identity" + flags.StringVar(&cOpts.Identity, identityFlagName, "", "path to SSH identity file") + _ = addCmd.RegisterFlagCompletionFunc(identityFlagName, completion.AutocompleteDefault) + + socketPathFlagName := "socket-path" + flags.StringVar(&cOpts.UDSPath, socketPathFlagName, "", "path to podman socket on remote host. (default '/run/podman/podman.sock' or '/run/user/{uid}/podman/podman.sock)") + _ = addCmd.RegisterFlagCompletionFunc(socketPathFlagName, completion.AutocompleteDefault) + flags.BoolVarP(&cOpts.Default, "default", "d", false, "Set connection to be default") } diff --git a/cmd/podman/system/connection/default.go b/cmd/podman/system/connection/default.go index eafcf37b2..e2ae6ae7f 100644 --- a/cmd/podman/system/connection/default.go +++ b/cmd/podman/system/connection/default.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/containers/common/pkg/config" + "github.com/containers/podman/v2/cmd/podman/common" "github.com/containers/podman/v2/cmd/podman/registry" "github.com/containers/podman/v2/cmd/podman/system" "github.com/containers/podman/v2/pkg/domain/entities" @@ -18,6 +19,7 @@ var ( Short: "Set named destination as default", Long: `Set named destination as default for the Podman service`, DisableFlagsInUseLine: true, + ValidArgsFunction: common.AutocompleteSystemConnections, RunE: defaultRunE, Example: `podman system connection default testing`, } diff --git a/cmd/podman/system/connection/list.go b/cmd/podman/system/connection/list.go index 9010ec803..b434559b4 100644 --- a/cmd/podman/system/connection/list.go +++ b/cmd/podman/system/connection/list.go @@ -5,6 +5,7 @@ import ( "text/tabwriter" "text/template" + "github.com/containers/common/pkg/completion" "github.com/containers/common/pkg/config" "github.com/containers/podman/v2/cmd/podman/registry" "github.com/containers/podman/v2/cmd/podman/system" @@ -23,8 +24,9 @@ var ( DisableFlagsInUseLine: true, Example: `podman system connection list podman system connection ls`, - RunE: list, - TraverseChildren: false, + ValidArgsFunction: completion.AutocompleteNone, + RunE: list, + TraverseChildren: false, } ) diff --git a/cmd/podman/system/connection/remove.go b/cmd/podman/system/connection/remove.go index 58674efb6..429325f50 100644 --- a/cmd/podman/system/connection/remove.go +++ b/cmd/podman/system/connection/remove.go @@ -2,6 +2,7 @@ package connection import ( "github.com/containers/common/pkg/config" + "github.com/containers/podman/v2/cmd/podman/common" "github.com/containers/podman/v2/cmd/podman/registry" "github.com/containers/podman/v2/cmd/podman/system" "github.com/containers/podman/v2/pkg/domain/entities" @@ -17,6 +18,7 @@ var ( Long: `Delete named destination from podman configuration`, Short: "Delete named destination", DisableFlagsInUseLine: true, + ValidArgsFunction: common.AutocompleteSystemConnections, RunE: rm, Example: `podman system connection remove devl podman system connection rm devl`, diff --git a/cmd/podman/system/connection/rename.go b/cmd/podman/system/connection/rename.go index bb2ca262a..7ab94d49a 100644 --- a/cmd/podman/system/connection/rename.go +++ b/cmd/podman/system/connection/rename.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/containers/common/pkg/config" + "github.com/containers/podman/v2/cmd/podman/common" "github.com/containers/podman/v2/cmd/podman/registry" "github.com/containers/podman/v2/cmd/podman/system" "github.com/containers/podman/v2/pkg/domain/entities" @@ -19,6 +20,7 @@ var ( Short: "Rename \"old\" to \"new\"", Long: `Rename destination for the Podman service from "old" to "new"`, DisableFlagsInUseLine: true, + ValidArgsFunction: common.AutocompleteSystemConnections, RunE: rename, Example: `podman system connection rename laptop devl, podman system connection mv laptop devl`, diff --git a/cmd/podman/system/df.go b/cmd/podman/system/df.go index fbdf274fb..a9eab24bb 100644 --- a/cmd/podman/system/df.go +++ b/cmd/podman/system/df.go @@ -8,6 +8,7 @@ import ( "text/template" "time" + "github.com/containers/common/pkg/completion" "github.com/containers/common/pkg/report" "github.com/containers/podman/v2/cmd/podman/parse" "github.com/containers/podman/v2/cmd/podman/registry" @@ -24,11 +25,12 @@ var ( Show podman disk usage ` dfSystemCommand = &cobra.Command{ - Use: "df [options]", - Args: validate.NoArgs, - Short: "Show podman disk usage", - Long: dfSystemDescription, - RunE: df, + Use: "df [options]", + Args: validate.NoArgs, + Short: "Show podman disk usage", + Long: dfSystemDescription, + RunE: df, + ValidArgsFunction: completion.AutocompleteNone, } ) @@ -44,7 +46,11 @@ func init() { }) flags := dfSystemCommand.Flags() flags.BoolVarP(&dfOptions.Verbose, "verbose", "v", false, "Show detailed information on disk usage") - flags.StringVar(&dfOptions.Format, "format", "", "Pretty-print images using a Go template") + + formatFlagName := "format" + flags.StringVar(&dfOptions.Format, formatFlagName, "", "Pretty-print images using a Go template") + _ = dfSystemCommand.RegisterFlagCompletionFunc(formatFlagName, completion.AutocompleteNone) + } func df(cmd *cobra.Command, args []string) error { diff --git a/cmd/podman/system/events.go b/cmd/podman/system/events.go index 368cd41a6..224ef89f3 100644 --- a/cmd/podman/system/events.go +++ b/cmd/podman/system/events.go @@ -6,7 +6,9 @@ import ( "os" "text/template" + "github.com/containers/common/pkg/completion" "github.com/containers/common/pkg/report" + "github.com/containers/podman/v2/cmd/podman/common" "github.com/containers/podman/v2/cmd/podman/registry" "github.com/containers/podman/v2/cmd/podman/validate" "github.com/containers/podman/v2/libpod/events" @@ -20,11 +22,12 @@ var ( By default, streaming mode is used, printing new events as they occur. Previous events can be listed via --since and --until.` eventsCommand = &cobra.Command{ - Use: "events [options]", - Args: validate.NoArgs, - Short: "Show podman events", - Long: eventsDescription, - RunE: eventsCmd, + Use: "events [options]", + Args: validate.NoArgs, + Short: "Show podman events", + Long: eventsDescription, + RunE: eventsCmd, + ValidArgsFunction: completion.AutocompleteNone, Example: `podman events podman events --filter event=create podman events --format {{.Image}} @@ -43,11 +46,25 @@ func init() { Command: eventsCommand, }) flags := eventsCommand.Flags() - flags.StringArrayVar(&eventOptions.Filter, "filter", []string{}, "filter output") - flags.StringVar(&eventFormat, "format", "", "format the output using a Go template") + + filterFlagName := "filter" + flags.StringArrayVar(&eventOptions.Filter, filterFlagName, []string{}, "filter output") + _ = eventsCommand.RegisterFlagCompletionFunc(filterFlagName, common.AutocompleteEventFilter) + + formatFlagName := "format" + flags.StringVar(&eventFormat, formatFlagName, "", "format the output using a Go template") + _ = eventsCommand.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteJSONFormat) + flags.BoolVar(&eventOptions.Stream, "stream", true, "stream new events; for testing only") - flags.StringVar(&eventOptions.Since, "since", "", "show all events created since timestamp") - flags.StringVar(&eventOptions.Until, "until", "", "show all events until timestamp") + + sinceFlagName := "since" + flags.StringVar(&eventOptions.Since, sinceFlagName, "", "show all events created since timestamp") + _ = eventsCommand.RegisterFlagCompletionFunc(sinceFlagName, completion.AutocompleteNone) + + untilFlagName := "until" + flags.StringVar(&eventOptions.Until, untilFlagName, "", "show all events until timestamp") + _ = eventsCommand.RegisterFlagCompletionFunc(untilFlagName, completion.AutocompleteNone) + _ = flags.MarkHidden("stream") } diff --git a/cmd/podman/system/info.go b/cmd/podman/system/info.go index dece6b37e..17aeb2940 100644 --- a/cmd/podman/system/info.go +++ b/cmd/podman/system/info.go @@ -5,13 +5,14 @@ import ( "os" "text/template" + "github.com/containers/common/pkg/completion" "github.com/containers/common/pkg/report" + "github.com/containers/podman/v2/cmd/podman/common" "github.com/containers/podman/v2/cmd/podman/registry" "github.com/containers/podman/v2/cmd/podman/validate" "github.com/containers/podman/v2/pkg/domain/entities" "github.com/ghodss/yaml" "github.com/spf13/cobra" - "github.com/spf13/pflag" ) var ( @@ -20,21 +21,23 @@ var ( Useful for the user and when reporting issues. ` infoCommand = &cobra.Command{ - Use: "info [options]", - Args: validate.NoArgs, - Long: infoDescription, - Short: "Display podman system information", - RunE: info, - Example: `podman info`, + Use: "info [options]", + Args: validate.NoArgs, + Long: infoDescription, + Short: "Display podman system information", + RunE: info, + ValidArgsFunction: completion.AutocompleteNone, + Example: `podman info`, } systemInfoCommand = &cobra.Command{ - Args: infoCommand.Args, - Use: infoCommand.Use, - Short: infoCommand.Short, - Long: infoCommand.Long, - RunE: infoCommand.RunE, - Example: `podman system info`, + Args: infoCommand.Args, + Use: infoCommand.Use, + Short: infoCommand.Short, + Long: infoCommand.Long, + RunE: infoCommand.RunE, + ValidArgsFunction: infoCommand.ValidArgsFunction, + Example: `podman system info`, } ) @@ -48,19 +51,24 @@ func init() { Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, Command: infoCommand, }) - infoFlags(infoCommand.Flags()) + infoFlags(infoCommand) registry.Commands = append(registry.Commands, registry.CliCommand{ Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, Command: systemInfoCommand, Parent: systemCmd, }) - infoFlags(systemInfoCommand.Flags()) + infoFlags(systemInfoCommand) } -func infoFlags(flags *pflag.FlagSet) { +func infoFlags(cmd *cobra.Command) { + flags := cmd.Flags() + flags.BoolVarP(&debug, "debug", "D", false, "Display additional debug information") - flags.StringVarP(&inFormat, "format", "f", "", "Change the output format to JSON or a Go template") + + formatFlagName := "format" + flags.StringVarP(&inFormat, formatFlagName, "f", "", "Change the output format to JSON or a Go template") + _ = cmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteJSONFormat) } func info(cmd *cobra.Command, args []string) error { diff --git a/cmd/podman/system/migrate.go b/cmd/podman/system/migrate.go index 7870df60b..234a49e4b 100644 --- a/cmd/podman/system/migrate.go +++ b/cmd/podman/system/migrate.go @@ -6,6 +6,7 @@ import ( "fmt" "os" + "github.com/containers/common/pkg/completion" "github.com/containers/podman/v2/cmd/podman/registry" "github.com/containers/podman/v2/cmd/podman/validate" "github.com/containers/podman/v2/pkg/domain/entities" @@ -21,11 +22,12 @@ var ( ` migrateCommand = &cobra.Command{ - Use: "migrate [options]", - Args: validate.NoArgs, - Short: "Migrate containers", - Long: migrateDescription, - Run: migrate, + Use: "migrate [options]", + Args: validate.NoArgs, + Short: "Migrate containers", + Long: migrateDescription, + Run: migrate, + ValidArgsFunction: completion.AutocompleteNone, } ) @@ -41,7 +43,10 @@ func init() { }) flags := migrateCommand.Flags() - flags.StringVar(&migrateOptions.NewRuntime, "new-runtime", "", "Specify a new runtime for all containers") + + newRuntimeFlagName := "new-runtime" + flags.StringVar(&migrateOptions.NewRuntime, newRuntimeFlagName, "", "Specify a new runtime for all containers") + _ = migrateCommand.RegisterFlagCompletionFunc(newRuntimeFlagName, completion.AutocompleteNone) } func migrate(cmd *cobra.Command, args []string) { diff --git a/cmd/podman/system/prune.go b/cmd/podman/system/prune.go index a229b06b0..be0d60604 100644 --- a/cmd/podman/system/prune.go +++ b/cmd/podman/system/prune.go @@ -7,6 +7,7 @@ import ( "os" "strings" + "github.com/containers/common/pkg/completion" "github.com/containers/podman/v2/cmd/podman/registry" "github.com/containers/podman/v2/cmd/podman/utils" "github.com/containers/podman/v2/cmd/podman/validate" @@ -25,12 +26,13 @@ var ( `) pruneCommand = &cobra.Command{ - Use: "prune [options]", - Short: "Remove unused data", - Args: validate.NoArgs, - Long: pruneDescription, - RunE: prune, - Example: `podman system prune`, + Use: "prune [options]", + Short: "Remove unused data", + Args: validate.NoArgs, + Long: pruneDescription, + RunE: prune, + ValidArgsFunction: completion.AutocompleteNone, + Example: `podman system prune`, } force bool ) diff --git a/cmd/podman/system/renumber.go b/cmd/podman/system/renumber.go index 1631ab093..b1683395f 100644 --- a/cmd/podman/system/renumber.go +++ b/cmd/podman/system/renumber.go @@ -6,6 +6,7 @@ import ( "fmt" "os" + "github.com/containers/common/pkg/completion" "github.com/containers/podman/v2/cmd/podman/registry" "github.com/containers/podman/v2/cmd/podman/validate" "github.com/containers/podman/v2/pkg/domain/entities" @@ -28,6 +29,7 @@ var ( Short: "Migrate lock numbers", Long: renumberDescription, Run: renumber, + ValidArgsFunction: completion.AutocompleteNone, } ) diff --git a/cmd/podman/system/reset.go b/cmd/podman/system/reset.go index 0b04c6ee0..d38a1a427 100644 --- a/cmd/podman/system/reset.go +++ b/cmd/podman/system/reset.go @@ -8,6 +8,7 @@ import ( "os" "strings" + "github.com/containers/common/pkg/completion" "github.com/containers/podman/v2/cmd/podman/registry" "github.com/containers/podman/v2/cmd/podman/validate" "github.com/containers/podman/v2/pkg/domain/entities" @@ -22,11 +23,12 @@ var ( All containers will be stopped and removed, and all images, volumes and container content will be removed. ` systemResetCommand = &cobra.Command{ - Use: "reset [options]", - Args: validate.NoArgs, - Short: "Reset podman storage", - Long: systemResetDescription, - Run: reset, + Use: "reset [options]", + Args: validate.NoArgs, + Short: "Reset podman storage", + Long: systemResetDescription, + Run: reset, + ValidArgsFunction: completion.AutocompleteNone, } forceFlag bool diff --git a/cmd/podman/system/service.go b/cmd/podman/system/service.go index 0476c632d..78062d135 100644 --- a/cmd/podman/system/service.go +++ b/cmd/podman/system/service.go @@ -9,6 +9,7 @@ import ( "syscall" "time" + "github.com/containers/common/pkg/completion" "github.com/containers/podman/v2/cmd/podman/registry" "github.com/containers/podman/v2/pkg/domain/entities" "github.com/containers/podman/v2/pkg/rootless" @@ -26,12 +27,13 @@ Enable a listening service for API access to Podman commands. ` srvCmd = &cobra.Command{ - Use: "service [options] [URI]", - Args: cobra.MaximumNArgs(1), - Short: "Run API service", - Long: srvDescription, - RunE: service, - Example: `podman system service --time=0 unix:///tmp/podman.sock`, + Use: "service [options] [URI]", + Args: cobra.MaximumNArgs(1), + Short: "Run API service", + Long: srvDescription, + RunE: service, + ValidArgsFunction: completion.AutocompleteDefault, + Example: `podman system service --time=0 unix:///tmp/podman.sock`, } srvArgs = struct { @@ -48,7 +50,11 @@ func init() { }) flags := srvCmd.Flags() - flags.Int64VarP(&srvArgs.Timeout, "time", "t", 5, "Time until the service session expires in seconds. Use 0 to disable the timeout") + + timeFlagName := "time" + flags.Int64VarP(&srvArgs.Timeout, timeFlagName, "t", 5, "Time until the service session expires in seconds. Use 0 to disable the timeout") + _ = srvCmd.RegisterFlagCompletionFunc(timeFlagName, completion.AutocompleteNone) + flags.BoolVar(&srvArgs.Varlink, "varlink", false, "Use legacy varlink service instead of REST. Unit of --time changes from seconds to milliseconds.") _ = flags.MarkDeprecated("varlink", "valink API is deprecated.") diff --git a/cmd/podman/system/unshare.go b/cmd/podman/system/unshare.go index 2d0113779..437cf7b2e 100644 --- a/cmd/podman/system/unshare.go +++ b/cmd/podman/system/unshare.go @@ -3,6 +3,7 @@ package system import ( "os" + "github.com/containers/common/pkg/completion" "github.com/containers/podman/v2/cmd/podman/registry" "github.com/containers/podman/v2/pkg/domain/entities" "github.com/containers/podman/v2/pkg/rootless" @@ -18,6 +19,7 @@ var ( Short: "Run a command in a modified user namespace", Long: unshareDescription, RunE: unshare, + ValidArgsFunction: completion.AutocompleteDefault, Example: `podman unshare id podman unshare cat /proc/self/uid_map, podman unshare podman-script.sh`, diff --git a/cmd/podman/system/varlink.go b/cmd/podman/system/varlink.go index 89669d51a..363ac9cca 100644 --- a/cmd/podman/system/varlink.go +++ b/cmd/podman/system/varlink.go @@ -5,6 +5,7 @@ package system import ( "time" + "github.com/containers/common/pkg/completion" "github.com/containers/podman/v2/cmd/podman/registry" "github.com/containers/podman/v2/pkg/domain/entities" "github.com/spf13/cobra" @@ -16,13 +17,14 @@ var ( Tools speaking varlink protocol can remotely manage pods, containers and images. ` varlinkCmd = &cobra.Command{ - Use: "varlink [options] [URI]", - Args: cobra.MinimumNArgs(1), - Short: "Run varlink interface", - Long: varlinkDescription, - RunE: varlinkE, - Deprecated: "Please see 'podman system service' for RESTful APIs", - Hidden: true, + Use: "varlink [options] [URI]", + Args: cobra.MinimumNArgs(1), + Short: "Run varlink interface", + Long: varlinkDescription, + RunE: varlinkE, + ValidArgsFunction: completion.AutocompleteDefault, + Deprecated: "Please see 'podman system service' for RESTful APIs", + Hidden: true, Example: `podman varlink unix:/run/podman/io.podman podman varlink --time 5000 unix:/run/podman/io.podman`, } @@ -37,7 +39,11 @@ func init() { Command: varlinkCmd, }) flags := varlinkCmd.Flags() - flags.Int64VarP(&varlinkArgs.Timeout, "time", "t", 1000, "Time until the varlink session expires in milliseconds. Use 0 to disable the timeout") + + timeFlagName := "time" + flags.Int64VarP(&varlinkArgs.Timeout, timeFlagName, "t", 1000, "Time until the varlink session expires in milliseconds. Use 0 to disable the timeout") + _ = varlinkCmd.RegisterFlagCompletionFunc(timeFlagName, completion.AutocompleteNone) + flags.SetNormalizeFunc(aliasTimeoutFlag) } diff --git a/cmd/podman/system/version.go b/cmd/podman/system/version.go index b790a7511..cb7206b8a 100644 --- a/cmd/podman/system/version.go +++ b/cmd/podman/system/version.go @@ -8,7 +8,9 @@ import ( "text/tabwriter" "text/template" + "github.com/containers/common/pkg/completion" "github.com/containers/common/pkg/report" + "github.com/containers/podman/v2/cmd/podman/common" "github.com/containers/podman/v2/cmd/podman/registry" "github.com/containers/podman/v2/cmd/podman/validate" "github.com/containers/podman/v2/libpod/define" @@ -18,10 +20,11 @@ import ( var ( versionCommand = &cobra.Command{ - Use: "version [options]", - Args: validate.NoArgs, - Short: "Display the Podman Version Information", - RunE: version, + Use: "version [options]", + Args: validate.NoArgs, + Short: "Display the Podman Version Information", + RunE: version, + ValidArgsFunction: completion.AutocompleteNone, } versionFormat string ) @@ -32,7 +35,10 @@ func init() { Command: versionCommand, }) flags := versionCommand.Flags() - flags.StringVarP(&versionFormat, "format", "f", "", "Change the output format to JSON or a Go template") + + formatFlagName := "format" + flags.StringVarP(&versionFormat, formatFlagName, "f", "", "Change the output format to JSON or a Go template") + _ = versionCommand.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteJSONFormat) } func version(cmd *cobra.Command, args []string) error { -- cgit v1.2.3-54-g00ecf