8000 opts: ListOpts: implement cobra.SliceValue to fix shell completion by thaJeztah · Pull Request #6030 · docker/cli · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

opts: ListOpts: implement cobra.SliceValue to fix shell completion #6030

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 23, 2025

Conversation

thaJeztah
Copy link
Member
@thaJeztah thaJeztah commented Apr 23, 2025

Cobra's shell completion has specific rules to decide whether a flag can be accepted multiple times. If a flag does not meet that rule, it only completes the flag name once; some of those rules depend on the "type" of the option to end with "Array" or "Slice", which most of our options don't.

Starting with Cobra 1.9, it also checks whether an option implements the cobra.SliceValue interface (see spf13/cobra 2210).

This patch implements the cobra.SliceValue interface on ListOpts, so that these options can be completed multiple times.

In a follow-up, we can update our code to replace our uses of GetAll(), which is identical with the GetSlice() method, and potentially deprecate the old method.

Before this patch, ListOpts would only be completed once when completing flag names. For example, the following would show the --label flag the first time, but omit it if a --label flag was already set;

docker run--l<TAB>
--label                  (Set meta data on a container)  --link-local-ip  (Container IPv4/IPv6 link-local addresses)
--label-file  (Read in a line delimited file of labels)  --log-driver             (Logging driver for the container)
--link                  (Add link to another container)  --log-opt                              (Log driver options)

docker run --label hello --l<TAB>
--label-file  (Read in a line delimited file of labels)  --link-local-ip  (Container IPv4/IPv6 link-local addresses)  --log-opt  (Log driver options)
--link                  (Add link to another container)  --log-driver             (Logging driver for the container)

With this patch, the completion script correctly identifies the --label flag to be accepted multiple times, and also completes it when already set;

docker run --label hello --l<TAB>
--label                  (Set meta data on a container)  --link-local-ip  (Container IPv4/IPv6 link-local addresses)
--label-file  (Read in a line delimited file of labels)  --log-driver             (Logging driver for the container)
--link                  (Add link to another container)  --log-opt                              (Log driver options)

- Human readable description for the release notes

Fix shell-completion to only complete some flags once, even though they can be set multiple times.

- A picture of a cute animal (not mandatory but encouraged)

@codecov-commenter
Copy link
codecov-commenter commented Apr 23, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 58.90%. Comparing base (61c6818) to head (572e3f1).

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #6030   +/-   ##
=======================================
  Coverage   58.89%   58.90%           
=======================================
  Files         358      358           
  Lines       29962    29964    +2     
=======================================
+ Hits        17647    17649    +2     
  Misses      11334    11334           
  Partials      981      981           
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Cobra's shell completion has specific rules to decide whether a flag can
be accepted multiple times. If a flag does not meet that rule, it only
completes the flag name once; some of those rules depend on the "type"
of the option to end with "Array" or "Slice", which most of our options
don't.

Starting with Cobra 1.9, it also checks whether an option implements
the [cobra.SliceValue] interface (see [spf13/cobra 2210]).

This patch implements the [cobra.SliceValue] interface on ListOpts, so
that these options can be completed multiple times.

In a follow-up, we can update our code to replace our uses of `GetAll()`,
which is identical with the `GetSlice()` method, and potentially deprecate
the old method.

Before this patch, ListOpts would only be completed once when completing
flag names. For example, the following would show the `--label` flag the
first time, but omit it if a `--label` flag was already set;

    docker run--l<TAB>
    --label                  (Set meta data on a container)  --link-local-ip  (Container IPv4/IPv6 link-local addresses)
    --label-file  (Read in a line delimited file of labels)  --log-driver             (Logging driver for the container)
    --link                  (Add link to another container)  --log-opt                              (Log driver options)

    docker run --label hello --l<TAB>
    --label-file  (Read in a line delimited file of labels)  --link-local-ip  (Container IPv4/IPv6 link-local addresses)  --log-opt  (Log driver options)
    --link                  (Add link to another container)  --log-driver             (Logging driver for the container)

With this patch, the completion script correctly identifies the `--label`
flag to be accepted multiple times, and also completes it when already
set;

    docker run --label hello --l<TAB>
    --label                  (Set meta data on a container)  --link-local-ip  (Container IPv4/IPv6 link-local addresses)
    --label-file  (Read in a line delimited file of labels)  --log-driver             (Logging driver for the container)
    --link                  (Add link to another container)  --log-opt                              (Log driver options)

[cobra.SliceValue]: https://pkg.go.dev/github.com/spf13/cobra@v1.9.1#SliceValue
[spf13/cobra 2210]: spf13/cobra#2210

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
@@ -145,12 +146,13 @@ func TestListOptsWithoutValidator(t *testing.T) {
if o.String() != "[bar bar]" {
t.Errorf("%s != [bar bar]", o.String())
}
listOpts := o.GetAll()
if len(listOpts) != 2 || listOpts[0] != "bar" || listOpts[1] != "bar" {
if listOpts := o.GetAll(); len(listOpts) != 2 || listOpts[0] != "bar" || listOpts[1] != "bar" {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A DeepEqual might make this easier to read, and avoid the nolint? The is is already imported anyway. I've not tried it, but something like ...

assert.Check(t, is.DeepEqual(o.GetAll(), []string{"bar", "bar"}))

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, yes, I want to have a look at this file, as there's more to fix in that area, so for now I chose to "mostly" keep it as-is.

Will likely do some follow-ups to modernise tests in this package a bit.

@thaJeztah thaJeztah merged commit 81a5db6 into docker:master Apr 23, 2025
90 checks passed
@thaJeztah thaJeztah deleted the flag_multiple_completion branch April 23, 2025 11:51
@thaJeztah thaJeztah modified the milestones: 28.1.2, 28.2.0 May 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants
0