Merge pull request #6448 from thaJeztah/cleanup_completion

cli/command/completion: change signatures to return a cobra.CompletionFunc
This commit is contained in:
Sebastiaan van Stijn
2025-09-10 15:08:18 +02:00
committed by GitHub
17 changed files with 39 additions and 33 deletions

View File

@ -116,14 +116,16 @@ func NetworkNames(dockerCLI APIClientProvider) cobra.CompletionFunc {
// export MY_VAR=hello
// docker run --rm --env MY_VAR alpine printenv MY_VAR
// hello
func EnvVarNames(_ *cobra.Command, _ []string, _ string) (names []string, _ cobra.ShellCompDirective) {
envs := os.Environ()
names = make([]string, 0, len(envs))
for _, env := range envs {
name, _, _ := strings.Cut(env, "=")
names = append(names, name)
func EnvVarNames() cobra.CompletionFunc {
return func(_ *cobra.Command, _ []string, _ string) (names []string, _ cobra.ShellCompDirective) {
envs := os.Environ()
names = make([]string, 0, len(envs))
for _, env := range envs {
name, _, _ := strings.Cut(env, "=")
names = append(names, name)
}
return names, cobra.ShellCompDirectiveNoFileComp
}
return names, cobra.ShellCompDirectiveNoFileComp
}
// FromList offers completion for the given list of options.
@ -134,8 +136,10 @@ func FromList(options ...string) cobra.CompletionFunc {
// FileNames is a convenience function to use [cobra.ShellCompDirectiveDefault],
// which indicates to let the shell perform its default behavior after
// completions have been provided.
func FileNames(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
return nil, cobra.ShellCompDirectiveDefault
func FileNames() cobra.CompletionFunc {
return func(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
return nil, cobra.ShellCompDirectiveDefault
}
}
var commonPlatforms = []string{
@ -175,6 +179,8 @@ var commonPlatforms = []string{
// - we currently exclude architectures that may have unofficial builds,
// but don't have wide adoption (and no support), such as loong64, mipsXXX,
// ppc64 (non-le) to prevent confusion.
func Platforms(_ *cobra.Command, _ []string, _ string) (platforms []string, _ cobra.ShellCompDirective) {
return commonPlatforms, cobra.ShellCompDirectiveNoFileComp
func Platforms() cobra.CompletionFunc {
return func(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
return commonPlatforms, cobra.ShellCompDirectiveNoFileComp
}
}

View File

@ -176,7 +176,7 @@ func TestCompleteEnvVarNames(t *testing.T) {
"ENV_A": "hello-a",
"ENV_B": "hello-b",
})
values, directives := EnvVarNames(nil, nil, "")
values, directives := EnvVarNames()(nil, nil, "")
assert.Check(t, is.Equal(directives&cobra.ShellCompDirectiveNoFileComp, cobra.ShellCompDirectiveNoFileComp), "Should not perform file completion")
sort.Strings(values)
@ -185,7 +185,7 @@ func TestCompleteEnvVarNames(t *testing.T) {
}
func TestCompleteFileNames(t *testing.T) {
values, directives := FileNames(nil, nil, "")
values, directives := FileNames()(nil, nil, "")
assert.Check(t, is.Equal(directives, cobra.ShellCompDirectiveDefault))
assert.Check(t, is.Len(values, 0))
}
@ -304,7 +304,7 @@ func TestCompleteNetworkNames(t *testing.T) {
}
func TestCompletePlatforms(t *testing.T) {
values, directives := Platforms(nil, nil, "")
values, directives := Platforms()(nil, nil, "")
assert.Check(t, is.Equal(directives&cobra.ShellCompDirectiveNoFileComp, cobra.ShellCompDirectiveNoFileComp), "Should not perform file completion")
assert.Check(t, is.DeepEqual(values, commonPlatforms))
}

View File

@ -122,15 +122,15 @@ func addCompletions(cmd *cobra.Command, dockerCLI completion.APIClientProvider)
_ = cmd.RegisterFlagCompletionFunc("cap-add", completeLinuxCapabilityNames)
_ = cmd.RegisterFlagCompletionFunc("cap-drop", completeLinuxCapabilityNames)
_ = cmd.RegisterFlagCompletionFunc("cgroupns", completeCgroupns())
_ = cmd.RegisterFlagCompletionFunc("env", completion.EnvVarNames)
_ = cmd.RegisterFlagCompletionFunc("env-file", completion.FileNames)
_ = cmd.RegisterFlagCompletionFunc("env", completion.EnvVarNames())
_ = cmd.RegisterFlagCompletionFunc("env-file", completion.FileNames())
_ = cmd.RegisterFlagCompletionFunc("ipc", completeIpc(dockerCLI))
_ = cmd.RegisterFlagCompletionFunc("link", completeLink(dockerCLI))
_ = cmd.RegisterFlagCompletionFunc("log-driver", completeLogDriver(dockerCLI))
_ = cmd.RegisterFlagCompletionFunc("log-opt", completeLogOpt)
_ = cmd.RegisterFlagCompletionFunc("network", completion.NetworkNames(dockerCLI))
_ = cmd.RegisterFlagCompletionFunc("pid", completePid(dockerCLI))
_ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms)
_ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms())
_ = cmd.RegisterFlagCompletionFunc("pull", completion.FromList(PullImageAlways, PullImageMissing, PullImageNever))
_ = cmd.RegisterFlagCompletionFunc("restart", completeRestartPolicies)
_ = cmd.RegisterFlagCompletionFunc("security-opt", completeSecurityOpt)

View File

@ -88,7 +88,7 @@ func newCreateCommand(dockerCLI command.Cli) *cobra.Command {
// TODO(thaJeztah): consider adding platform as "image create option" on containerOptions
addPlatformFlag(flags, &options.platform)
_ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms)
_ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms())
flags.BoolVar(&options.untrusted, "disable-content-trust", !dockerCLI.ContentTrustEnabled(), "Skip image verification")
copts = addFlags(flags)

View File

@ -78,8 +78,8 @@ func newExecCommand(dockerCLI command.Cli) *cobra.Command {
flags.StringVarP(&options.Workdir, "workdir", "w", "", "Working directory inside the container")
flags.SetAnnotation("workdir", "version", []string{"1.35"})
_ = cmd.RegisterFlagCompletionFunc("env", completion.EnvVarNames)
_ = cmd.RegisterFlagCompletionFunc("env-file", completion.FileNames)
_ = cmd.RegisterFlagCompletionFunc("env", completion.EnvVarNames())
_ = cmd.RegisterFlagCompletionFunc("env-file", completion.FileNames())
return cmd
}

View File

@ -21,7 +21,7 @@ func newImportCommand(dockerCLI command.Cli) *cobra.Command {
return runImport(dockerCLI, args[0], args[1])
},
// TODO(thaJeztah): this should also include "-"
ValidArgsFunction: completion.FileNames,
ValidArgsFunction: completion.FileNames(),
DisableFlagsInUseLine: true,
}
return cmd

View File

@ -157,7 +157,7 @@ func newBuildCommand(dockerCLI command.Cli) *cobra.Command {
flags.SetAnnotation("squash", "experimental", nil)
flags.SetAnnotation("squash", "version", []string{"1.25"})
_ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms)
_ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms())
return cmd
}

View File

@ -52,7 +52,7 @@ func newHistoryCommand(dockerCLI command.Cli) *cobra.Command {
flags.StringVar(&opts.platform, "platform", "", `Show history for the given platform. Formatted as "os[/arch[/variant]]" (e.g., "linux/amd64")`)
_ = flags.SetAnnotation("platform", "version", []string{"1.48"})
_ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms)
_ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms())
return cmd
}

View File

@ -49,7 +49,7 @@ func newImportCommand(dockerCLI command.Cli) *cobra.Command {
flags.VarP(&options.changes, "change", "c", "Apply Dockerfile instruction to the created image")
flags.StringVarP(&options.message, "message", "m", "", "Set commit message for imported image")
addPlatformFlag(flags, &options.platform)
_ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms)
_ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms())
return cmd
}

View File

@ -52,7 +52,7 @@ If the image or the server is not multi-platform capable, the command will error
'os[/arch[/variant]]': Explicit platform (eg. linux/amd64)`)
flags.SetAnnotation("platform", "version", []string{"1.49"})
_ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms)
_ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms())
return cmd
}

View File

@ -48,7 +48,7 @@ func newLoadCommand(dockerCLI command.Cli) *cobra.Command {
flags.StringSliceVar(&opts.platform, "platform", []string{}, `Load only the given platform(s). Formatted as a comma-separated list of "os[/arch[/variant]]" (e.g., "linux/amd64,linux/arm64/v8").`)
_ = flags.SetAnnotation("platform", "version", []string{"1.48"})
_ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms)
_ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms())
return cmd
}

View File

@ -52,7 +52,7 @@ func newPullCommand(dockerCLI command.Cli) *cobra.Command {
addPlatformFlag(flags, &opts.platform)
flags.BoolVar(&opts.untrusted, "disable-content-trust", !dockerCLI.ContentTrustEnabled(), "Skip image verification")
_ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms)
_ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms())
return cmd
}

View File

@ -69,7 +69,7 @@ Image index won't be pushed, meaning that other manifests, including attestation
'os[/arch[/variant]]': Explicit platform (eg. linux/amd64)`)
flags.SetAnnotation("platform", "version", []string{"1.46"})
_ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms)
_ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms())
return cmd
}

View File

@ -47,7 +47,7 @@ func newRemoveCommand(dockerCLI command.Cli) *cobra.Command {
flags.StringSliceVar(&options.platforms, "platform", nil, `Remove only the given platform variant. Formatted as "os[/arch[/variant]]" (e.g., "linux/amd64")`)
_ = flags.SetAnnotation("platform", "version", []string{"1.50"})
_ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms)
_ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms())
return cmd
}

View File

@ -47,7 +47,7 @@ func newSaveCommand(dockerCLI command.Cli) *cobra.Command {
flags.StringSliceVar(&opts.platform, "platform", []string{}, `Save only the given platform(s). Formatted as a comma-separated list of "os[/arch[/variant]]" (e.g., "linux/amd64,linux/arm64/v8")`)
_ = flags.SetAnnotation("platform", "version", []string{"1.48"})
_ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms)
_ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms())
return cmd
}

View File

@ -82,8 +82,8 @@ func newCreateCommand(dockerCLI command.Cli) *cobra.Command {
// _ = cmd.RegisterFlagCompletionFunc(flagStopSignal, completeSignals)
_ = cmd.RegisterFlagCompletionFunc(flagMode, completion.FromList("replicated", "global", "replicated-job", "global-job"))
_ = cmd.RegisterFlagCompletionFunc(flagEnv, completion.EnvVarNames) // TODO(thaJeztah): flagEnvRemove (needs to read current env-vars on the service)
_ = cmd.RegisterFlagCompletionFunc(flagEnvFile, completion.FileNames)
_ = cmd.RegisterFlagCompletionFunc(flagEnv, completion.EnvVarNames()) // TODO(thaJeztah): flagEnvRemove (needs to read current env-vars on the service)
_ = cmd.RegisterFlagCompletionFunc(flagEnvFile, completion.FileNames())
_ = cmd.RegisterFlagCompletionFunc(flagNetwork, completion.NetworkNames(dockerCLI))
_ = cmd.RegisterFlagCompletionFunc(flagRestartCondition, completion.FromList("none", "on-failure", "any"))
_ = cmd.RegisterFlagCompletionFunc(flagRollbackOrder, completion.FromList("start-first", "stop-first"))

View File

@ -121,7 +121,7 @@ func newUpdateCommand(dockerCLI command.Cli) *cobra.Command {
// _ = cmd.RegisterFlagCompletionFunc(flagCapDrop, completeLinuxCapabilityNames)
// _ = cmd.RegisterFlagCompletionFunc(flagStopSignal, completeSignals)
_ = cmd.RegisterFlagCompletionFunc(flagEnvAdd, completion.EnvVarNames)
_ = cmd.RegisterFlagCompletionFunc(flagEnvAdd, completion.EnvVarNames())
// TODO(thaJeztah): flagEnvRemove (needs to read current env-vars on the service)
_ = cmd.RegisterFlagCompletionFunc("image", completion.ImageNames(dockerCLI, -1))
_ = cmd.RegisterFlagCompletionFunc(flagNetworkAdd, completion.NetworkNames(dockerCLI))