diff --git a/cli/cmd/context/rm.go b/cli/cmd/context/rm.go index 7d972e98..a909d3d9 100644 --- a/cli/cmd/context/rm.go +++ b/cli/cmd/context/rm.go @@ -20,12 +20,13 @@ import ( "context" "errors" "fmt" + "strings" + "github.com/hashicorp/go-multierror" "github.com/spf13/cobra" apicontext "github.com/docker/api/context" "github.com/docker/api/context/store" - "github.com/docker/api/multierror" ) type removeOpts struct { @@ -56,8 +57,7 @@ func runRemove(ctx context.Context, args []string, force bool) error { for _, contextName := range args { if currentContext == contextName { if force { - err := runUse(ctx, "default") - if err != nil { + if err := runUse(ctx, "default"); err != nil { errs = multierror.Append(errs, errors.New("cannot delete current context")) } else { errs = removeContext(s, contextName, errs) @@ -69,9 +69,20 @@ func runRemove(ctx context.Context, args []string, force bool) error { errs = removeContext(s, contextName, errs) } } + if errs != nil { + errs.ErrorFormat = formatErrors + } return errs.ErrorOrNil() } +func formatErrors(errs []error) string { + messages := make([]string, len(errs)) + for i, err := range errs { + messages[i] = "Error: "+err.Error() + } + return strings.Join(messages, "\n") +} + func removeContext(s store.Store, n string, errs *multierror.Error) *multierror.Error { if err := s.Remove(n); err != nil { errs = multierror.Append(errs, err) diff --git a/cli/cmd/rm.go b/cli/cmd/rm.go index 06ad878a..06ad0a8a 100644 --- a/cli/cmd/rm.go +++ b/cli/cmd/rm.go @@ -19,14 +19,15 @@ package cmd import ( "context" "fmt" + "strings" + "github.com/hashicorp/go-multierror" "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/docker/api/client" "github.com/docker/api/containers" "github.com/docker/api/errdefs" - "github.com/docker/api/multierror" ) type rmOpts struct { @@ -75,6 +76,16 @@ func runRm(ctx context.Context, args []string, opts rmOpts) error { fmt.Println(id) } - + if errs != nil { + errs.ErrorFormat = formatErrors + } return errs.ErrorOrNil() } + +func formatErrors(errs []error) string { + messages := make([]string, len(errs)) + for i, err := range errs { + messages[i] = "Error: "+err.Error() + } + return strings.Join(messages, "\n") +} diff --git a/multierror/multierror.go b/multierror/multierror.go deleted file mode 100644 index 2b112dad..00000000 --- a/multierror/multierror.go +++ /dev/null @@ -1,108 +0,0 @@ -/* - Copyright 2020 Docker, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package multierror - -import ( - "strings" - - "github.com/hashicorp/go-multierror" -) - -// Error wraps a multierror.Error and defines a default -// formatting function that fits cli needs -type Error struct { - err *multierror.Error -} - -func (e *Error) Error() string { - if e == nil || e.err == nil { - return "" - } - e.err.ErrorFormat = listErrorFunc - return e.err.Error() -} - -// WrappedErrors returns the list of errors that this Error is wrapping. -// It is an implementation of the errwrap.Wrapper interface so that -// multierror.Error can be used with that library. -// -// This method is not safe to be called concurrently and is no different -// than accessing the Errors field directly. It is implemented only to -// satisfy the errwrap.Wrapper interface. -func (e *Error) WrappedErrors() []error { - return e.err.WrappedErrors() -} - -// Unwrap returns an error from Error (or nil if there are no errors) -func (e *Error) Unwrap() error { - if e == nil || e.err == nil { - return nil - } - return e.err.Unwrap() -} - -// ErrorOrNil returns an error interface if this Error represents -// a list of errors, or returns nil if the list of errors is empty. This -// function is useful at the end of accumulation to make sure that the value -// returned represents the existence of errors. -func (e *Error) ErrorOrNil() error { - if e == nil || e.err == nil { - return nil - } - if len(e.err.Errors) == 0 { - return nil - } - - return e -} - -// Append adds an error to a multierror, if err is -// not a multierror it will be converted to one -func Append(err error, errs ...error) *Error { - switch err := err.(type) { - case *Error: - if err == nil { - err = new(Error) - } - for _, e := range errs { - err.err = multierror.Append(err.err, e) - } - return err - default: - newErrs := make([]error, 0, len(errs)+1) - if err != nil { - newErrs = append(newErrs, err) - } - newErrs = append(newErrs, errs...) - - return Append(&Error{}, newErrs...) - } -} - -func listErrorFunc(errs []error) string { - if len(errs) == 1 { - return "Error: " + errs[0].Error() - } - - messages := make([]string, len(errs)) - - for i, err := range errs { - messages[i] = "Error: " + err.Error() - } - - return strings.Join(messages, "\n") -} diff --git a/multierror/multierror_test.go b/multierror/multierror_test.go deleted file mode 100644 index 1d2c58c3..00000000 --- a/multierror/multierror_test.go +++ /dev/null @@ -1,65 +0,0 @@ -/* - Copyright 2020 Docker, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package multierror - -import ( - "errors" - "testing" - - "gotest.tools/v3/assert" - "gotest.tools/v3/assert/cmp" -) - -func TestSingleError(t *testing.T) { - var err *Error - err = Append(err, errors.New("error")) - assert.Assert(t, cmp.Len(err.WrappedErrors(), 1)) -} - -func TestGoError(t *testing.T) { - var err error - result := Append(err, errors.New("error")) - assert.Assert(t, cmp.Len(result.WrappedErrors(), 1)) -} - -func TestMultiError(t *testing.T) { - var err *Error - err = Append(err, - errors.New("first"), - errors.New("second"), - ) - assert.Assert(t, cmp.Len(err.WrappedErrors(), 2)) - assert.Error(t, err, "Error: first\nError: second") -} - -func TestUnwrap(t *testing.T) { - var err *Error - assert.NilError(t, errors.Unwrap(err)) - - err = Append(err, errors.New("first")) - e := errors.Unwrap(err) - assert.Error(t, e, "first") -} - -func TestErrorOrNil(t *testing.T) { - var err *Error - assert.NilError(t, err.ErrorOrNil()) - - err = Append(err, errors.New("error")) - e := err.ErrorOrNil() - assert.Error(t, e, "Error: error") -}