Skip to content

Commit 2b9a4d5

Browse files
committed
cli/command/context: use errors.Join
Use stdlib multi-errors instead of creating our own; also touch-up one error and some minor cleanups. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
1 parent 150f27b commit 2b9a4d5

3 files changed

Lines changed: 23 additions & 28 deletions

File tree

cli/command/context/options.go

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
package context
22

33
import (
4+
"errors"
5+
"fmt"
46
"strconv"
5-
"strings"
67

78
"github.com/docker/cli/cli/context"
89
"github.com/docker/cli/cli/context/docker"
910
"github.com/docker/cli/cli/context/store"
1011
"github.com/docker/docker/client"
11-
"github.com/pkg/errors"
1212
)
1313

1414
const (
@@ -68,20 +68,17 @@ func parseBool(config map[string]string, name string) (bool, error) {
6868
return false, nil
6969
}
7070
res, err := strconv.ParseBool(strVal)
71-
return res, errors.Wrap(err, name)
71+
return res, fmt.Errorf("name: %w", err)
7272
}
7373

7474
func validateConfig(config map[string]string, allowedKeys map[string]struct{}) error {
75-
var errs []string
75+
var errs []error
7676
for k := range config {
7777
if _, ok := allowedKeys[k]; !ok {
78-
errs = append(errs, "unrecognized config key: "+k)
78+
errs = append(errs, errors.New("unrecognized config key: "+k))
7979
}
8080
}
81-
if len(errs) == 0 {
82-
return nil
83-
}
84-
return errors.New(strings.Join(errs, "\n"))
81+
return errors.Join(errs...)
8582
}
8683

8784
func getDockerEndpoint(contextStore store.Reader, config map[string]string) (docker.Endpoint, error) {
@@ -96,7 +93,7 @@ func getDockerEndpoint(contextStore store.Reader, config map[string]string) (doc
9693
if ep, ok := metadata.Endpoints[docker.DockerEndpoint].(docker.EndpointMeta); ok {
9794
return docker.Endpoint{EndpointMeta: ep}, nil
9895
}
99-
return docker.Endpoint{}, errors.Errorf("unable to get endpoint from context %q", contextName)
96+
return docker.Endpoint{}, fmt.Errorf("unable to get endpoint from context %q", contextName)
10097
}
10198
tlsData, err := context.TLSDataFromFiles(config[keyCA], config[keyCert], config[keyKey])
10299
if err != nil {
@@ -116,10 +113,11 @@ func getDockerEndpoint(contextStore store.Reader, config map[string]string) (doc
116113
// try to resolve a docker client, validating the configuration
117114
opts, err := ep.ClientOpts()
118115
if err != nil {
119-
return docker.Endpoint{}, errors.Wrap(err, "invalid docker endpoint options")
116+
return docker.Endpoint{}, fmt.Errorf("invalid docker endpoint options: %w", err)
120117
}
118+
// FIXME(thaJeztah): this creates a new client (but discards it) only to validate the options; are the validation steps above not enough?
121119
if _, err := client.NewClientWithOpts(opts...); err != nil {
122-
return docker.Endpoint{}, errors.Wrap(err, "unable to apply docker endpoint options")
120+
return docker.Endpoint{}, fmt.Errorf("unable to apply docker endpoint options: %w", err)
123121
}
124122
return ep, nil
125123
}

cli/command/context/remove.go

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
package context
22

33
import (
4+
"errors"
45
"fmt"
56
"os"
6-
"strings"
77

88
"github.com/docker/cli/cli"
99
"github.com/docker/cli/cli/command"
1010
"github.com/docker/docker/errdefs"
11-
"github.com/pkg/errors"
1211
"github.com/spf13/cobra"
1312
)
1413

@@ -33,28 +32,25 @@ func newRemoveCommand(dockerCli command.Cli) *cobra.Command {
3332
}
3433

3534
// RunRemove removes one or more contexts
36-
func RunRemove(dockerCli command.Cli, opts RemoveOptions, names []string) error {
37-
var errs []string
38-
currentCtx := dockerCli.CurrentContext()
35+
func RunRemove(dockerCLI command.Cli, opts RemoveOptions, names []string) error {
36+
var errs []error
37+
currentCtx := dockerCLI.CurrentContext()
3938
for _, name := range names {
4039
if name == "default" {
41-
errs = append(errs, `default: context "default" cannot be removed`)
42-
} else if err := doRemove(dockerCli, name, name == currentCtx, opts.Force); err != nil {
43-
errs = append(errs, err.Error())
40+
errs = append(errs, errors.New(`context "default" cannot be removed`))
41+
} else if err := doRemove(dockerCLI, name, name == currentCtx, opts.Force); err != nil {
42+
errs = append(errs, err)
4443
} else {
45-
fmt.Fprintln(dockerCli.Out(), name)
44+
_, _ = fmt.Fprintln(dockerCLI.Out(), name)
4645
}
4746
}
48-
if len(errs) > 0 {
49-
return errors.New(strings.Join(errs, "\n"))
50-
}
51-
return nil
47+
return errors.Join(errs...)
5248
}
5349

5450
func doRemove(dockerCli command.Cli, name string, isCurrent, force bool) error {
5551
if isCurrent {
5652
if !force {
57-
return errors.Errorf("context %q is in use, set -f flag to force remove", name)
53+
return fmt.Errorf("context %q is in use, set -f flag to force remove", name)
5854
}
5955
// fallback to DOCKER_HOST
6056
cfg := dockerCli.ConfigFile()
@@ -65,6 +61,7 @@ func doRemove(dockerCli command.Cli, name string, isCurrent, force bool) error {
6561
}
6662

6763
if !force {
64+
// TODO(thaJeztah): instead of checking before removing, can we make ContextStore().Remove() return a proper errdef and ignore "not found" errors?
6865
if err := checkContextExists(dockerCli, name); err != nil {
6966
return err
7067
}
@@ -77,7 +74,7 @@ func checkContextExists(dockerCli command.Cli, name string) error {
7774
contextDir := dockerCli.ContextStore().GetStorageInfo(name).MetadataPath
7875
_, err := os.Stat(contextDir)
7976
if os.IsNotExist(err) {
80-
return errdefs.NotFound(errors.Errorf("context %q does not exist", name))
77+
return errdefs.NotFound(fmt.Errorf("context %q does not exist", name))
8178
}
8279
// Ignore other errors; if relevant, they will produce an error when
8380
// performing the actual delete.

cli/command/context/remove_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,5 +60,5 @@ func TestRemoveDefault(t *testing.T) {
6060
createTestContext(t, cli, "other", nil)
6161
cli.SetCurrentContext("current")
6262
err := RunRemove(cli, RemoveOptions{}, []string{"default"})
63-
assert.ErrorContains(t, err, `default: context "default" cannot be removed`)
63+
assert.ErrorContains(t, err, `context "default" cannot be removed`)
6464
}

0 commit comments

Comments
 (0)