From 35779176e8297b00e85da343c1046bf01f4a002d Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Tue, 26 Sep 2023 00:57:12 +0200 Subject: [PATCH] deps: remove deprecated github.com/pkg/errors Signed-off-by: Matthieu MOREL --- .golangci.yml | 6 ++++++ cmd/compose/compose.go | 2 +- cmd/compose/ps.go | 2 +- cmd/compose/scale.go | 6 +++--- cmd/compose/watch.go | 4 ++-- cmd/formatter/formatter.go | 4 +--- go.mod | 5 ++--- internal/sync/tar.go | 6 +++--- internal/sync/writer_test.go | 4 ++-- internal/tracing/docker_context.go | 8 ++++---- internal/tracing/tracing.go | 2 +- pkg/api/dryrunclient.go | 2 +- pkg/api/errors.go | 2 +- pkg/api/errors_test.go | 11 ++++++----- pkg/compose/attach.go | 4 +++- pkg/compose/build_classic.go | 23 ++++++++++++----------- pkg/compose/compose.go | 5 ++--- pkg/compose/convergence.go | 4 ++-- pkg/compose/cp.go | 6 +++--- pkg/compose/create.go | 9 ++++----- pkg/compose/dependencies.go | 5 ++--- pkg/compose/down.go | 5 ++--- pkg/compose/errors.go | 3 +-- pkg/compose/exec.go | 4 +++- pkg/compose/logs.go | 7 +++++-- pkg/compose/pull.go | 2 +- pkg/compose/push.go | 4 ++-- pkg/compose/start.go | 4 ++-- pkg/compose/watch.go | 2 +- pkg/e2e/framework.go | 4 ++-- pkg/e2e/pause_test.go | 5 ++++- pkg/e2e/up_test.go | 4 +++- pkg/remote/git.go | 5 ++--- pkg/remote/oci.go | 3 +-- pkg/watch/notify.go | 2 +- pkg/watch/paths.go | 4 +--- pkg/watch/watcher_darwin.go | 4 ++-- pkg/watch/watcher_naive.go | 19 +++++++++---------- pkg/watch/watcher_naive_test.go | 4 ++-- 39 files changed, 106 insertions(+), 99 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index b32b091f716..836fca50959 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -7,6 +7,7 @@ linters: enable: - depguard - errcheck + - errorlint - gocritic - gocyclo - gofmt @@ -40,6 +41,11 @@ linters-settings: desc: 'compose-go uses yaml.v3' gomodguard: blocked: + modules: + - github.com/pkg/errors: + recommendations: + - errors + - fmt versions: - github.com/distribution/distribution: reason: "use distribution/reference" diff --git a/cmd/compose/compose.go b/cmd/compose/compose.go index 383440da631..763b5cf267d 100644 --- a/cmd/compose/compose.go +++ b/cmd/compose/compose.go @@ -18,6 +18,7 @@ package compose import ( "context" + "errors" "fmt" "os" "os/signal" @@ -37,7 +38,6 @@ import ( "github.com/docker/cli/cli/command" "github.com/docker/compose/v2/pkg/remote" "github.com/morikuni/aec" - "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/pflag" diff --git a/cmd/compose/ps.go b/cmd/compose/ps.go index ad7c5cd262f..eed22aee72f 100644 --- a/cmd/compose/ps.go +++ b/cmd/compose/ps.go @@ -18,6 +18,7 @@ package compose import ( "context" + "errors" "fmt" "sort" "strings" @@ -29,7 +30,6 @@ import ( "github.com/docker/cli/cli/command" cliformatter "github.com/docker/cli/cli/command/formatter" cliflags "github.com/docker/cli/cli/flags" - "github.com/pkg/errors" "github.com/spf13/cobra" ) diff --git a/cmd/compose/scale.go b/cmd/compose/scale.go index 5c8142c7390..63ab1414a2d 100644 --- a/cmd/compose/scale.go +++ b/cmd/compose/scale.go @@ -18,13 +18,13 @@ package compose import ( "context" + "fmt" "strconv" "strings" "github.com/docker/cli/cli/command" "github.com/compose-spec/compose-go/types" - "github.com/pkg/errors" "golang.org/x/exp/maps" "github.com/docker/compose/v2/pkg/api" @@ -95,12 +95,12 @@ func parseServicesReplicasArgs(args []string) (map[string]int, error) { for _, arg := range args { key, val, ok := strings.Cut(arg, "=") if !ok || key == "" || val == "" { - return nil, errors.Errorf("invalid scale specifier: %s", arg) + return nil, fmt.Errorf("invalid scale specifier: %s", arg) } intValue, err := strconv.Atoi(val) if err != nil { - return nil, errors.Errorf("invalid scale specifier: can't parse replica value as int: %v", arg) + return nil, fmt.Errorf("invalid scale specifier: can't parse replica value as int: %v", arg) } serviceReplicaTuples[key] = intValue } diff --git a/cmd/compose/watch.go b/cmd/compose/watch.go index 8463cf32c01..fa3d1936931 100644 --- a/cmd/compose/watch.go +++ b/cmd/compose/watch.go @@ -78,10 +78,10 @@ func runWatch(ctx context.Context, dockerCli command.Cli, backend api.Service, w // validation done -- ensure we have the lockfile for this project before doing work l, err := locker.NewPidfile(project.Name) if err != nil { - return fmt.Errorf("cannot take exclusive lock for project %q: %v", project.Name, err) + return fmt.Errorf("cannot take exclusive lock for project %q: %w", project.Name, err) } if err := l.Lock(); err != nil { - return fmt.Errorf("cannot take exclusive lock for project %q: %v", project.Name, err) + return fmt.Errorf("cannot take exclusive lock for project %q: %w", project.Name, err) } if !watchOpts.noUp { diff --git a/cmd/formatter/formatter.go b/cmd/formatter/formatter.go index 0f54dfcacd9..7330c578fd0 100644 --- a/cmd/formatter/formatter.go +++ b/cmd/formatter/formatter.go @@ -23,8 +23,6 @@ import ( "strings" "github.com/docker/compose/v2/pkg/api" - - "github.com/pkg/errors" ) // Print prints formatted lists in different formats @@ -67,7 +65,7 @@ func Print(toJSON interface{}, format string, outWriter io.Writer, writerFn func _, _ = fmt.Fprintln(outWriter, outJSON) } default: - return errors.Wrapf(api.ErrParsingFailed, "format value %q could not be parsed", format) + return fmt.Errorf("format value %q could not be parsed: %w", format, api.ErrParsingFailed) } return nil } diff --git a/go.mod b/go.mod index 5a0aa671766..254970f83c0 100644 --- a/go.mod +++ b/go.mod @@ -33,7 +33,6 @@ require ( github.com/morikuni/aec v1.0.0 github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec v1.1.0-rc5 - github.com/pkg/errors v0.9.1 github.com/sirupsen/logrus v1.9.3 github.com/spf13/cobra v1.7.0 github.com/spf13/pflag v1.0.5 @@ -46,13 +45,12 @@ require ( go.opentelemetry.io/otel/sdk v1.14.0 go.opentelemetry.io/otel/trace v1.14.0 go.uber.org/goleak v1.2.1 + golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 golang.org/x/sync v0.3.0 google.golang.org/grpc v1.58.2 gotest.tools/v3 v3.5.1 ) -require golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 - require ( github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect @@ -132,6 +130,7 @@ require ( github.com/opencontainers/runc v1.1.7 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.5 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_golang v1.14.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect diff --git a/internal/sync/tar.go b/internal/sync/tar.go index c16444c3b62..bb6a0acf0e4 100644 --- a/internal/sync/tar.go +++ b/internal/sync/tar.go @@ -21,6 +21,7 @@ import ( "archive/tar" "bytes" "context" + "errors" "fmt" "io" "io/fs" @@ -30,7 +31,6 @@ import ( "strings" "github.com/hashicorp/go-multierror" - "github.com/pkg/errors" "github.com/compose-spec/compose-go/types" moby "github.com/docker/docker/api/types" @@ -212,7 +212,7 @@ func (a *ArchiveBuilder) writeEntry(entry archiveEntry) error { if useBuf { a.copyBuf.Reset() _, err = io.Copy(a.copyBuf, file) - if err != nil && err != io.EOF { + if err != nil && !errors.Is(err, io.EOF) { return fmt.Errorf("copying %q: %w", pathInTar, err) } header.Size = int64(len(a.copyBuf.Bytes())) @@ -232,7 +232,7 @@ func (a *ArchiveBuilder) writeEntry(entry archiveEntry) error { _, err = io.Copy(a.tw, file) } - if err != nil && err != io.EOF { + if err != nil && !errors.Is(err, io.EOF) { return fmt.Errorf("copying %q: %w", pathInTar, err) } diff --git a/internal/sync/writer_test.go b/internal/sync/writer_test.go index 1e5c13d40b9..b6de694c72c 100644 --- a/internal/sync/writer_test.go +++ b/internal/sync/writer_test.go @@ -18,12 +18,12 @@ package sync import ( "context" + "errors" "io" "sync" "testing" "time" - "github.com/pkg/errors" "github.com/stretchr/testify/require" ) @@ -115,7 +115,7 @@ func (b *bufReader) consume() { b.data = append(b.data, buf[:n]...) b.mu.Unlock() } - if err == io.EOF { + if errors.Is(err, io.EOF) { return } if err != nil { diff --git a/internal/tracing/docker_context.go b/internal/tracing/docker_context.go index 092a299b543..f5f5ece3f74 100644 --- a/internal/tracing/docker_context.go +++ b/internal/tracing/docker_context.go @@ -39,7 +39,7 @@ func traceClientFromDockerContext(dockerCli command.Cli, otelEnv envMap) (otlptr // automatic integration with Docker Desktop; cfg, err := ConfigFromDockerContext(dockerCli.ContextStore(), dockerCli.CurrentContext()) if err != nil { - return nil, fmt.Errorf("loading otel config from docker context metadata: %v", err) + return nil, fmt.Errorf("loading otel config from docker context metadata: %w", err) } if cfg.Endpoint == "" { @@ -52,13 +52,13 @@ func traceClientFromDockerContext(dockerCli command.Cli, otelEnv envMap) (otlptr defer func() { for k, v := range otelEnv { if err := os.Setenv(k, v); err != nil { - panic(fmt.Errorf("restoring env for %q: %v", k, err)) + panic(fmt.Errorf("restoring env for %q: %w", k, err)) } } }() for k := range otelEnv { if err := os.Unsetenv(k); err != nil { - return nil, fmt.Errorf("stashing env for %q: %v", k, err) + return nil, fmt.Errorf("stashing env for %q: %w", k, err) } } @@ -71,7 +71,7 @@ func traceClientFromDockerContext(dockerCli command.Cli, otelEnv envMap) (otlptr grpc.WithTransportCredentials(insecure.NewCredentials()), ) if err != nil { - return nil, fmt.Errorf("initializing otel connection from docker context metadata: %v", err) + return nil, fmt.Errorf("initializing otel connection from docker context metadata: %w", err) } client := otlptracegrpc.NewClient(otlptracegrpc.WithGRPCConn(conn)) diff --git a/internal/tracing/tracing.go b/internal/tracing/tracing.go index afa534d57b5..63d275d776a 100644 --- a/internal/tracing/tracing.go +++ b/internal/tracing/tracing.go @@ -111,7 +111,7 @@ func InitProvider(dockerCli command.Cli) (ShutdownFunc, error) { ), ) if err != nil { - return nil, fmt.Errorf("failed to create resource: %v", err) + return nil, fmt.Errorf("failed to create resource: %w", err) } muxExporter := MuxExporter{exporters: exporters} diff --git a/pkg/api/dryrunclient.go b/pkg/api/dryrunclient.go index 57e52d04511..88cfc12a98b 100644 --- a/pkg/api/dryrunclient.go +++ b/pkg/api/dryrunclient.go @@ -21,6 +21,7 @@ import ( "context" "crypto/rand" "encoding/json" + "errors" "fmt" "io" "net" @@ -44,7 +45,6 @@ import ( "github.com/docker/docker/client" "github.com/docker/docker/pkg/jsonmessage" specs "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" ) const ( diff --git a/pkg/api/errors.go b/pkg/api/errors.go index e7820168e30..c61c2d0f45e 100644 --- a/pkg/api/errors.go +++ b/pkg/api/errors.go @@ -17,7 +17,7 @@ package api import ( - "github.com/pkg/errors" + "errors" ) const ( diff --git a/pkg/api/errors_test.go b/pkg/api/errors_test.go index ea47edb6148..d221db3fdec 100644 --- a/pkg/api/errors_test.go +++ b/pkg/api/errors_test.go @@ -17,35 +17,36 @@ package api import ( + "errors" + "fmt" "testing" - "github.com/pkg/errors" "gotest.tools/v3/assert" ) func TestIsNotFound(t *testing.T) { - err := errors.Wrap(ErrNotFound, `object "name"`) + err := fmt.Errorf(`object "name": %w`, ErrNotFound) assert.Assert(t, IsNotFoundError(err)) assert.Assert(t, !IsNotFoundError(errors.New("another error"))) } func TestIsAlreadyExists(t *testing.T) { - err := errors.Wrap(ErrAlreadyExists, `object "name"`) + err := fmt.Errorf(`object "name": %w`, ErrAlreadyExists) assert.Assert(t, IsAlreadyExistsError(err)) assert.Assert(t, !IsAlreadyExistsError(errors.New("another error"))) } func TestIsForbidden(t *testing.T) { - err := errors.Wrap(ErrForbidden, `object "name"`) + err := fmt.Errorf(`object "name": %w`, ErrForbidden) assert.Assert(t, IsForbiddenError(err)) assert.Assert(t, !IsForbiddenError(errors.New("another error"))) } func TestIsUnknown(t *testing.T) { - err := errors.Wrap(ErrUnknown, `object "name"`) + err := fmt.Errorf(`object "name": %w`, ErrUnknown) assert.Assert(t, IsUnknownError(err)) assert.Assert(t, !IsUnknownError(errors.New("another error"))) diff --git a/pkg/compose/attach.go b/pkg/compose/attach.go index 1403226800d..88077993474 100644 --- a/pkg/compose/attach.go +++ b/pkg/compose/attach.go @@ -18,6 +18,7 @@ package compose import ( "context" + "errors" "fmt" "io" "strings" @@ -132,7 +133,8 @@ func (s *composeService) attachContainerStreams(ctx context.Context, container s if streamIn != nil && stdin != nil { go func() { _, err := io.Copy(streamIn, stdin) - if _, ok := err.(term.EscapeError); ok { + var escapeErr term.EscapeError + if errors.As(err, &escapeErr) { close(detached) } }() diff --git a/pkg/compose/build_classic.go b/pkg/compose/build_classic.go index 243ffb17ed5..e49a15cc2be 100644 --- a/pkg/compose/build_classic.go +++ b/pkg/compose/build_classic.go @@ -19,6 +19,7 @@ package compose import ( "context" "encoding/json" + "errors" "fmt" "io" "os" @@ -41,7 +42,6 @@ import ( "github.com/docker/docker/pkg/jsonmessage" "github.com/docker/docker/pkg/progress" "github.com/docker/docker/pkg/streamformatter" - "github.com/pkg/errors" "github.com/docker/compose/v2/pkg/api" ) @@ -64,19 +64,19 @@ func (s *composeService) doBuildClassic(ctx context.Context, project *types.Proj buildBuff := s.stdout() if len(service.Build.Platforms) > 1 { - return "", errors.Errorf("the classic builder doesn't support multi-arch build, set DOCKER_BUILDKIT=1 to use BuildKit") + return "", fmt.Errorf("the classic builder doesn't support multi-arch build, set DOCKER_BUILDKIT=1 to use BuildKit") } if service.Build.Privileged { - return "", errors.Errorf("the classic builder doesn't support privileged mode, set DOCKER_BUILDKIT=1 to use BuildKit") + return "", fmt.Errorf("the classic builder doesn't support privileged mode, set DOCKER_BUILDKIT=1 to use BuildKit") } if len(service.Build.AdditionalContexts) > 0 { - return "", errors.Errorf("the classic builder doesn't support additional contexts, set DOCKER_BUILDKIT=1 to use BuildKit") + return "", fmt.Errorf("the classic builder doesn't support additional contexts, set DOCKER_BUILDKIT=1 to use BuildKit") } if len(service.Build.SSH) > 0 { - return "", errors.Errorf("the classic builder doesn't support SSH keys, set DOCKER_BUILDKIT=1 to use BuildKit") + return "", fmt.Errorf("the classic builder doesn't support SSH keys, set DOCKER_BUILDKIT=1 to use BuildKit") } if len(service.Build.Secrets) > 0 { - return "", errors.Errorf("the classic builder doesn't support secrets, set DOCKER_BUILDKIT=1 to use BuildKit") + return "", fmt.Errorf("the classic builder doesn't support secrets, set DOCKER_BUILDKIT=1 to use BuildKit") } if service.Build.Labels == nil { @@ -91,7 +91,7 @@ func (s *composeService) doBuildClassic(ctx context.Context, project *types.Proj // Dockerfile is outside of build-context; read the Dockerfile and pass it as dockerfileCtx dockerfileCtx, err = os.Open(dockerfileName) if err != nil { - return "", errors.Errorf("unable to open Dockerfile: %v", err) + return "", fmt.Errorf("unable to open Dockerfile: %w", err) } defer dockerfileCtx.Close() //nolint:errcheck } @@ -100,11 +100,11 @@ func (s *composeService) doBuildClassic(ctx context.Context, project *types.Proj case urlutil.IsURL(specifiedContext): buildCtx, relDockerfile, err = build.GetContextFromURL(progBuff, specifiedContext, dockerfileName) default: - return "", errors.Errorf("unable to prepare context: path %q not found", specifiedContext) + return "", fmt.Errorf("unable to prepare context: path %q not found", specifiedContext) } if err != nil { - return "", errors.Errorf("unable to prepare context: %s", err) + return "", fmt.Errorf("unable to prepare context: %w", err) } if tempDir != "" { @@ -120,7 +120,7 @@ func (s *composeService) doBuildClassic(ctx context.Context, project *types.Proj } if err := build.ValidateContextDirectory(contextDir, excludes); err != nil { - return "", errors.Wrap(err, "checking context") + return "", fmt.Errorf("checking context: %w", err) } // And canonicalize dockerfile name to a platform-independent one @@ -188,7 +188,8 @@ func (s *composeService) doBuildClassic(ctx context.Context, project *types.Proj err = jsonmessage.DisplayJSONMessagesStream(response.Body, buildBuff, progBuff.FD(), true, aux) if err != nil { - if jerr, ok := err.(*jsonmessage.JSONError); ok { + var jerr *jsonmessage.JSONError + if errors.As(err, &jerr) { // If no error code is set, default to 1 if jerr.Code == 0 { jerr.Code = 1 diff --git a/pkg/compose/compose.go b/pkg/compose/compose.go index 688a48454b9..a9469496b1e 100644 --- a/pkg/compose/compose.go +++ b/pkg/compose/compose.go @@ -41,7 +41,6 @@ import ( "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/client" "github.com/opencontainers/go-digest" - "github.com/pkg/errors" ) var stdioToStdout bool @@ -180,7 +179,7 @@ func (s *composeService) projectFromName(containers Containers, projectName stri Name: projectName, } if len(containers) == 0 { - return project, errors.Wrap(api.ErrNotFound, fmt.Sprintf("no container found for project %q", projectName)) + return project, fmt.Errorf("no container found for project %q: %w", projectName, api.ErrNotFound) } set := map[string]*types.ServiceConfig{} for _, c := range containers { @@ -226,7 +225,7 @@ SERVICES: continue SERVICES } } - return project, errors.Wrapf(api.ErrNotFound, "no such service: %q", qs) + return project, fmt.Errorf("no such service: %q: %w", qs, api.ErrNotFound) } err := project.ForServices(services) if err != nil { diff --git a/pkg/compose/convergence.go b/pkg/compose/convergence.go index 626a7b09748..7c5b13eaec5 100644 --- a/pkg/compose/convergence.go +++ b/pkg/compose/convergence.go @@ -18,6 +18,7 @@ package compose import ( "context" + "errors" "fmt" "sort" "strconv" @@ -34,7 +35,6 @@ import ( moby "github.com/docker/docker/api/types" containerType "github.com/docker/docker/api/types/container" specs "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" "github.com/sirupsen/logrus" "golang.org/x/sync/errgroup" @@ -365,7 +365,7 @@ func (s *composeService) waitDependencies(ctx context.Context, project *types.Pr return nil } w.Events(containerEvents(waitingFor, progress.ErrorEvent)) - return errors.Wrap(err, "dependency failed to start") + return fmt.Errorf("dependency failed to start: %w", err) } if healthy { w.Events(containerEvents(waitingFor, progress.Healthy)) diff --git a/pkg/compose/cp.go b/pkg/compose/cp.go index fdba0a8d021..85941f8f6cd 100644 --- a/pkg/compose/cp.go +++ b/pkg/compose/cp.go @@ -18,6 +18,7 @@ package compose import ( "context" + "errors" "fmt" "io" "os" @@ -32,7 +33,6 @@ import ( moby "github.com/docker/docker/api/types" "github.com/docker/docker/pkg/archive" "github.com/docker/docker/pkg/system" - "github.com/pkg/errors" ) type copyDirection int @@ -175,7 +175,7 @@ func (s *composeService) copyToContainer(ctx context.Context, containerID string // Validate the destination path if err := command.ValidateOutputPathFileMode(dstStat.Mode); err != nil { - return errors.Wrapf(err, `destination "%s:%s" must be a directory or a regular file`, containerID, dstPath) + return fmt.Errorf(`destination "%s:%s" must be a directory or a regular file: %w`, containerID, dstPath, err) } // Ignore any error and assume that the parent directory of the destination @@ -197,7 +197,7 @@ func (s *composeService) copyToContainer(ctx context.Context, containerID string content = s.stdin() resolvedDstPath = dstInfo.Path if !dstInfo.IsDir { - return errors.Errorf("destination \"%s:%s\" must be a directory", containerID, dstPath) + return fmt.Errorf("destination \"%s:%s\" must be a directory", containerID, dstPath) } } else { // Prepare source copy info. diff --git a/pkg/compose/create.go b/pkg/compose/create.go index 0b0d81ca25d..01b67ebf25e 100644 --- a/pkg/compose/create.go +++ b/pkg/compose/create.go @@ -38,7 +38,6 @@ import ( "github.com/docker/docker/errdefs" "github.com/docker/go-connections/nat" "github.com/docker/go-units" - "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/compose-spec/compose-go/types" @@ -345,17 +344,17 @@ func parseSecurityOpts(p *types.Project, securityOpts []string) ([]string, bool, if strings.Contains(opt, ":") { con = strings.SplitN(opt, ":", 2) } else { - return securityOpts, false, errors.Errorf("Invalid security-opt: %q", opt) + return securityOpts, false, fmt.Errorf("Invalid security-opt: %q", opt) } } if con[0] == "seccomp" && con[1] != "unconfined" { f, err := os.ReadFile(p.RelativePath(con[1])) if err != nil { - return securityOpts, false, errors.Errorf("opening seccomp profile (%s) failed: %v", con[1], err) + return securityOpts, false, fmt.Errorf("opening seccomp profile (%s) failed: %w", con[1], err) } b := bytes.NewBuffer(nil) if err := json.Compact(b, f); err != nil { - return securityOpts, false, errors.Errorf("compacting json for seccomp profile (%s) failed: %v", con[1], err) + return securityOpts, false, fmt.Errorf("compacting json for seccomp profile (%s) failed: %w", con[1], err) } parsed = append(parsed, fmt.Sprintf("seccomp=%s", b.Bytes())) } else { @@ -1111,7 +1110,7 @@ func (s *composeService) resolveOrCreateNetwork(ctx context.Context, n *types.Ne _, err = s.apiClient().NetworkCreate(ctx, n.Name, createOpts) if err != nil { w.Event(progress.ErrorEvent(networkEventName)) - return errors.Wrapf(err, "failed to create network %s", n.Name) + return fmt.Errorf("failed to create network %s: %w", n.Name, err) } w.Event(progress.CreatedEvent(networkEventName)) return nil diff --git a/pkg/compose/dependencies.go b/pkg/compose/dependencies.go index 5205b30e084..94b8d2d21a0 100644 --- a/pkg/compose/dependencies.go +++ b/pkg/compose/dependencies.go @@ -24,7 +24,6 @@ import ( "github.com/compose-spec/compose-go/types" "github.com/docker/compose/v2/pkg/api" - "github.com/pkg/errors" "golang.org/x/sync/errgroup" "github.com/docker/compose/v2/pkg/utils" @@ -324,10 +323,10 @@ func (g *Graph) AddEdge(source string, destination string) error { destinationVertex := g.Vertices[destination] if sourceVertex == nil { - return errors.Wrapf(api.ErrNotFound, "could not find %s", source) + return fmt.Errorf("could not find %s: %w", source, api.ErrNotFound) } if destinationVertex == nil { - return errors.Wrapf(api.ErrNotFound, "could not find %s", destination) + return fmt.Errorf("could not find %s: %w", destination, api.ErrNotFound) } // If they are already connected diff --git a/pkg/compose/down.go b/pkg/compose/down.go index 3f5910c6ef6..f0d3ddf1c6f 100644 --- a/pkg/compose/down.go +++ b/pkg/compose/down.go @@ -29,7 +29,6 @@ import ( containerType "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" "github.com/docker/docker/errdefs" - "github.com/pkg/errors" "golang.org/x/sync/errgroup" "github.com/docker/compose/v2/pkg/api" @@ -192,7 +191,7 @@ func (s *composeService) removeNetwork(ctx context.Context, composeNetworkName s networkFilter(composeNetworkName)), }) if err != nil { - return errors.Wrapf(err, "failed to list networks") + return fmt.Errorf("failed to list networks: %w", err) } if len(networks) == 0 { @@ -226,7 +225,7 @@ func (s *composeService) removeNetwork(ctx context.Context, composeNetworkName s continue } w.Event(progress.ErrorEvent(eventName)) - return errors.Wrapf(err, fmt.Sprintf("failed to remove network %s", name)) + return fmt.Errorf("failed to remove network %s: %w", name, err) } w.Event(progress.RemovedEvent(eventName)) found++ diff --git a/pkg/compose/errors.go b/pkg/compose/errors.go index d97fe713d3c..0dd06c6dbb5 100644 --- a/pkg/compose/errors.go +++ b/pkg/compose/errors.go @@ -17,10 +17,9 @@ package compose import ( + "errors" "io/fs" - "github.com/pkg/errors" - "github.com/compose-spec/compose-go/errdefs" ) diff --git a/pkg/compose/exec.go b/pkg/compose/exec.go index 6477ca06ad2..62b9d31c912 100644 --- a/pkg/compose/exec.go +++ b/pkg/compose/exec.go @@ -18,6 +18,7 @@ package compose import ( "context" + "errors" "strings" "github.com/docker/cli/cli" @@ -50,7 +51,8 @@ func (s *composeService) Exec(ctx context.Context, projectName string, options a } err = container.RunExec(s.dockerCli, exec) - if sterr, ok := err.(cli.StatusError); ok { + var sterr cli.StatusError + if errors.As(err, &sterr) { return sterr.StatusCode, nil } return 0, err diff --git a/pkg/compose/logs.go b/pkg/compose/logs.go index f5a20b16a9a..6546ffe0438 100644 --- a/pkg/compose/logs.go +++ b/pkg/compose/logs.go @@ -18,6 +18,7 @@ package compose import ( "context" + "errors" "io" "strings" "time" @@ -56,7 +57,8 @@ func (s *composeService) Logs( c := c eg.Go(func() error { err := s.logContainers(ctx, consumer, c, options) - if _, ok := err.(errdefs.ErrNotImplemented); ok { + var notImplErr errdefs.ErrNotImplemented + if errors.As(err, ¬ImplErr) { logrus.Warnf("Can't retrieve logs for %q: %s", getCanonicalContainerName(c), err.Error()) return nil } @@ -97,7 +99,8 @@ func (s *composeService) Logs( Tail: options.Tail, Timestamps: options.Timestamps, }) - if _, ok := err.(errdefs.ErrNotImplemented); ok { + var notImplErr errdefs.ErrNotImplemented + if errors.As(err, ¬ImplErr) { // ignore return nil } diff --git a/pkg/compose/pull.go b/pkg/compose/pull.go index e5d2ff656d7..247be85af8e 100644 --- a/pkg/compose/pull.go +++ b/pkg/compose/pull.go @@ -215,7 +215,7 @@ func (s *composeService) pullServiceImage(ctx context.Context, service types.Ser for { var jm jsonmessage.JSONMessage if err := dec.Decode(&jm); err != nil { - if err == io.EOF { + if errors.Is(err, io.EOF) { break } return "", WrapCategorisedComposeError(err, PullFailure) diff --git a/pkg/compose/push.go b/pkg/compose/push.go index f37fd305e46..13b8081a2f3 100644 --- a/pkg/compose/push.go +++ b/pkg/compose/push.go @@ -20,6 +20,7 @@ import ( "context" "encoding/base64" "encoding/json" + "errors" "fmt" "io" @@ -29,7 +30,6 @@ import ( moby "github.com/docker/docker/api/types" "github.com/docker/docker/pkg/jsonmessage" "github.com/docker/docker/registry" - "github.com/pkg/errors" "golang.org/x/sync/errgroup" "github.com/docker/compose/v2/pkg/api" @@ -117,7 +117,7 @@ func (s *composeService) pushServiceImage(ctx context.Context, service types.Ser for { var jm jsonmessage.JSONMessage if err := dec.Decode(&jm); err != nil { - if err == io.EOF { + if errors.Is(err, io.EOF) { break } return err diff --git a/pkg/compose/start.go b/pkg/compose/start.go index f3548f039cb..d7022400f7e 100644 --- a/pkg/compose/start.go +++ b/pkg/compose/start.go @@ -18,6 +18,7 @@ package compose import ( "context" + "errors" "fmt" "strings" "time" @@ -31,7 +32,6 @@ import ( "github.com/compose-spec/compose-go/types" moby "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" - "github.com/pkg/errors" "golang.org/x/sync/errgroup" ) @@ -150,7 +150,7 @@ func (s *composeService) start(ctx context.Context, projectName string, options err = s.waitDependencies(ctx, project, depends, containers) if err != nil { - if ctx.Err() == context.DeadlineExceeded { + if errors.Is(ctx.Err(), context.DeadlineExceeded) { return fmt.Errorf("application not healthy after %s", options.WaitTimeout) } return err diff --git a/pkg/compose/watch.go b/pkg/compose/watch.go index 29b0fe33e30..b569a42b954 100644 --- a/pkg/compose/watch.go +++ b/pkg/compose/watch.go @@ -16,6 +16,7 @@ package compose import ( "context" + "errors" "fmt" "io" "os" @@ -33,7 +34,6 @@ import ( moby "github.com/docker/docker/api/types" "github.com/jonboulle/clockwork" "github.com/mitchellh/mapstructure" - "github.com/pkg/errors" "github.com/sirupsen/logrus" "golang.org/x/sync/errgroup" ) diff --git a/pkg/e2e/framework.go b/pkg/e2e/framework.go index e9ded780e93..58f7debafd4 100644 --- a/pkg/e2e/framework.go +++ b/pkg/e2e/framework.go @@ -18,6 +18,7 @@ package e2e import ( "encoding/json" + "errors" "fmt" "io" "io/fs" @@ -29,7 +30,6 @@ import ( "testing" "time" - "github.com/pkg/errors" "github.com/stretchr/testify/require" "gotest.tools/v3/assert" "gotest.tools/v3/icmd" @@ -192,7 +192,7 @@ func findPluginExecutable(pluginExecutableName string) (string, error) { if _, err := os.Stat(bin); err == nil { return bin, nil } - return "", errors.Wrap(os.ErrNotExist, fmt.Sprintf("plugin not found %s", pluginExecutableName)) + return "", fmt.Errorf("plugin not found %s: %w", pluginExecutableName, os.ErrNotExist) } // CopyFile copies a file from a sourceFile to a destinationFile setting permissions to 0755 diff --git a/pkg/e2e/pause_test.go b/pkg/e2e/pause_test.go index c3699eb8073..ef1c18db1f1 100644 --- a/pkg/e2e/pause_test.go +++ b/pkg/e2e/pause_test.go @@ -18,6 +18,7 @@ package e2e import ( "encoding/json" + "errors" "fmt" "net" "net/http" @@ -61,7 +62,9 @@ func TestPause(t *testing.T) { _ = resp.Body.Close() } require.Error(t, err, "a should no longer respond") - require.True(t, err.(net.Error).Timeout(), "Error should have indicated a timeout") + var netErr net.Error + errors.As(err, &netErr) + require.True(t, netErr.Timeout(), "Error should have indicated a timeout") HTTPGetWithRetry(t, urls["b"], http.StatusOK, 50*time.Millisecond, 5*time.Second) // unpause a and verify that both containers work again diff --git a/pkg/e2e/up_test.go b/pkg/e2e/up_test.go index 64beac7dd73..c38f9cd5a2e 100644 --- a/pkg/e2e/up_test.go +++ b/pkg/e2e/up_test.go @@ -21,6 +21,7 @@ package e2e import ( "context" + "errors" "os/exec" "strings" "syscall" @@ -90,7 +91,8 @@ func TestUpDependenciesNotStopped(t *testing.T) { t.Log("Waiting for `compose up` to exit") err = cmd.Wait() if err != nil { - exitErr := err.(*exec.ExitError) + var exitErr *exec.ExitError + errors.As(err, &exitErr) if exitErr.ExitCode() == -1 { t.Fatalf("`compose up` was killed: %v", err) } diff --git a/pkg/remote/git.go b/pkg/remote/git.go index e0ab25cc34e..3e7c9a1d8fb 100644 --- a/pkg/remote/git.go +++ b/pkg/remote/git.go @@ -32,14 +32,13 @@ import ( "github.com/compose-spec/compose-go/types" "github.com/docker/compose/v2/pkg/api" "github.com/moby/buildkit/util/gitutil" - "github.com/pkg/errors" ) func GitRemoteLoaderEnabled() (bool, error) { if v := os.Getenv("COMPOSE_EXPERIMENTAL_GIT_REMOTE"); v != "" { enabled, err := strconv.ParseBool(v) if err != nil { - return false, errors.Wrap(err, "COMPOSE_EXPERIMENTAL_GIT_REMOTE environment variable expects boolean value") + return false, fmt.Errorf("COMPOSE_EXPERIMENTAL_GIT_REMOTE environment variable expects boolean value: %w", err) } return enabled, err } @@ -90,7 +89,7 @@ func (g gitRemoteLoader) Load(ctx context.Context, path string) (string, error) out, err := cmd.Output() if err != nil { if cmd.ProcessState.ExitCode() == 2 { - return "", errors.Wrapf(err, "repository does not contain ref %s, output: %q", path, string(out)) + return "", fmt.Errorf("repository does not contain ref %s, output: %q: %w", path, string(out), err) } return "", err } diff --git a/pkg/remote/oci.go b/pkg/remote/oci.go index f7746b954d8..c2a8b042a77 100644 --- a/pkg/remote/oci.go +++ b/pkg/remote/oci.go @@ -33,14 +33,13 @@ import ( v1 "github.com/opencontainers/image-spec/specs-go/v1" "github.com/compose-spec/compose-go/loader" - "github.com/pkg/errors" ) func OCIRemoteLoaderEnabled() (bool, error) { if v := os.Getenv("COMPOSE_EXPERIMENTAL_OCI_REMOTE"); v != "" { enabled, err := strconv.ParseBool(v) if err != nil { - return false, errors.Wrap(err, "COMPOSE_EXPERIMENTAL_OCI_REMOTE environment variable expects boolean value") + return false, fmt.Errorf("COMPOSE_EXPERIMENTAL_OCI_REMOTE environment variable expects boolean value: %w", err) } return enabled, err } diff --git a/pkg/watch/notify.go b/pkg/watch/notify.go index 7f28d84b67a..61b6b16ec41 100644 --- a/pkg/watch/notify.go +++ b/pkg/watch/notify.go @@ -17,6 +17,7 @@ package watch import ( + "errors" "expvar" "fmt" "os" @@ -24,7 +25,6 @@ import ( "runtime" "strconv" - "github.com/pkg/errors" "github.com/tilt-dev/fsnotify" ) diff --git a/pkg/watch/paths.go b/pkg/watch/paths.go index 4d057c25b1e..1496a06dd3e 100644 --- a/pkg/watch/paths.go +++ b/pkg/watch/paths.go @@ -21,8 +21,6 @@ import ( "os" "path/filepath" "strings" - - "github.com/pkg/errors" ) func greatestExistingAncestor(path string) (string, error) { @@ -33,7 +31,7 @@ func greatestExistingAncestor(path string) (string, error) { _, err := os.Stat(path) if err != nil && !os.IsNotExist(err) { - return "", errors.Wrapf(err, "os.Stat(%q)", path) + return "", fmt.Errorf("os.Stat(%q): %w", path, err) } if os.IsNotExist(err) { diff --git a/pkg/watch/watcher_darwin.go b/pkg/watch/watcher_darwin.go index d1a2a9c200b..37aac3a31ba 100644 --- a/pkg/watch/watcher_darwin.go +++ b/pkg/watch/watcher_darwin.go @@ -20,12 +20,12 @@ package watch import ( + "fmt" "os" "path/filepath" "time" "github.com/fsnotify/fsevents" - "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -136,7 +136,7 @@ func newWatcher(paths []string, ignore PathMatcher) (Notify, error) { for _, path := range paths { path, err := filepath.Abs(path) if err != nil { - return nil, errors.Wrap(err, "newWatcher") + return nil, fmt.Errorf("newWatcher: %w", err) } dw.initAdd(path) } diff --git a/pkg/watch/watcher_naive.go b/pkg/watch/watcher_naive.go index e8c7e855f5b..e681d5a96c8 100644 --- a/pkg/watch/watcher_naive.go +++ b/pkg/watch/watcher_naive.go @@ -27,7 +27,6 @@ import ( "runtime" "strings" - "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/tilt-dev/fsnotify" @@ -78,7 +77,7 @@ func (d *naiveNotify) Start() error { for _, name := range pathsToWatch { fi, err := os.Stat(name) if err != nil && !os.IsNotExist(err) { - return errors.Wrapf(err, "notify.Add(%q)", name) + return fmt.Errorf("notify.Add(%q): %w", name, err) } // if it's a file that doesn't exist, @@ -90,12 +89,12 @@ func (d *naiveNotify) Start() error { if fi.IsDir() { err = d.watchRecursively(name) if err != nil { - return errors.Wrapf(err, "notify.Add(%q)", name) + return fmt.Errorf("notify.Add(%q): %w", name, err) } } else { err = d.add(filepath.Dir(name)) if err != nil { - return errors.Wrapf(err, "notify.Add(%q)", filepath.Dir(name)) + return fmt.Errorf("notify.Add(%q): %w", filepath.Dir(name), err) } } } @@ -111,7 +110,7 @@ func (d *naiveNotify) watchRecursively(dir string) error { if err == nil || os.IsNotExist(err) { return nil } - return errors.Wrapf(err, "watcher.Add(%q)", dir) + return fmt.Errorf("watcher.Add(%q): %w", dir, err) } return filepath.WalkDir(dir, func(path string, info fs.DirEntry, err error) error { @@ -138,7 +137,7 @@ func (d *naiveNotify) watchRecursively(dir string) error { if os.IsNotExist(err) { return nil } - return errors.Wrapf(err, "watcher.Add(%q)", path) + return fmt.Errorf("watcher.Add(%q): %w", path, err) } return nil }) @@ -262,7 +261,7 @@ func (d *naiveNotify) shouldSkipDir(path string) (bool, error) { skip, err := d.ignore.MatchesEntireDir(path) if err != nil { - return false, errors.Wrap(err, "shouldSkipDir") + return false, fmt.Errorf("shouldSkipDir: %w", err) } if skip { @@ -311,7 +310,7 @@ func newWatcher(paths []string, ignore PathMatcher) (Notify, error) { "Run 'sysctl fs.inotify.max_user_instances' to check your inotify limits.\n" + "To raise them, run 'sudo sysctl fs.inotify.max_user_instances=1024'") } - return nil, errors.Wrap(err, "creating file watcher") + return nil, fmt.Errorf("creating file watcher: %w", err) } MaybeIncreaseBufferSize(fsw) @@ -326,7 +325,7 @@ func newWatcher(paths []string, ignore PathMatcher) (Notify, error) { for _, path := range paths { path, err := filepath.Abs(path) if err != nil { - return nil, errors.Wrap(err, "newWatcher") + return nil, fmt.Errorf("newWatcher: %w", err) } notifyList[path] = true } @@ -351,7 +350,7 @@ func greatestExistingAncestors(paths []string) ([]string, error) { for _, p := range paths { newP, err := greatestExistingAncestor(p) if err != nil { - return nil, fmt.Errorf("Finding ancestor of %s: %v", p, err) + return nil, fmt.Errorf("Finding ancestor of %s: %w", p, err) } result = append(result, newP) } diff --git a/pkg/watch/watcher_naive_test.go b/pkg/watch/watcher_naive_test.go index de0e80fe95e..78acfdc5fee 100644 --- a/pkg/watch/watcher_naive_test.go +++ b/pkg/watch/watcher_naive_test.go @@ -125,12 +125,12 @@ func inotifyNodes() (int, error) { output, err := exec.Command("/bin/sh", "-c", fmt.Sprintf( "find /proc/%d/fd -lname anon_inode:inotify -printf '%%hinfo/%%f\n' | xargs cat | grep -c '^inotify'", pid)).Output() if err != nil { - return 0, fmt.Errorf("error running command to determine number of watched files: %v\n %s", err, output) + return 0, fmt.Errorf("error running command to determine number of watched files: %w\n %s", err, output) } n, err := strconv.Atoi(strings.TrimSpace(string(output))) if err != nil { - return 0, fmt.Errorf("couldn't parse number of watched files: %v", err) + return 0, fmt.Errorf("couldn't parse number of watched files: %w", err) } return n, nil }