From 3b82516d4e3b092e46351881816fd33154bf7dea Mon Sep 17 00:00:00 2001 From: Janis Horsts Date: Thu, 25 Jun 2026 16:18:58 +0100 Subject: [PATCH 1/3] refactor: use std errors --- buildcontext/detectbuildfile.go | 8 +- buildcontext/excludes.go | 13 +- buildcontext/git.go | 42 ++--- buildcontext/gitlookup.go | 55 +++--- buildcontext/local.go | 4 +- buildcontext/parsefeatures.go | 3 +- buildcontext/provider/provider.go | 9 +- buildcontext/resolver.go | 13 +- builder/builder.go | 77 ++++---- builder/image_solver.go | 27 +-- builder/solver.go | 15 +- buildkitd/buildkitd.go | 117 ++++++------ buildkitd/certificates.go | 44 ++--- buildkitd/settings.go | 8 +- cmd/debugger/main.go | 42 ++--- cmd/earthly/app/before.go | 12 +- cmd/earthly/app/create.go | 6 +- cmd/earthly/app/run.go | 33 +--- cmd/earthly/base/buildkit.go | 7 +- cmd/earthly/base/init_frontend.go | 7 +- cmd/earthly/bk/buildkitskipper_create.go | 4 +- cmd/earthly/common/shared.go | 20 ++- cmd/earthly/helper/autocomplete.go | 6 +- cmd/earthly/main.go | 3 +- cmd/earthly/subcmd/bootstrap_cmds.go | 41 +++-- cmd/earthly/subcmd/build_cmd.go | 89 +++++----- cmd/earthly/subcmd/config_cmds.go | 12 +- cmd/earthly/subcmd/debug_cmds.go | 27 +-- cmd/earthly/subcmd/doc_cmds.go | 27 +-- cmd/earthly/subcmd/init_cmds.go | 27 +-- cmd/earthly/subcmd/ls_cmds.go | 16 +- cmd/earthly/subcmd/prune_cmds.go | 14 +- config/config.go | 38 ++-- debugger/server/server.go | 8 +- debugger/terminal/terminal_other.go | 10 +- debugger/terminal/terminal_windows.go | 3 +- docker2earth/convert.go | 24 +-- docker2earth/convert_test.go | 3 +- dockertar/dockertar.go | 15 +- domain/artifact.go | 8 +- domain/command.go | 4 +- domain/importtracker.go | 21 ++- domain/reference.go | 14 +- domain/target.go | 4 +- earthfile2llb/cachedmetaresolver.go | 4 +- earthfile2llb/converter.go | 166 +++++++++--------- earthfile2llb/earthfile2llb.go | 10 +- earthfile2llb/earthfile_info.go | 15 +- earthfile2llb/interpreter.go | 12 +- earthfile2llb/interpretererror.go | 12 +- earthfile2llb/interpretererror_test.go | 2 +- earthfile2llb/runmount.go | 55 +++--- earthfile2llb/wait_block.go | 30 ++-- earthfile2llb/with_docker_run_base.go | 13 +- earthfile2llb/with_docker_run_local_reg.go | 19 +- earthfile2llb/with_docker_run_local_tar.go | 25 +-- earthfile2llb/with_docker_run_reg.go | 38 ++-- earthfile2llb/with_docker_run_tar.go | 32 ++-- examples/readme/proto/pb/api.pb.go | 3 +- features/features.go | 6 +- go.mod | 4 +- go.sum | 5 - inputgraph/error.go | 2 +- inputgraph/loader.go | 20 +-- inputgraph/util.go | 2 +- logbus/command.go | 8 +- logbus/formatter/formatter.go | 22 +-- logbus/setup/setup.go | 43 ++--- logbus/solvermon/solvermon.go | 7 +- logbus/solvermon/vertexmon.go | 10 +- logbus/solvermon/vertexmon_test.go | 3 +- logbus/writersub/raw.go | 19 +- logbus/writersub/writersub.go | 11 +- logstream/delta.pb.go | 48 ++--- regproxy/controller.go | 14 +- regproxy/proxy.go | 14 +- states/dedup/targetinput.go | 7 +- states/solvecache.go | 5 +- states/states.go | 3 +- states/visited-legacy.go | 7 +- tests/cli/cli_test.go | 3 +- util/cliutil/earthlydir.go | 10 +- util/containerutil/docker.go | 17 +- util/containerutil/frontend.go | 10 +- .../frontend_integration_test.go | 18 +- util/containerutil/podman.go | 26 +-- util/containerutil/shell_shared.go | 19 +- util/containerutil/stub.go | 6 +- util/containerutil/types.go | 5 +- util/dockerutil/docker.go | 20 +-- util/fileutil/fileutil.go | 17 +- util/fileutil/homedirs.go | 11 +- util/fileutil/iswritable_other.go | 5 +- util/flagutil/matrix.go | 4 +- util/flagutil/parse.go | 5 +- util/flagutil/remote_cache.go | 8 +- util/gatewaycrafter/gatewaycrafter.go | 4 +- util/gitutil/detectgit.go | 60 +++---- .../authprovider/helheim_mocks_test.go | 5 +- util/llbutil/authprovider/podman.go | 6 +- util/llbutil/copyop.go | 3 +- util/llbutil/platform_name.go | 7 +- util/llbutil/secretprovider/aws_creds.go | 13 +- util/llbutil/secretprovider/secrets.go | 6 +- util/llbutil/statetoref.go | 8 +- util/params/paramerror.go | 8 +- util/params/paramerror_test.go | 27 +-- util/platutil/native.go | 5 +- util/proj/golang.go | 17 +- util/proj/golang_test.go | 3 +- util/proj/helheim_mocks_test.go | 7 +- util/proj/proj.go | 6 +- .../saveartifactlocally.go | 24 +-- util/semverutil/semverutil.go | 5 +- util/shell/lex.go | 17 +- util/syncutil/synccache/synccache.go | 2 +- variables/collection.go | 7 +- variables/parse.go | 17 +- variables/parsenew.go | 6 +- 119 files changed, 1068 insertions(+), 1055 deletions(-) diff --git a/buildcontext/detectbuildfile.go b/buildcontext/detectbuildfile.go index 43e1727dc4..4657319412 100644 --- a/buildcontext/detectbuildfile.go +++ b/buildcontext/detectbuildfile.go @@ -2,6 +2,7 @@ package buildcontext import ( "context" + "fmt" "os" "path" "path/filepath" @@ -9,7 +10,6 @@ import ( "github.com/EarthBuild/earthbuild/domain" gwclient "github.com/moby/buildkit/frontend/gateway/client" - "github.com/pkg/errors" ) // EarthfileNotExistError is the struct indicating that file does not exist. @@ -38,12 +38,12 @@ func detectBuildFile(ref domain.Reference, localDir string) (string, error) { if os.IsNotExist(err) { return "", EarthfileNotExistError{Target: ref.String()} } else if err != nil { - return "", errors.Wrapf(err, "stat file %s", buildEarthPath) + return "", fmt.Errorf("stat file %s: %w", buildEarthPath, err) } return buildEarthPath, nil } else if err != nil { - return "", errors.Wrapf(err, "stat file %s", earthfilePath) + return "", fmt.Errorf("stat file %s: %w", earthfilePath, err) } return earthfilePath, nil @@ -89,7 +89,7 @@ func fileExists(ctx context.Context, ref gwclient.Reference, fpath string) (bool IncludePattern: file, }) if err != nil { - return false, errors.Wrapf(err, "cannot read dir %s", dir) + return false, fmt.Errorf("cannot read dir %s: %w", dir, err) } for _, fstat := range fstats { diff --git a/buildcontext/excludes.go b/buildcontext/excludes.go index dd35177284..ab42d2027a 100644 --- a/buildcontext/excludes.go +++ b/buildcontext/excludes.go @@ -1,12 +1,13 @@ package buildcontext import ( + "errors" + "fmt" "os" "path/filepath" "github.com/EarthBuild/earthbuild/util/fileutil" "github.com/moby/patternmatcher/ignorefile" - "github.com/pkg/errors" ) const ( @@ -46,7 +47,7 @@ func readExcludes(dir string, noImplicitIgnore bool, useDockerIgnore bool) ([]st earthExists, err := fileutil.FileExists(earthIgnoreFilePath) if err != nil { - return nil, errors.Wrapf(err, "failed to check if %s exists", earthIgnoreFilePath) + return nil, fmt.Errorf("failed to check if %s exists: %w", earthIgnoreFilePath, err) } // earthlyIgnoreFile @@ -54,7 +55,7 @@ func readExcludes(dir string, noImplicitIgnore bool, useDockerIgnore bool) ([]st earthlyExists, err := fileutil.FileExists(earthlyIgnoreFilePath) if err != nil { - return nil, errors.Wrapf(err, "failed to check if %s exists", earthlyIgnoreFilePath) + return nil, fmt.Errorf("failed to check if %s exists: %w", earthlyIgnoreFilePath, err) } // dockerIgnoreFile @@ -64,7 +65,7 @@ func readExcludes(dir string, noImplicitIgnore bool, useDockerIgnore bool) ([]st if useDockerIgnore { dockerExists, err = fileutil.FileExists(dockerIgnoreFilePath) if err != nil { - return nil, errors.Wrapf(err, "failed to check if %s exists", dockerIgnoreFilePath) + return nil, fmt.Errorf("failed to check if %s exists: %w", dockerIgnoreFilePath, err) } } @@ -94,13 +95,13 @@ func readExcludes(dir string, noImplicitIgnore bool, useDockerIgnore bool) ([]st f, err := os.Open(filePath) // #nosec G304 if err != nil { - return nil, errors.Wrapf(err, "read %s", filePath) + return nil, fmt.Errorf("read %s: %w", filePath, err) } defer f.Close() excludes, err := ignorefile.ReadAll(f) if err != nil { - return nil, errors.Wrapf(err, "parse %s", filePath) + return nil, fmt.Errorf("parse %s: %w", filePath, err) } return append(excludes, defaultExcludes...), nil diff --git a/buildcontext/git.go b/buildcontext/git.go index ebee151983..e545fe5b04 100644 --- a/buildcontext/git.go +++ b/buildcontext/git.go @@ -24,7 +24,6 @@ import ( "github.com/moby/buildkit/client/llb" gwclient "github.com/moby/buildkit/frontend/gateway/client" buildkitgitutil "github.com/moby/buildkit/util/gitutil" - "github.com/pkg/errors" ) const ( @@ -72,13 +71,13 @@ func (gr *gitResolver) expandWildcard( ctx context.Context, gwClient gwclient.Client, platr *platutil.Resolver, target domain.Target, pattern string, ) ([]string, error) { if !target.IsRemote() { - return nil, errors.Errorf("unexpected local reference %s", target.String()) + return nil, fmt.Errorf("unexpected local reference %s", target.String()) } rgp, _, subDir, err := gr.resolveGitProject(ctx, gwClient, platr, target) if err != nil { - return nil, errors.Wrapf(err, "failed resolving git project [platform: %s/%s]", - platr.LLBNative().OS, platr.LLBNative().Architecture) + return nil, fmt.Errorf("failed resolving git project [platform: %s/%s]: %w", + platr.LLBNative().OS, platr.LLBNative().Architecture, err) } fullPattern := filepath.Join(subDir, pattern) @@ -114,13 +113,13 @@ func (gr *gitResolver) resolveEarthProject( featureFlagOverrides string, ) (*Data, error) { if !ref.IsRemote() { - return nil, errors.Errorf("unexpected local reference %s", ref.String()) + return nil, fmt.Errorf("unexpected local reference %s", ref.String()) } rgp, gitURL, subDir, err := gr.resolveGitProject(ctx, gwClient, platr, ref) if err != nil { - return nil, errors.Wrapf(err, "failed resolving git project [platform: %s/%s]", - platr.LLBNative().OS, platr.LLBNative().Architecture) + return nil, fmt.Errorf("failed resolving git project [platform: %s/%s]: %w", + platr.LLBNative().OS, platr.LLBNative().Architecture, err) } var buildContextFactory llbfactory.Factory @@ -143,7 +142,7 @@ func (gr *gitResolver) resolveEarthProject( rgp.state, []string{subDir}, platr.Scratch(), "./", false, false, false, "root:root", nil, false, false, false, llb.WithCustomNamef("%sCOPY git context %s", vm.ToVertexPrefix(), ref.String())) if err != nil { - return nil, errors.Wrap(err, "copyOp failed in resolveEarthProject") + return nil, fmt.Errorf("copyOp failed in resolveEarthProject: %w", err) } buildContextFactory = llbfactory.PreconstructedState(copyState) @@ -162,7 +161,7 @@ func (gr *gitResolver) resolveEarthProject( localBuildFileValue, err := gr.buildFileCache.Do(ctx, key, func(ctx context.Context, _ any) (any, error) { earthfileTmpDir, inErr := os.MkdirTemp(os.TempDir(), "earthly-git") if inErr != nil { - return nil, errors.Wrap(inErr, "create temp dir for Earthfile") + return nil, fmt.Errorf("create temp dir for Earthfile: %w", inErr) } gr.cleanCollection.Add(func() error { @@ -171,9 +170,10 @@ func (gr *gitResolver) resolveEarthProject( gitState, inErr := llbutil.StateToRef( ctx, gwClient, rgp.state, false, - platr.SubResolver(platutil.NativePlatform), nil) + platr.SubResolver(platutil.NativePlatform), nil, + ) if inErr != nil { - return nil, errors.Wrap(inErr, "state to ref git meta") + return nil, fmt.Errorf("state to ref git meta: %w", inErr) } bf, inErr := detectBuildFileInRef(ctx, ref, gitState, subDir) @@ -185,14 +185,14 @@ func (gr *gitResolver) resolveEarthProject( Filename: bf, }) if inErr != nil { - return nil, errors.Wrap(inErr, "read build file") + return nil, fmt.Errorf("read build file: %w", inErr) } localBuildFilePath := filepath.Join(earthfileTmpDir, path.Base(bf)) inErr = os.WriteFile(localBuildFilePath, bfBytes, 0o700) // #nosec G306 if inErr != nil { - return nil, errors.Wrapf(inErr, "write build file to tmp dir at %s", localBuildFilePath) + return nil, fmt.Errorf("write build file to tmp dir at %s: %w", localBuildFilePath, inErr) } var ftrs *features.Features @@ -257,7 +257,7 @@ func (gr *gitResolver) resolveGitProject( gitURL, subDir, keyScans, sshCommand, err = gr.gitLookup.GetCloneURL(ctx, ref.GetGitURL()) if err != nil { - return nil, "", "", errors.Wrap(err, "failed to get url for cloning") + return nil, "", "", fmt.Errorf("failed to get url for cloning: %w", err) } // Check the cache first. @@ -300,7 +300,8 @@ func (gr *gitResolver) resolveGitProject( opImg := pllb.Image( gitImage, llb.MarkImageInternal, llb.ResolveModePreferLocal, - llb.Platform(platr.LLBNative())) + llb.Platform(platr.LLBNative()), + ) // Get git hash. gitHashOpts := []llb.RunOption{ @@ -338,9 +339,10 @@ func (gr *gitResolver) resolveGitProject( gitMetaRef, err = llbutil.StateToRef( ctx, gwClient, gitMetaState, noCache, - platr.SubResolver(platutil.NativePlatform), nil) + platr.SubResolver(platutil.NativePlatform), nil, + ) if err != nil { - return nil, errors.Wrap(err, "state to ref git meta") + return nil, fmt.Errorf("state to ref git meta: %w", err) } var unameM []byte @@ -349,7 +351,7 @@ func (gr *gitResolver) resolveGitProject( Filename: "uname-m", }) if err != nil { - return nil, errors.Wrap(err, "read uname-m") + return nil, fmt.Errorf("read uname-m: %w", err) } var imgArch string @@ -381,7 +383,7 @@ func (gr *gitResolver) resolveGitProject( Filename: name, }) if err != nil { - return nil, errors.Wrap(err, "read "+name) + return nil, fmt.Errorf("%s: %w", "read "+name, err) } } @@ -389,7 +391,7 @@ func (gr *gitResolver) resolveGitProject( gitBranch, err = gr.readGitBranch(ctx, gitMetaRef) if err != nil { - return nil, errors.Wrap(err, "read git-branch") + return nil, fmt.Errorf("read git-branch: %w", err) } isNotHead := func(s string) bool { diff --git a/buildcontext/gitlookup.go b/buildcontext/gitlookup.go index c8376207ee..b9ac8c2784 100644 --- a/buildcontext/gitlookup.go +++ b/buildcontext/gitlookup.go @@ -6,6 +6,7 @@ import ( "crypto/hmac" "crypto/sha1" // #nosec G505 "encoding/base64" + "errors" "fmt" "maps" "net" @@ -23,7 +24,7 @@ import ( "github.com/EarthBuild/earthbuild/util/stringutil" "github.com/jdxcode/netrc" "github.com/moby/buildkit/util/sshutil" - "github.com/pkg/errors" + "golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh/agent" "golang.org/x/crypto/ssh/knownhosts" @@ -99,7 +100,7 @@ func NewGitLookup(console conslogging.ConsoleLogger, sshAuthSock string) *GitLoo } // ErrNoMatch occurs when no git matcher is found. -var ErrNoMatch = errors.Errorf("no git match found") +var ErrNoMatch = errors.New("no git match found") // DisableSSH changes all git matchers from ssh to https. func (gl *GitLookup) DisableSSH() { @@ -143,23 +144,23 @@ func (gl *GitLookup) AddMatcher( p := gitProtocol(protocol) if p == httpProtocol && password != "" { - return errors.Errorf("using a password with http for %s is insecure", name) + return fmt.Errorf("using a password with http for %s is insecure", name) } if sub != "" && (port != 0 || prefix != "") { - return errors.Errorf("unable to use substitution in combination with port or prefix values for %s git config", name) + return fmt.Errorf("unable to use substitution in combination with port or prefix values for %s git config", name) } re, err := regexp.Compile(pattern) if err != nil { - return errors.Wrapf(err, "failed to compile regex %s", pattern) + return fmt.Errorf("failed to compile regex %s: %w", pattern, err) } switch p { case httpProtocol, httpsProtocol, sshProtocol, autoProtocol: break default: - return errors.Errorf("unsupported git protocol %q", protocol) + return fmt.Errorf("unsupported git protocol %q", protocol) } gm := &gitMatcher{ @@ -232,12 +233,12 @@ func isHashedHost(hashAndSalt, hostname string) (bool, error) { salt, err := base64.StdEncoding.DecodeString(splits[0]) if err != nil { - return false, errors.Wrap(err, "failed to decode known_hosts salt") + return false, fmt.Errorf("failed to decode known_hosts salt: %w", err) } hash, err := base64.StdEncoding.DecodeString(splits[1]) if err != nil { - return false, errors.Wrap(err, "failed to decode known_hosts hash") + return false, fmt.Errorf("failed to decode known_hosts hash: %w", err) } hostnameHash := hashHost(hostname, salt) @@ -249,7 +250,7 @@ func isHashedHost(hashAndSalt, hostname string) (bool, error) { if hasPort(hostname) { host, _, err := net.SplitHostPort(hostname) if err != nil { - return false, errors.Wrapf(err, "SplitHostPort on %q failed", hostname) + return false, fmt.Errorf("SplitHostPort on %q failed: %w", hostname, err) } hostnameHash := hashHost(host, salt) @@ -307,7 +308,7 @@ func parseKeyScanIfHostMatches(keyScan, hostname string) (keyAlg, keyData string host, _, err = net.SplitHostPort(hostname) if err != nil { - return "", "", errors.Wrapf(err, "SplitHostPort on %q failed", hostname) + return "", "", fmt.Errorf("SplitHostPort on %q failed: %w", hostname, err) } if scannedHostname != host { @@ -494,7 +495,7 @@ func (gl *GitLookup) lookupNetRCCredential(host string) (login, password string, machine := n.Machine(host) if machine == nil { - return "", "", errors.Wrapf(errNoRCHostEntry, "failed to lookup netrc entry for %s", host) + return "", "", fmt.Errorf("failed to lookup netrc entry for %s: %w", host, errNoRCHostEntry) } login = n.Machine(host).Get("login") @@ -508,7 +509,7 @@ func (*GitLookup) getNetrc() (*netrc.Netrc, error) { if content != "" { n, err := netrc.ParseString(content) if err != nil { - return nil, errors.Wrap(err, "failed to parse NETRC_CONTENT data") + return nil, fmt.Errorf("failed to parse NETRC_CONTENT data: %w", err) } return n, nil @@ -518,7 +519,7 @@ func (*GitLookup) getNetrc() (*netrc.Netrc, error) { if path != "" { n, err := netrc.Parse(path) if err != nil { - return nil, errors.Wrapf(err, "failed to parse netrc file: %s", path) + return nil, fmt.Errorf("failed to parse netrc file: %s: %w", path, err) } return n, nil @@ -529,7 +530,7 @@ func (*GitLookup) getNetrc() (*netrc.Netrc, error) { n, err := netrc.Parse(path) if err != nil { - return nil, errors.Wrap(err, "failed to parse default .netrc file") + return nil, fmt.Errorf("failed to parse default .netrc file: %w", err) } return n, nil @@ -615,7 +616,7 @@ func (gl *GitLookup) makeCloneURL( } if len(keyScans) == 0 && m.strictHostKeyChecking { - return "", nil, "", errors.Errorf("no known_hosts entries exist for %s", host) + return "", nil, "", fmt.Errorf("no known_hosts entries exist for %s", host) } case httpProtocol: if user != "" || password != "" { @@ -637,7 +638,7 @@ func (gl *GitLookup) makeCloneURL( gitURL = "https://" + userAndPass + host + "/" + gitPath default: - return "", nil, "", errors.Errorf("unsupported protocol: %s", configuredProtocol) + return "", nil, "", fmt.Errorf("unsupported protocol: %s", configuredProtocol) } return gitURL, keyScans, m.sshCommand, nil @@ -731,7 +732,7 @@ func (gl *GitLookup) GetCloneURL( } if !m.re.MatchString(path) { - return "", "", nil, "", errors.Errorf("failed to determine git path to clone for %q", path) + return "", "", nil, "", fmt.Errorf("failed to determine git path to clone for %q", path) } gitURL = m.re.ReplaceAllString(path, m.sub) @@ -748,7 +749,7 @@ func (gl *GitLookup) GetCloneURL( } if len(keyScans) == 0 && m.strictHostKeyChecking { - return "", "", nil, "", errors.Errorf("no known_hosts entries exist for substituted host %s", subHost) + return "", "", nil, "", fmt.Errorf("no known_hosts entries exist for substituted host %s", subHost) } } @@ -772,7 +773,7 @@ func (gl *GitLookup) ConvertCloneURL( case HTTPProtocol, HTTPSProtocol: splits := strings.SplitN(remote, "/", 2) if len(splits) != 2 { - return "", nil, "", errors.Errorf("failed to split path from host in %s", remote) + return "", nil, "", fmt.Errorf("failed to split path from host in %s", remote) } host = splits[0] @@ -781,7 +782,7 @@ func (gl *GitLookup) ConvertCloneURL( if sshutil.IsImplicitSSHTransport(inURL) { splits := strings.SplitN(remote, ":", 2) if len(splits) != 2 { - return "", nil, "", errors.Errorf("failed to split path from host in %s", remote) + return "", nil, "", fmt.Errorf("failed to split path from host in %s", remote) } host = splits[0] @@ -791,7 +792,7 @@ func (gl *GitLookup) ConvertCloneURL( u, err = url.Parse(inURL) if err != nil { - return "", nil, "", errors.Wrapf(err, "failed to parse %s", inURL) + return "", nil, "", fmt.Errorf("failed to parse %s: %w", inURL, err) } if u.Scheme != "ssh" { @@ -802,7 +803,7 @@ func (gl *GitLookup) ConvertCloneURL( gitPath = u.Path } default: - return "", nil, "", errors.Errorf("unsupported git protocol %v", protocol) + return "", nil, "", fmt.Errorf("unsupported git protocol %v", protocol) } m := gl.getGitMatcherByName(host) @@ -815,7 +816,7 @@ func (gl *GitLookup) ConvertCloneURL( path := host + strings.TrimSuffix(gitPath, ".git") if !m.re.MatchString(path) { - return "", nil, "", errors.Errorf("failed to determine git path to clone for %q", path) + return "", nil, "", fmt.Errorf("failed to determine git path to clone for %q", path) } gitURL = m.re.ReplaceAllString(path, m.sub) @@ -830,7 +831,7 @@ func (gl *GitLookup) ConvertCloneURL( } if len(keyScans) == 0 && m.strictHostKeyChecking { - return "", nil, "", errors.Errorf("no known_hosts entries exist for substituted host %s", subHost) + return "", nil, "", fmt.Errorf("no known_hosts entries exist for substituted host %s", subHost) } } @@ -840,7 +841,7 @@ func (gl *GitLookup) ConvertCloneURL( func loadKnownHostsFromPath(path string) ([]string, error) { knownHostsExists, err := fileutil.FileExists(path) if err != nil { - return nil, errors.Wrapf(err, "failed to check if %s exists", path) + return nil, fmt.Errorf("failed to check if %s exists: %w", path, err) } if !knownHostsExists { @@ -849,7 +850,7 @@ func loadKnownHostsFromPath(path string) ([]string, error) { b, err := os.ReadFile(path) // #nosec G304 if err != nil { - return nil, errors.Wrapf(err, "failed to read %s", path) + return nil, fmt.Errorf("failed to read %s: %w", path, err) } return knownHostsToKeyScans(string(b)), nil @@ -858,7 +859,7 @@ func loadKnownHostsFromPath(path string) ([]string, error) { func loadKnownHosts() ([]string, error) { homeDir, err := os.UserHomeDir() if err != nil { - return nil, errors.Wrap(err, "failed to get user home dir") + return nil, fmt.Errorf("failed to get user home dir: %w", err) } knownHosts, err := loadKnownHostsFromPath(filepath.Join(homeDir, ".ssh/known_hosts")) diff --git a/buildcontext/local.go b/buildcontext/local.go index 036a99053a..41b7840201 100644 --- a/buildcontext/local.go +++ b/buildcontext/local.go @@ -2,6 +2,7 @@ package buildcontext import ( "context" + "errors" "fmt" "path/filepath" "strings" @@ -15,7 +16,6 @@ import ( "github.com/EarthBuild/earthbuild/util/syncutil/synccache" "github.com/moby/buildkit/client/llb" gwclient "github.com/moby/buildkit/frontend/gateway/client" - "github.com/pkg/errors" ) type localResolver struct { @@ -33,7 +33,7 @@ func (lr *localResolver) resolveLocal( featureFlagOverrides string, ) (*Data, error) { if ref.IsRemote() { - return nil, errors.Errorf("unexpected remote target %s", ref.String()) + return nil, fmt.Errorf("unexpected remote target %s", ref.String()) } metadataValue, err := lr.gitMetaCache.Do(ctx, ref.GetLocalPath(), func(ctx context.Context, _ any) (any, error) { diff --git a/buildcontext/parsefeatures.go b/buildcontext/parsefeatures.go index c9a0968e69..fbaf1a18c4 100644 --- a/buildcontext/parsefeatures.go +++ b/buildcontext/parsefeatures.go @@ -40,7 +40,8 @@ func parseFeatures( console.Printf( "NOTE: The %s feature is enabled by default under VERSION %s, "+ "and can be safely removed from the VERSION command", - strings.Join(warningStrs, ", "), ftrs.Version()) + strings.Join(warningStrs, ", "), ftrs.Version(), + ) } err = features.ApplyFlagOverrides(ftrs, featureFlagOverrides) diff --git a/buildcontext/provider/provider.go b/buildcontext/provider/provider.go index 529d1952da..9701505020 100644 --- a/buildcontext/provider/provider.go +++ b/buildcontext/provider/provider.go @@ -4,6 +4,7 @@ package provider import ( + "errors" "os" "strings" "sync" @@ -14,7 +15,7 @@ import ( "github.com/moby/buildkit/session" "github.com/moby/buildkit/session/filesync" - "github.com/pkg/errors" + "github.com/sirupsen/logrus" "github.com/tonistiigi/fsutil" fstypes "github.com/tonistiigi/fsutil/types" @@ -235,7 +236,7 @@ var supportedProtocols = []protocol{ } func sendDiffCopy(stream filesync.Stream, fs fsutil.FS, progress progressCb, verbose fsutil.VerboseProgressCB) error { - return errors.WithStack(fsutil.Send(stream.Context(), stream, fs, progress, verbose)) + return fsutil.Send(stream.Context(), stream, fs, progress, verbose) } func recvDiffCopy( @@ -262,10 +263,10 @@ func recvDiffCopy( ch = cu.ContentHasher() } - return errors.WithStack(fsutil.Receive(ds.Context(), ds, dest, fsutil.ReceiveOpt{ + return fsutil.Receive(ds.Context(), ds, dest, fsutil.ReceiveOpt{ NotifyHashed: cf, ContentHasher: ch, ProgressCb: progress, Filter: fsutil.FilterFunc(filter), - })) + }) } diff --git a/buildcontext/resolver.go b/buildcontext/resolver.go index 530656b7ac..0e0eda4aa7 100644 --- a/buildcontext/resolver.go +++ b/buildcontext/resolver.go @@ -18,7 +18,6 @@ import ( "github.com/EarthBuild/earthbuild/util/syncutil/synccache" gwclient "github.com/moby/buildkit/frontend/gateway/client" buildkitgitutil "github.com/moby/buildkit/util/gitutil" - "github.com/pkg/errors" ) // DockerfileMetaTarget is a target name prefix which signals the resolver that the build file is a @@ -96,7 +95,7 @@ func (r *Resolver) ExpandWildcard( if parentTarget.IsRemote() { matches, err := r.gr.expandWildcard(ctx, gwClient, platr, parentTarget, target.GetLocalPath()) if err != nil { - return nil, errors.Wrap(err, "failed to expand remote BUILD target path") + return nil, fmt.Errorf("failed to expand remote BUILD target path: %w", err) } return matches, nil @@ -108,7 +107,7 @@ func (r *Resolver) ExpandWildcard( // include *'s (expanded below), but that shouldn't be a problem. ref, err := domain.JoinReferences(parentTarget, target) if err != nil { - return nil, errors.Wrap(err, "failed to join references") + return nil, fmt.Errorf("failed to join references: %w", err) } target, ok := ref.(domain.Target) @@ -118,7 +117,7 @@ func (r *Resolver) ExpandWildcard( matches, err := fileutil.GlobDirs(target.GetLocalPath()) if err != nil { - return nil, errors.Wrap(err, "failed to expand BUILD target path") + return nil, fmt.Errorf("failed to expand BUILD target path: %w", err) } // Here, the relative path is reconstructed from the glob results and the @@ -128,7 +127,7 @@ func (r *Resolver) ExpandWildcard( for _, match := range matches { rel, err := filepath.Rel(parentTarget.GetLocalPath(), match) if err != nil { - return nil, errors.Wrap(err, "failed to resolve relative path") + return nil, fmt.Errorf("failed to resolve relative path: %w", err) } ret = append(ret, rel) @@ -143,7 +142,7 @@ func (r *Resolver) Resolve( ctx context.Context, gwClient gwclient.Client, platr *platutil.Resolver, ref domain.Reference, ) (*Data, error) { if ref.IsUnresolvedImportReference() { - return nil, errors.Errorf("cannot resolve non-dereferenced import ref %s", ref.String()) + return nil, fmt.Errorf("cannot resolve non-dereferenced import ref %s", ref.String()) } var ( @@ -201,7 +200,7 @@ func (r *Resolver) parseEarthfile(ctx context.Context, path string) (earthfile.T ef, ok := efValue.(earthfile.Tree) if !ok { - return earthfile.Tree{}, errors.Errorf("want earthfile.Tree, got %T", efValue) + return earthfile.Tree{}, fmt.Errorf("want earthfile.Tree, got %T", efValue) } return ef, nil diff --git a/builder/builder.go b/builder/builder.go index 638d036a73..10c168e4d4 100644 --- a/builder/builder.go +++ b/builder/builder.go @@ -3,6 +3,7 @@ package builder import ( "context" + "errors" "fmt" "io" "os" @@ -42,7 +43,7 @@ import ( "github.com/moby/buildkit/util/apicaps" "github.com/moby/buildkit/util/entitlements" buildkitgitutil "github.com/moby/buildkit/util/gitutil" - "github.com/pkg/errors" + "golang.org/x/sync/errgroup" ) @@ -151,7 +152,8 @@ func NewBuilder(opt Opt) (*Builder, error) { } b.resolver = buildcontext.NewResolver( opt.CleanCollection, opt.GitLookup, opt.Console, opt.FeatureFlagOverrides, opt.GitBranchOverride, - opt.GitLFSInclude, opt.GitLogLevel, opt.GitImage) + opt.GitLFSInclude, opt.GitLogLevel, opt.GitImage, + ) return b, nil } @@ -226,18 +228,18 @@ func useSecondaryProxy() (bool, error) { return false, nil } - return false, errors.Wrapf(err, "failed to stat %s", versionFile) + return false, fmt.Errorf("failed to stat %s: %w", versionFile, err) } f, err := os.Open(versionFile) if err != nil { - return false, errors.Wrapf(err, "failed to open %s", versionFile) + return false, fmt.Errorf("failed to open %s: %w", versionFile, err) } defer f.Close() data, err := io.ReadAll(f) if err != nil { - return false, errors.Wrapf(err, "failed to read %s", versionFile) + return false, fmt.Errorf("failed to read %s: %w", versionFile, err) } s := string(data) @@ -408,7 +410,8 @@ func (b *Builder) convertAndBuild( if isMultiPlatform[saveImage.DockerTag] && noManifestListImgs[saveImage.DockerTag] { return nil, fmt.Errorf( "cannot save image %s defined multiple times, but declared as SAVE IMAGE --no-manifest-list", - saveImage.DockerTag) + saveImage.DockerTag, + ) } } } @@ -465,9 +468,10 @@ func (b *Builder) convertAndBuild( if saveImage.CheckDuplicate && saveImage.DockerTag != "" { if _, found := platformImgNames[platformImgName]; found { - return nil, errors.Errorf( + return nil, fmt.Errorf( "image %s is defined multiple times for the same platform (%s)", - saveImage.DockerTag, platformImgName) + saveImage.DockerTag, platformImgName, + ) } platformImgNames[platformImgName] = true @@ -481,7 +485,8 @@ func (b *Builder) convertAndBuild( if shouldPush { _, err = gwCrafter.AddPushImageEntry( ref, imageIndex, saveImage.DockerTag, shouldPush, saveImage.InsecurePush, - saveImage.Image, []byte(platformStr)) + saveImage.Image, []byte(platformStr), + ) if err != nil { return nil, err } @@ -510,14 +515,16 @@ func (b *Builder) convertAndBuild( manifestLists[saveImage.DockerTag], dockerutil.Manifest{ ImageName: platformImgName, Platform: resolvedPlat, - }) + }, + ) } } else { if saveImage.CheckDuplicate && saveImage.DockerTag != "" { if _, found := singPlatImgNames[saveImage.DockerTag]; found { - return nil, errors.Errorf( + return nil, fmt.Errorf( "image %s is defined multiple times for the same default platform", - saveImage.DockerTag) + saveImage.DockerTag, + ) } singPlatImgNames[saveImage.DockerTag] = true @@ -526,7 +533,8 @@ func (b *Builder) convertAndBuild( localRegPullID := exportCoordinator.AddImage(gwClient.BuildOpts().SessionID, saveImage.DockerTag, nil) refPrefix, err := gwCrafter.AddPushImageEntry( - ref, imageIndex, saveImage.DockerTag, shouldPush, saveImage.InsecurePush, saveImage.Image, nil) + ref, imageIndex, saveImage.DockerTag, shouldPush, saveImage.InsecurePush, saveImage.Image, nil, + ) if err != nil { return nil, err } @@ -551,7 +559,8 @@ func (b *Builder) convertAndBuild( for _, saveLocal := range b.targetPhaseArtifacts(sts) { ref, err := b.artifactStateToRef( childCtx, gwClient, sts.SeparateArtifactsState[saveLocal.Index], - sts.PlatformResolver) + sts.PlatformResolver, + ) if err != nil { return nil, err } @@ -619,7 +628,8 @@ func (b *Builder) convertAndBuild( } err := dockerutil.LoadDockerManifest( - ctx, b.opt.Console, b.opt.ContainerFrontend, parentImageName, children, opt.PlatformResolver) + ctx, b.opt.Console, b.opt.ContainerFrontend, parentImageName, children, opt.PlatformResolver, + ) if err != nil { return err } @@ -637,7 +647,7 @@ func (b *Builder) convertAndBuild( err := dockerutil.LoadDockerTar(childCtx, b.opt.ContainerFrontend, pipeR) if err != nil { - return errors.Wrapf(err, "load docker tar") + return fmt.Errorf("load docker tar: %w", err) } if manifestKey == "" { @@ -651,7 +661,7 @@ func (b *Builder) convertAndBuild( } onArtifact := func(_ context.Context, index string, _ domain.Artifact, _, destPath string) (string, error) { if !opt.LocalArtifactWhiteList.Exists(destPath) { - err := errors.Errorf("dest path %s is not in the whitelist: %+v", destPath, opt.LocalArtifactWhiteList.AsList()) + err := fmt.Errorf("dest path %s is not in the whitelist: %+v", destPath, opt.LocalArtifactWhiteList.AsList()) return "", err } @@ -664,7 +674,7 @@ func (b *Builder) convertAndBuild( err = os.MkdirAll(artifactDir, 0o755) // #nosec G301 if err != nil { - return "", errors.Wrapf(err, "create dir %s", artifactDir) + return "", fmt.Errorf("create dir %s: %w", artifactDir, err) } return artifactDir, nil @@ -683,7 +693,7 @@ func (b *Builder) convertAndBuild( for _, imgToPull := range imagesToPull { manifest, dockerTag, ok := exportCoordinator.GetImage(imgToPull) if !ok { - return errors.Errorf("unrecognized image to pull %s", imgToPull) + return fmt.Errorf("unrecognized image to pull %s", imgToPull) } if manifest != nil { @@ -705,7 +715,8 @@ func (b *Builder) convertAndBuild( } err = dockerutil.LoadDockerManifest( - ctx, b.opt.Console, b.opt.ContainerFrontend, parentImageName, children, opt.PlatformResolver) + ctx, b.opt.Console, b.opt.ContainerFrontend, parentImageName, children, opt.PlatformResolver, + ) if err != nil { return err } @@ -720,7 +731,7 @@ func (b *Builder) convertAndBuild( err := b.s.buildMainMulti(ctx, buildFunc, onImage, onArtifact, onFinalArtifact, onPull, b.opt.Console) if err != nil { - return nil, errors.Wrapf(err, "build main") + return nil, fmt.Errorf("build main: %w", err) } if opt.PrintPhases { @@ -750,7 +761,7 @@ func (b *Builder) convertAndBuild( if hasRunPush { err = b.s.buildMainMulti(ctx, buildFunc, onImage, onArtifact, onFinalArtifact, onPull, b.opt.Console) if err != nil { - return nil, errors.Wrapf(err, "build push") + return nil, fmt.Errorf("build push: %w", err) } } } @@ -774,7 +785,8 @@ func (b *Builder) convertAndBuild( } err = saveartifactlocally.SaveArtifactLocally( - exportCoordinator, b.opt.Console, *opt.OnlyArtifact, outDir, opt.OnlyArtifactDestPath, mts.Final.ID, false) + exportCoordinator, b.opt.Console, *opt.OnlyArtifact, outDir, opt.OnlyArtifactDestPath, mts.Final.ID, false, + ) if err != nil { return nil, err } @@ -851,7 +863,8 @@ func (b *Builder) convertAndBuild( } err = saveartifactlocally.SaveArtifactLocally( - exportCoordinator, b.opt.Console, artifact, artifactDir, saveLocal.DestPath, sts.ID, saveLocal.IfExists) + exportCoordinator, b.opt.Console, artifact, artifactDir, saveLocal.DestPath, sts.ID, saveLocal.IfExists, + ) if err != nil { return nil, err } @@ -885,7 +898,8 @@ func (b *Builder) convertAndBuild( } err = saveartifactlocally.SaveArtifactLocally( - exportCoordinator, b.opt.Console, artifact, artifactDir, saveLocal.DestPath, sts.ID, saveLocal.IfExists) + exportCoordinator, b.opt.Console, artifact, artifactDir, saveLocal.DestPath, sts.ID, saveLocal.IfExists, + ) if err != nil { return nil, err } @@ -903,7 +917,8 @@ func (b *Builder) convertAndBuild( for _, saveImage := range sts.RunPush.SaveImages { pushConsole.Printf( "Did not push image %s as evaluating the image would "+ - "have caused a RUN --push to execute", saveImage.DockerTag) + "have caused a RUN --push to execute", saveImage.DockerTag, + ) outputConsole.Printf("Did not output image %s locally, "+ "as evaluating the image would have caused a "+ "RUN --push to execute", saveImage.DockerTag) @@ -1004,7 +1019,8 @@ func (b *Builder) stateToRef( return llbutil.StateToRef( ctx, gwClient, state, noCache, - platr, b.opt.CacheImports.AsSlice()) + platr, b.opt.CacheImports.AsSlice(), + ) } func (b *Builder) artifactStateToRef( @@ -1014,7 +1030,8 @@ func (b *Builder) artifactStateToRef( return llbutil.StateToRef( ctx, gwClient, state, noCache, - platr, b.opt.CacheImports.AsSlice()) + platr, b.opt.CacheImports.AsSlice(), + ) } func (b *Builder) tempEarthOutDir() (string, error) { @@ -1025,13 +1042,13 @@ func (b *Builder) tempEarthOutDir() (string, error) { err = os.MkdirAll(tmpParentDir, 0o755) // #nosec G301 if err != nil { - err = errors.Wrapf(err, "unable to create dir %s", tmpParentDir) + err = fmt.Errorf("unable to create dir %s: %w", tmpParentDir, err) return } b.outDir, err = os.MkdirTemp(tmpParentDir, "tmp") if err != nil { - err = errors.Wrap(err, "mk temp dir for artifacts") + err = fmt.Errorf("mk temp dir for artifacts: %w", err) return } diff --git a/builder/image_solver.go b/builder/image_solver.go index 1d0b0dc9f5..473d87678a 100644 --- a/builder/image_solver.go +++ b/builder/image_solver.go @@ -5,6 +5,7 @@ import ( "context" "encoding/base64" "encoding/json" + "errors" "fmt" "io" "os" @@ -23,7 +24,6 @@ import ( "github.com/moby/buildkit/session/pullping" "github.com/moby/buildkit/util/entitlements" ocispecs "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" "golang.org/x/sync/errgroup" ) @@ -48,7 +48,7 @@ type tarImageSolver struct { func (s *tarImageSolver) newSolveOpt(img *image.Image, dockerTag string, w io.WriteCloser) (*client.SolveOpt, error) { imgJSON, err := json.Marshal(img) if err != nil { - return nil, errors.Wrap(err, "image json marshal") + return nil, fmt.Errorf("image json marshal: %w", err) } imports := s.cacheImports.AsSlice() @@ -87,14 +87,14 @@ func (s *tarImageSolver) SolveImage( dt, err := saveImage.State.Marshal(ctx, llb.Platform(platform)) if err != nil { - return errors.Wrap(err, "state marshal") + return fmt.Errorf("state marshal: %w", err) } pipeR, pipeW := io.Pipe() solveOpt, err := s.newSolveOpt(saveImage.Image, dockerTag, pipeW) if err != nil { - return errors.Wrap(err, "new solve opt") + return fmt.Errorf("new solve opt: %w", err) } ch := make(chan *client.SolveStatus) @@ -108,7 +108,7 @@ func (s *tarImageSolver) SolveImage( _, err = s.bkClient.Solve(ctx, dt, *solveOpt, ch) if err != nil { - return errors.Wrap(err, "solve") + return fmt.Errorf("solve: %w", err) } return nil @@ -133,7 +133,7 @@ func (s *tarImageSolver) SolveImage( eg.Go(func() error { file, err := os.Create(outFile) // #nosec G304 if err != nil { - return errors.Wrapf(err, "open file %s for writing", outFile) + return fmt.Errorf("open file %s for writing: %w", outFile, err) } defer file.Close() @@ -148,12 +148,12 @@ func (s *tarImageSolver) SolveImage( break } - return errors.Wrap(err, "pipe read") + return fmt.Errorf("pipe read: %w", err) } _, err = bufFile.Write(buf[:n]) if err != nil { - return errors.Wrap(err, "write chunk to file") + return fmt.Errorf("write chunk to file: %w", err) } } @@ -241,7 +241,7 @@ func (m *multiImageSolver) SolveImages( for i, img := range images { finalImageName, ok := onPullMap[img] if !ok { - return errors.Errorf("image %s not found in onPullMap", img) + return fmt.Errorf("image %s not found in onPullMap", img) } result := &states.ImageResult{ @@ -273,19 +273,20 @@ func (m *multiImageSolver) SolveImages( case exptypes.ExporterImageDescriptorKey: vdec, err := base64.StdEncoding.DecodeString(v) if err != nil { - return errors.Wrapf(err, "base64 decode img descriptor for img %s", img) + return fmt.Errorf("base64 decode img descriptor for img %s: %w", img, err) } result.ImageDescriptor = &ocispecs.Descriptor{} err = json.Unmarshal(vdec, result.ImageDescriptor) if err != nil { - return errors.Wrapf(err, "json unmarshal img descriptor for img %s", img) + return fmt.Errorf("json unmarshal img descriptor for img %s: %w", img, err) } result.ImageDigest = result.ImageDescriptor.Digest.String() result.FinalImageNameWithDigest = fmt.Sprintf( - "%s@%s", result.FinalImageName, result.ImageDigest) + "%s@%s", result.FinalImageName, result.ImageDigest, + ) case exptypes.ExporterConfigDigestKey: result.ConfigDigest = v default: @@ -405,7 +406,7 @@ func (m *multiImageSolver) addRefToResult( ref, err := llbutil. StateToRef(ctx, gwClient, saveImage.State, false, imageDef.MTS.Final.PlatformResolver, m.cacheImports.AsSlice()) if err != nil { - return errors.Wrap(err, "initial state to ref conversion") + return fmt.Errorf("initial state to ref conversion: %w", err) } refPrefix, err := gwCrafter.AddPushImageEntry(ref, imageIndex, imageDef.ImageName, false, false, saveImage.Image, nil) diff --git a/builder/solver.go b/builder/solver.go index db0a7738d1..1f28bae049 100644 --- a/builder/solver.go +++ b/builder/solver.go @@ -2,6 +2,8 @@ package builder import ( "context" + "errors" + "fmt" "io" "maps" @@ -19,12 +21,11 @@ import ( "github.com/moby/buildkit/session/pullping" "github.com/moby/buildkit/util/entitlements" "github.com/moby/buildkit/util/grpcerrors" - "github.com/pkg/errors" "golang.org/x/sync/errgroup" + // statusChanSize is used to ensure we consume all BK status messages without + // causing back-pressure that forces BK to cancel. ) -// statusChanSize is used to ensure we consume all BK status messages without -// causing back-pressure that forces BK to cancel. const statusChanSize = 500 type ( @@ -62,7 +63,7 @@ func (s *solver) buildMainMulti( solveOpt, err := s.newSolveOptMulti(ctx, eg, onImage, onArtifact, onFinalArtifact, onPullCallback, console) if err != nil { - return errors.Wrap(err, "new solve opt") + return fmt.Errorf("new solve opt: %w", err) } var buildErr error @@ -122,7 +123,7 @@ func (s *solver) newSolveOptMulti( if s.cacheExport != "" { cacheExportName, attrs, err := flagutil.ParseImageNameAndAttrs(s.cacheExport) if err != nil { - return nil, errors.Wrapf(err, "parse export cache error: %s", s.cacheExport) + return nil, fmt.Errorf("parse export cache error: %s: %w", s.cacheExport, err) } cacheExports = append(cacheExports, newCacheExportOpt(cacheExportName, attrs, false)) @@ -131,7 +132,7 @@ func (s *solver) newSolveOptMulti( if s.maxCacheExport != "" { maxCacheExportName, attrs, err := flagutil.ParseImageNameAndAttrs(s.maxCacheExport) if err != nil { - return nil, errors.Wrapf(err, "parse max export cache error: %s", s.maxCacheExport) + return nil, fmt.Errorf("parse max export cache error: %s: %w", s.maxCacheExport, err) } cacheExports = append(cacheExports, newCacheExportOpt(maxCacheExportName, attrs, true)) @@ -180,7 +181,7 @@ func (s *solver) newSolveOptMulti( artifact, err := domain.ParseArtifact(artifactStr) if err != nil { - return "", errors.Wrapf(err, "parse artifact %s", artifactStr) + return "", fmt.Errorf("parse artifact %s: %w", artifactStr, err) } return onArtifact(ctx, indexStr, artifact, srcPath, destPath) diff --git a/buildkitd/buildkitd.go b/buildkitd/buildkitd.go index 0806e3cbea..eb03bdb56d 100644 --- a/buildkitd/buildkitd.go +++ b/buildkitd/buildkitd.go @@ -4,6 +4,7 @@ package buildkitd import ( "context" "crypto/rsa" + "errors" "fmt" "net/url" "os" @@ -26,7 +27,6 @@ import ( "github.com/gofrs/flock" "github.com/moby/buildkit/client" _ "github.com/moby/buildkit/client/connhelper/dockercontainer" // Load "docker-container://" helper. - "github.com/pkg/errors" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -94,7 +94,7 @@ func NewClient( opts, err := addRequiredOpts(settings, opts...) if err != nil { - return nil, errors.Wrap(err, "add required client opts") + return nil, fmt.Errorf("add required client opts: %w", err) } isLocal := isLocalBuildkit(settings) @@ -109,7 +109,7 @@ func NewClient( info, workerInfo, err = waitForConnection(ctx, containerName, settings, fe, opts...) if err != nil { - return nil, errors.Wrap(err, "connect provided buildkit") + return nil, fmt.Errorf("connect provided buildkit: %w", err) } remoteConsole.Printf("...Done") @@ -119,7 +119,7 @@ func NewClient( bkClient, err = client.New(ctx, settings.BuildkitAddress, opts...) if err != nil { - return nil, errors.Wrap(err, "start provided buildkit") + return nil, fmt.Errorf("start provided buildkit: %w", err) } return bkClient, nil @@ -133,14 +133,14 @@ func NewClient( info, workerInfo, err := maybeStart(ctx, console, image, containerName, installationName, fe, settings, opts...) if err != nil { - return nil, errors.Wrap(err, "maybe start buildkitd") + return nil, fmt.Errorf("maybe start buildkitd: %w", err) } printBuildkitInfo(bkCons, info, workerInfo, earthVersion, isLocal, settings.HasConfiguredCacheSize()) bkClient, err := client.New(ctx, settings.BuildkitAddress, opts...) if err != nil { - return nil, errors.Wrap(err, "new buildkit client") + return nil, fmt.Errorf("new buildkit client: %w", err) } return bkClient, nil @@ -162,7 +162,7 @@ func ResetCache( opts, err := addRequiredOpts(settings, opts...) if err != nil { - return errors.Wrap(err, "add required client opts") + return fmt.Errorf("add required client opts: %w", err) } console. @@ -175,7 +175,7 @@ func ResetCache( isStarted, err := IsStarted(ctx, containerName, fe) if err != nil { - return errors.Wrap(err, "check is started buildkitd") + return fmt.Errorf("check is started buildkitd: %w", err) } if isStarted { @@ -240,9 +240,9 @@ func maybeStart( switch { case errors.Is(err, context.DeadlineExceeded): - return nil, nil, errors.Errorf("timeout waiting for other instance of earth to start buildkitd") + return nil, nil, errors.New("timeout waiting for other instance of earth to start buildkitd") case err != nil: - return nil, nil, errors.Wrapf(err, "try flock context %s", settings.StartUpLockPath) + return nil, nil, fmt.Errorf("try flock context %s: %w", settings.StartUpLockPath, err) default: defer func() { inErr := startLock.Unlock() @@ -261,7 +261,7 @@ func maybeStart( isStarted, err := IsStarted(ctx, containerName, fe) if err != nil { - return nil, nil, errors.Wrap(err, "check is started buildkitd") + return nil, nil, fmt.Errorf("check is started buildkitd: %w", err) } if isStarted { @@ -276,7 +276,7 @@ func maybeStart( info, workerInfo, err = maybeRestart(ctx, console, image, containerName, installationName, fe, settings, opts...) if err != nil { - return nil, nil, errors.Wrap(err, "maybe restart") + return nil, nil, fmt.Errorf("maybe restart: %w", err) } return info, workerInfo, nil @@ -288,23 +288,23 @@ func maybeStart( err = Start(ctx, console, image, containerName, installationName, fe, settings, false) if err != nil { - return nil, nil, errors.Wrap(err, "start") + return nil, nil, fmt.Errorf("start: %w", err) } info, workerInfo, err := WaitUntilStarted(ctx, console, containerName, settings.VolumeName, settings, fe, opts...) if err != nil { - return nil, nil, errors.Wrap(err, "wait until started") + return nil, nil, fmt.Errorf("wait until started: %w", err) } // check arch is correct runningContainerInfo, err := GetContainerInfo(ctx, containerName, fe) if err != nil { - return nil, nil, errors.Wrapf(err, "GetContainerInfo %s", containerName) + return nil, nil, fmt.Errorf("GetContainerInfo %s: %w", containerName, err) } currentImageInfo, err := GetImageInfo(ctx, runningContainerInfo.Image, fe) if err != nil { - return nil, nil, errors.Wrapf(err, "GetImageInfo %s", runningContainerInfo.Image) + return nil, nil, fmt.Errorf("GetImageInfo %s: %w", runningContainerInfo.Image, err) } if currentImageInfo.Architecture != runtime.GOARCH { @@ -336,12 +336,12 @@ func maybeRestart( runningContainerInfo, err := GetContainerInfo(ctx, containerName, fe) if err != nil { - return nil, nil, errors.Wrap(err, "could not get container info") + return nil, nil, fmt.Errorf("could not get container info: %w", err) } currentImageInfo, err := GetImageInfo(ctx, runningContainerInfo.Image, fe) if err != nil { - return nil, nil, errors.Wrap(err, "could not get image info") + return nil, nil, fmt.Errorf("could not get image info: %w", err) } if currentImageInfo.Architecture != runtime.GOARCH { @@ -371,14 +371,14 @@ func maybeRestart( hash, err = GetSettingsHash(ctx, containerName, fe) if err != nil { - return nil, nil, errors.Wrap(err, "could not get settings hash") + return nil, nil, fmt.Errorf("could not get settings hash: %w", err) } var hashOK bool hashOK, err = settings.VerifyHash(hash) if err != nil { - return nil, nil, errors.Wrap(err, "verify hash") + return nil, nil, fmt.Errorf("verify hash: %w", err) } useExistingContainer := false @@ -402,7 +402,7 @@ func maybeRestart( info, workerInfo, err = checkConnection(ctx, settings.BuildkitAddress, 5*time.Second, opts...) if err != nil { - return nil, nil, errors.Wrap(err, "could not connect to buildkitd to shut down container") + return nil, nil, fmt.Errorf("could not connect to buildkitd to shut down container: %w", err) } return info, workerInfo, nil @@ -419,7 +419,7 @@ func maybeRestart( info, workerInfo, err = checkConnection(ctx, settings.BuildkitAddress, 5*time.Second, opts...) if err != nil { - return nil, nil, errors.Wrap(err, "could not verify connection to buildkitd container") + return nil, nil, fmt.Errorf("could not verify connection to buildkitd container: %w", err) } return info, workerInfo, nil @@ -430,22 +430,22 @@ func maybeRestart( // Replace. err = Stop(ctx, containerName, fe) if err != nil { - return nil, nil, errors.Wrapf(err, "could not shut down container %q", containerName) + return nil, nil, fmt.Errorf("could not shut down container %q: %w", containerName, err) } err = WaitUntilStopped(ctx, containerName, settings.Timeout, fe) if err != nil { - return nil, nil, errors.Wrapf(err, "could not wait for container %q to stop", containerName) + return nil, nil, fmt.Errorf("could not wait for container %q to stop: %w", containerName, err) } err = Start(ctx, console, image, containerName, installationName, fe, settings, false) if err != nil { - return nil, nil, errors.Wrapf(err, "could not start container %q", containerName) + return nil, nil, fmt.Errorf("could not start container %q: %w", containerName, err) } info, workerInfo, err := WaitUntilStarted(ctx, console, containerName, settings.VolumeName, settings, fe, opts...) if err != nil { - return nil, nil, errors.Wrapf(err, "could not wait for container %q to start", containerName) + return nil, nil, fmt.Errorf("could not wait for container %q to start: %w", containerName, err) } bkCons.Printf("...Done\n") @@ -457,7 +457,7 @@ func maybeRestart( func RemoveExited(ctx context.Context, fe containerutil.ContainerFrontend, containerName string) error { infos, err := fe.ContainerInfo(ctx, containerName) if err != nil { - return errors.Wrapf(err, "get info to remove exited %s", containerName) + return fmt.Errorf("get info to remove exited %s: %w", containerName, err) } containerInfo, ok := infos[containerName] @@ -467,7 +467,7 @@ func RemoveExited(ctx context.Context, fe containerutil.ContainerFrontend, conta err = fe.ContainerRemove(ctx, false, containerName) if err != nil { - return errors.Wrapf(err, "remove exited %s", containerName) + return fmt.Errorf("remove exited %s: %w", containerName, err) } return nil @@ -484,7 +484,7 @@ func Start( ) error { settingsHash, err := settings.Hash() if err != nil { - return errors.Wrap(err, "settings hash") + return fmt.Errorf("settings hash: %w", err) } err = RemoveExited(ctx, fe, containerName) @@ -571,7 +571,7 @@ func Start( bkURL, err = url.Parse(settings.BuildkitAddress) if err != nil { - return errors.Wrap(err, "error parsing buildkit address url") + return fmt.Errorf("error parsing buildkit address url: %w", err) } if settings.UseTCP { @@ -600,7 +600,7 @@ func Start( if settings.UseTLS { if settings.TLSCA != "" { if exists, _ := fileutil.FileExists(settings.TLSCA); !exists { - return errors.Wrapf(os.ErrNotExist, "TLS CA file %q is missing", settings.TLSCA) + return fmt.Errorf("TLS CA file %q is missing: %w", settings.TLSCA, os.ErrNotExist) } volumeOpts = append(volumeOpts, containerutil.Mount{ @@ -613,7 +613,7 @@ func Start( if settings.ServerTLSCert != "" { if exists, _ := fileutil.FileExists(settings.ServerTLSCert); !exists { - return errors.Wrapf(os.ErrNotExist, "TLS certificate %q is missing", settings.ServerTLSCert) + return fmt.Errorf("TLS certificate %q is missing: %w", settings.ServerTLSCert, os.ErrNotExist) } volumeOpts = append(volumeOpts, containerutil.Mount{ @@ -626,7 +626,7 @@ func Start( if settings.ServerTLSKey != "" { if exists, _ := fileutil.FileExists(settings.ServerTLSKey); !exists { - return errors.Wrapf(os.ErrNotExist, "TLS private key %q is missing", settings.ServerTLSKey) + return fmt.Errorf("TLS private key %q is missing: %w", settings.ServerTLSKey, os.ErrNotExist) } volumeOpts = append(volumeOpts, containerutil.Mount{ @@ -681,7 +681,7 @@ func Start( AdditionalArgs: additionalArgs, }) if err != nil { - return errors.Wrap(err, "could not start buildkit") + return fmt.Errorf("could not start buildkit: %w", err) } return nil @@ -723,7 +723,7 @@ func WaitUntilStarted( expectedAddress := containerutil.DockerSchemePrefix + containerName if address != expectedAddress { // This shouldn't happen unless there's a programming error - return nil, nil, errors.Errorf("expected address to be %s, but got %s", expectedAddress, address) + return nil, nil, fmt.Errorf("expected address to be %s, but got %s", expectedAddress, address) } } // First, wait for the container to be marked as started. @@ -749,7 +749,7 @@ ContainerRunningLoop: } case <-ctxTimeout.Done(): - return nil, nil, errors.Errorf("timeout %s: buildkitd container did not start", opTimeout) + return nil, nil, fmt.Errorf("timeout %s: buildkitd container did not start", opTimeout) } } @@ -852,12 +852,11 @@ func waitForConnection( return info, workerInfo, nil case <-ctxTimeout.Done(): - // Try one last time. info, workerInfo, err := checkConnection(ctx, address, attemptTimeout, opts...) if err != nil { // We give up. - return nil, nil, errors.Wrapf(ErrBuildkitConnectionFailure, - "timeout %s: could not connect to buildkit: %s", opTimeout, err.Error()) + return nil, nil, fmt.Errorf("timeout %s: could not connect to buildkit: %s: %w", + opTimeout, err.Error(), ErrBuildkitConnectionFailure) } return info, workerInfo, nil @@ -926,7 +925,7 @@ func checkConnection( info, err = bkClient.Info(ctxTimeout) if err != nil { - s, ok := status.FromError(errors.Cause(err)) + s, ok := status.FromError(err) if ok && s.Code() == codes.Unimplemented { // Degrade gracefully. info = &client.Info{ @@ -961,7 +960,7 @@ func MaybePull( ) error { infos, err := fe.ImageInfo(ctx, image) if err != nil { - return errors.Wrap(err, "could not get container info") + return fmt.Errorf("could not get container info: %w", err) } if len(infos) > 0 { // the presence of an item implies its local @@ -974,7 +973,7 @@ func MaybePull( err = fe.ImagePull(ctx, image) if err != nil { - return errors.Wrapf(err, "could not pull %s", image) + return fmt.Errorf("could not pull %s: %w", image, err) } console. @@ -988,7 +987,7 @@ func MaybePull( func GetDockerVersion(ctx context.Context, fe containerutil.ContainerFrontend) (string, error) { info, err := fe.Information(ctx) if err != nil { - return "", errors.Wrap(err, "get info from frontend") + return "", fmt.Errorf("get info from frontend: %w", err) } return fmt.Sprintf("%#v", info), nil @@ -1004,7 +1003,7 @@ func GetLogs( logs, err := fe.ContainerLogs(ctx, containerName) if err != nil { - return "", errors.Wrap(err, "") + return "", fmt.Errorf(": %w", err) } if containerLogs, ok := logs[containerName]; ok { @@ -1024,7 +1023,7 @@ func GetContainerIP( infos, err := fe.ContainerInfo(ctx, containerName) if err != nil { - return "", errors.Wrap(err, "could not get container info to determine ip") + return "", fmt.Errorf("could not get container info to determine ip: %w", err) } if containerInfo, ok := infos[containerName]; ok { @@ -1055,7 +1054,7 @@ func WaitUntilStopped( return nil } case <-ctxTimeout.Done(): - return errors.Errorf("timeout %s: buildkitd did not stop", opTimeout) + return fmt.Errorf("timeout %s: buildkitd did not stop", opTimeout) } } } @@ -1064,7 +1063,7 @@ func WaitUntilStopped( func GetSettingsHash(ctx context.Context, containerName string, fe containerutil.ContainerFrontend) (string, error) { infos, err := fe.ContainerInfo(ctx, containerName) if err != nil { - return "", errors.Wrap(err, "get container info for settings") + return "", fmt.Errorf("get container info for settings: %w", err) } if containerInfo, ok := infos[containerName]; ok { @@ -1080,7 +1079,7 @@ func GetContainerInfo( ) (*containerutil.ContainerInfo, error) { infos, err := fe.ContainerInfo(ctx, containerName) if err != nil { - return nil, errors.Wrap(err, "get container info for current container image ID") + return nil, fmt.Errorf("get container info for current container image ID: %w", err) } if containerInfo, ok := infos[containerName]; ok { @@ -1096,7 +1095,7 @@ func GetImageInfo( ) (*containerutil.ImageInfo, error) { infos, err := fe.ImageInfo(ctx, image) if err != nil { - return nil, errors.Wrapf(err, "get image info %s", image) + return nil, fmt.Errorf("get image info %s: %w", image, err) } if info, ok := infos[image]; ok { @@ -1110,7 +1109,7 @@ func GetImageInfo( func GetAvailableImageID(ctx context.Context, image string, fe containerutil.ContainerFrontend) (string, error) { infos, err := fe.ImageInfo(ctx, image) if err != nil { - return "", errors.Wrap(err, "get output for available image ID") + return "", fmt.Errorf("get output for available image ID: %w", err) } return infos[image].ID, nil @@ -1119,7 +1118,7 @@ func GetAvailableImageID(ctx context.Context, image string, fe containerutil.Con func isContainerRunning(ctx context.Context, containerName string, fe containerutil.ContainerFrontend) (bool, error) { infos, err := fe.ContainerInfo(ctx, containerName) if err != nil { - return false, errors.Wrap(err, "failed to get container info while checking if running") + return false, fmt.Errorf("failed to get container info while checking if running: %w", err) } if containerInfo, ok := infos[containerName]; ok { @@ -1150,11 +1149,13 @@ func printBuildkitInfo( if info.BuildkitVersion.Version == unknown { bkCons.Warnf( "Warning: Buildkit version is unknown. This usually means that " + - "it's from a version lower than earth Buildkit v0.6.20") + "it's from a version lower than earth Buildkit v0.6.20", + ) } else { printFun( "Version %s %s %s", - info.BuildkitVersion.Package, info.BuildkitVersion.Version, info.BuildkitVersion.Revision) + info.BuildkitVersion.Package, info.BuildkitVersion.Version, info.BuildkitVersion.Revision, + ) const buildkitPackage = "github.com/EarthBuild/buildkit" @@ -1167,7 +1168,8 @@ func printBuildkitInfo( // For local buildkits we expect perfect version match. bkCons.Warnf( "Warning: Buildkit version (%s) is different from earth version (%s)", - info.BuildkitVersion.Version, earthVersion) + info.BuildkitVersion.Version, earthVersion, + ) } else { compatible := true @@ -1229,7 +1231,8 @@ func printBuildkitInfo( workerInfo.GCAnalytics.AvgDuration, workerInfo.GCAnalytics.AllTimeDuration, ld, - humanizeBytes(workerInfo.GCAnalytics.LastSizeCleared)) + humanizeBytes(workerInfo.GCAnalytics.LastSizeCleared), + ) if workerInfo.GCAnalytics.CurrentStartTime != nil { d := time.Since(*workerInfo.GCAnalytics.CurrentStartTime).Round(time.Second) @@ -1265,7 +1268,7 @@ func getGCPolicySize(workerInfo *client.WorkerInfo) (int64, bool) { func getCacheSize(ctx context.Context, volumeName string, fe containerutil.ContainerFrontend) (int, error) { infos, err := fe.VolumeInfo(ctx, volumeName) if err != nil { - return 0, errors.Wrapf(err, "failed to get volume info for cache size %s", volumeName) + return 0, fmt.Errorf("failed to get volume info for cache size %s: %w", volumeName, err) } return int(infos[volumeName].SizeBytes), nil // #nosec G115 @@ -1274,7 +1277,7 @@ func getCacheSize(ctx context.Context, volumeName string, fe containerutil.Conta func addRequiredOpts(settings Settings, opts ...client.ClientOpt) ([]client.ClientOpt, error) { server, err := url.Parse(settings.BuildkitAddress) if err != nil { - return []client.ClientOpt{}, errors.Wrapf(err, "failed to parse buildkit url %s", settings.BuildkitAddress) + return []client.ClientOpt{}, fmt.Errorf("failed to parse buildkit url %s: %w", settings.BuildkitAddress, err) } if !settings.UseTCP || !settings.UseTLS { diff --git a/buildkitd/certificates.go b/buildkitd/certificates.go index a444b9558c..7cb291fde9 100644 --- a/buildkitd/certificates.go +++ b/buildkitd/certificates.go @@ -6,6 +6,7 @@ import ( "crypto/x509" "crypto/x509/pkix" "encoding/pem" + "errors" "fmt" "math" "math/big" @@ -17,7 +18,6 @@ import ( "github.com/EarthBuild/earthbuild/config" "github.com/EarthBuild/earthbuild/util/fileutil" "github.com/EarthBuild/earthbuild/util/hint" - "github.com/pkg/errors" ) type certData struct { @@ -37,7 +37,7 @@ const ( func GenCerts(cfg config.Config, hostname string) error { caKey, err := parseTLSKey(cfg.Global.TLSCAKey) if err != nil && !errors.Is(err, os.ErrNotExist) { - return errors.Wrap(err, "failed reading CA key") + return fmt.Errorf("failed reading CA key: %w", err) } if errors.Is(err, os.ErrNotExist) { @@ -63,7 +63,7 @@ func GenCerts(cfg config.Config, hostname string) error { case len(all): caKey, err = createTLSKey(cfg.Global.TLSCAKey) if err != nil { - return errors.Wrap(err, "could not create CA") + return fmt.Errorf("could not create CA: %w", err) } default: found := all @@ -88,13 +88,13 @@ func GenCerts(cfg config.Config, hostname string) error { caCert, err := parseTLSCert(cfg.Global.TLSCACert) if err != nil && !errors.Is(err, os.ErrNotExist) { - return errors.Wrap(err, "could not parse CA certificate") + return fmt.Errorf("could not parse CA certificate: %w", err) } if errors.Is(err, os.ErrNotExist) { caCert, err = createCACert(caKey, cfg.Global.TLSCACert) if err != nil { - return errors.Wrap(err, "could not create CA certificate") + return fmt.Errorf("could not create CA certificate: %w", err) } } @@ -105,12 +105,12 @@ func GenCerts(cfg config.Config, hostname string) error { err = genCert(ca, buildkit, hostname, cfg.Global.ServerTLSKey, cfg.Global.ServerTLSCert) if err != nil { - return errors.Wrapf(err, "could not generate server TLS key/cert pair for %v", buildkit) + return fmt.Errorf("could not generate server TLS key/cert pair for %v: %w", buildkit, err) } err = genCert(ca, earthly, hostname, cfg.Global.ClientTLSKey, cfg.Global.ClientTLSCert) if err != nil { - return errors.Wrapf(err, "could not generate client TLS key/cert pair for %v", earthly) + return fmt.Errorf("could not generate client TLS key/cert pair for %v: %w", earthly, err) } return nil @@ -121,24 +121,24 @@ func genCert(ca *certData, role, hostname, keyPath, certPath string) error { key, err := parseTLSKey(keyPath) if err != nil && !errors.Is(err, os.ErrNotExist) { - return errors.Wrapf(err, "could not parse %v TLS key", role) + return fmt.Errorf("could not parse %v TLS key: %w", role, err) } if errors.Is(err, os.ErrNotExist) { if certExists { - return errors.Wrapf(err, "refusing to generate TLS key %q: TLS cert %q exists", keyPath, certPath) + return fmt.Errorf("refusing to generate TLS key %q: TLS cert %q exists: %w", keyPath, certPath, err) } key, err = createTLSKey(keyPath) if err != nil { - return errors.Wrapf(err, "could not create %v TLS key", role) + return fmt.Errorf("could not create %v TLS key: %w", role, err) } } if !certExists { _, err = createTLSCert(ca, key, role, certPath, hostname) if err != nil { - return errors.Wrapf(err, "could not create %v TLS cert", role) + return fmt.Errorf("could not create %v TLS cert: %w", role, err) } } @@ -148,14 +148,14 @@ func genCert(ca *certData, role, hostname, keyPath, certPath string) error { func parseTLSKey(path string) (*rsa.PrivateKey, error) { body, err := os.ReadFile(path) // #nosec G304 if err != nil { - return nil, errors.Wrapf(err, "could not read private key %q", path) + return nil, fmt.Errorf("could not read private key %q: %w", path, err) } dec, _ := pem.Decode(body) key, err := x509.ParsePKCS1PrivateKey(dec.Bytes) if err != nil { - return nil, errors.Wrapf(err, "could not decode %q as RSA private key", path) + return nil, fmt.Errorf("could not decode %q as RSA private key: %w", path, err) } return key, nil @@ -164,12 +164,12 @@ func parseTLSKey(path string) (*rsa.PrivateKey, error) { func createTLSKey(path string) (*rsa.PrivateKey, error) { key, err := rsa.GenerateKey(rand.Reader, 4096) if err != nil { - return nil, errors.Wrapf(err, "could not generate RSA key") + return nil, fmt.Errorf("could not generate RSA key: %w", err) } err = savePEM(path, typeRSAKey, x509.MarshalPKCS1PrivateKey(key)) if err != nil { - return nil, errors.Wrapf(err, "saving private key to %q failed", path) + return nil, fmt.Errorf("saving private key to %q failed: %w", path, err) } return key, nil @@ -178,14 +178,14 @@ func createTLSKey(path string) (*rsa.PrivateKey, error) { func parseTLSCert(path string) (*x509.Certificate, error) { body, err := os.ReadFile(path) // #nosec G304 if err != nil { - return nil, errors.Wrapf(err, "could not read public cert %q", path) + return nil, fmt.Errorf("could not read public cert %q: %w", path, err) } dec, _ := pem.Decode(body) cert, err := x509.ParseCertificate(dec.Bytes) if err != nil { - return nil, errors.Wrapf(err, "could not decode %q as x509 certificate", path) + return nil, fmt.Errorf("could not decode %q as x509 certificate: %w", path, err) } return cert, nil @@ -194,7 +194,7 @@ func parseTLSCert(path string) (*x509.Certificate, error) { func createTLSCert(ca *certData, key *rsa.PrivateKey, role, path, hostname string) (*x509.Certificate, error) { serial, err := rand.Int(rand.Reader, big.NewInt(math.MaxInt64)) if err != nil { - return nil, errors.Wrapf(err, "could not generate serial for role %q", role) + return nil, fmt.Errorf("could not generate serial for role %q: %w", role, err) } cert := &x509.Certificate{ @@ -213,12 +213,12 @@ func createTLSCert(ca *certData, key *rsa.PrivateKey, role, path, hostname strin certBytes, err := x509.CreateCertificate(rand.Reader, cert, ca.Cert, &key.PublicKey, ca.Key) if err != nil { - return nil, errors.Wrapf(err, "could not generate certificate for role %q", role) + return nil, fmt.Errorf("could not generate certificate for role %q: %w", role, err) } err = savePEM(path, typeCert, certBytes) if err != nil { - return nil, errors.Wrapf(err, "could not save certificate for role %q to path %q", role, path) + return nil, fmt.Errorf("could not save certificate for role %q to path %q: %w", role, path, err) } return cert, nil @@ -240,12 +240,12 @@ func createCACert(key *rsa.PrivateKey, path string) (*x509.Certificate, error) { caBytes, err := x509.CreateCertificate(rand.Reader, ca, ca, &key.PublicKey, key) if err != nil { - return nil, errors.Wrap(err, "creating CA certificate failed") + return nil, fmt.Errorf("creating CA certificate failed: %w", err) } err = savePEM(path, typeCert, caBytes) if err != nil { - return nil, errors.Wrapf(err, "saving CA certificate to %q failed", path) + return nil, fmt.Errorf("saving CA certificate to %q failed: %w", path, err) } return ca, nil diff --git a/buildkitd/settings.go b/buildkitd/settings.go index 5583419967..4be339dff1 100644 --- a/buildkitd/settings.go +++ b/buildkitd/settings.go @@ -1,12 +1,12 @@ package buildkitd import ( + "fmt" "strconv" "strings" "time" "github.com/mitchellh/hashstructure/v2" - "github.com/pkg/errors" ) // Settings represents the buildkitd settings used to start up the daemon with. @@ -40,7 +40,7 @@ type Settings struct { func (s Settings) Hash() (string, error) { hash, err := hashstructure.Hash(s, hashstructure.FormatV2, nil) if err != nil { - return "", errors.Wrap(err, "hash settings") + return "", fmt.Errorf("hash settings: %w", err) } return strconv.FormatUint(hash, 16), nil @@ -50,12 +50,12 @@ func (s Settings) Hash() (string, error) { func (s Settings) VerifyHash(hash string) (bool, error) { newHash, err := hashstructure.Hash(s, hashstructure.FormatV2, nil) if err != nil { - return false, errors.Wrap(err, "hash settings") + return false, fmt.Errorf("hash settings: %w", err) } oldHash, err := strconv.ParseUint(strings.TrimSpace(hash), 16, 64) if err != nil { - return false, errors.Wrap(err, "parse hash") + return false, fmt.Errorf("parse hash: %w", err) } return oldHash == newHash, nil diff --git a/cmd/debugger/main.go b/cmd/debugger/main.go index b5b0e20f7b..c7475f6ba9 100644 --- a/cmd/debugger/main.go +++ b/cmd/debugger/main.go @@ -5,6 +5,8 @@ import ( "bufio" "context" "encoding/json" + "errors" + "fmt" "io" "math" "net" @@ -19,8 +21,6 @@ import ( "github.com/EarthBuild/earthbuild/slog" "github.com/creack/pty" "github.com/fatih/color" - "github.com/hashicorp/go-multierror" - "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -65,7 +65,7 @@ func getShellPath() (string, bool) { func handlePtyData(ptmx *os.File, data []byte) error { _, err := ptmx.Write(data) if err != nil { - return errors.Wrap(err, "failed to write to ptmx") + return fmt.Errorf("failed to write to ptmx: %w", err) } return nil @@ -76,12 +76,12 @@ func handleWinChangeData(ptmx *os.File, data []byte) error { err := json.Unmarshal(data, &size) if err != nil { - return errors.Wrap(err, "failed unmarshal data") + return fmt.Errorf("failed unmarshal data: %w", err) } err = pty.Setsize(ptmx, &size) if err != nil { - return errors.Wrap(err, "failed to set window size") + return fmt.Errorf("failed to set window size: %w", err) } return nil @@ -96,13 +96,13 @@ func populateShellHistory(cmd string) error { } { f, err := os.Create(f) // #nosec G304 if err != nil { - result = multierror.Append(result, err) + result = errors.Join(result, err) } defer f.Close() _, err = f.WriteString(cmd + "\n") if err != nil { - result = multierror.Append(result, err) + result = errors.Join(result, err) } } @@ -116,13 +116,13 @@ func sendFile(ctx context.Context, sockAddr, src, dst string) error { conn, err := d.DialContext(ctx, "unix", sockAddr) if err != nil { - return errors.Wrap(err, "failed to connect to remote debugger") + return fmt.Errorf("failed to connect to remote debugger: %w", err) } defer func() { closeErr := conn.Close() if closeErr != nil { - log.Error(errors.Wrap(closeErr, "earth debugger: error closing")) + log.Error(fmt.Errorf("earth debugger: error closing: %w", closeErr)) } }() @@ -177,13 +177,13 @@ func interactiveMode( conn, err := d.DialContext(ctx, "unix", remoteConsoleAddr) if err != nil { - return errors.Wrap(err, "failed to connect to remote debugger") + return fmt.Errorf("failed to connect to remote debugger: %w", err) } defer func() { closeErr := conn.Close() if closeErr != nil { - log.Error(errors.Wrap(closeErr, "earth debugger: error closing")) + log.Error(fmt.Errorf("earth debugger: error closing: %w", closeErr)) } }() @@ -213,12 +213,12 @@ func interactiveMode( return } - conslogger.Warnf("%v\n", errors.Wrap(err, "failed to start pty")) + conslogger.Warnf("%v\n", fmt.Errorf("failed to start pty: %w", err)) } ptmx, err := pty.Start(c) if err != nil { - conslogger.Warnf("%v\n", errors.Wrap(err, "failed to start pty")) + conslogger.Warnf("%v\n", fmt.Errorf("failed to start pty: %w", err)) return err } @@ -237,7 +237,7 @@ func interactiveMode( connDataType, data, err = common.ReadDataPacket(conn) if err != nil { - logErrorIfNonCleanExit(errors.Wrap(err, "failed to read data from conn")) + logErrorIfNonCleanExit(fmt.Errorf("failed to read data from conn: %w", err)) return } @@ -245,13 +245,13 @@ func interactiveMode( case common.PtyData: err = handlePtyData(ptmx, data) if err != nil { - logErrorIfNonCleanExit(errors.Wrap(err, "failed to handle pty data")) + logErrorIfNonCleanExit(fmt.Errorf("failed to handle pty data: %w", err)) return } case common.WinSizeData: err = handleWinChangeData(ptmx, data) if err != nil { - logErrorIfNonCleanExit(errors.Wrap(err, "failed to handle win change data")) + logErrorIfNonCleanExit(fmt.Errorf("failed to handle win change data: %w", err)) return } default: @@ -272,7 +272,7 @@ func interactiveMode( n, err = ptmx.Read(buf) if err != nil { - logErrorIfNonCleanExit(errors.Wrap(err, "failed to read from ptmx")) + logErrorIfNonCleanExit(fmt.Errorf("failed to read from ptmx: %w", err)) return } @@ -284,7 +284,7 @@ func interactiveMode( err = common.WriteDataPacket(conn, common.PtyData, buf) if err != nil { - logErrorIfNonCleanExit(errors.Wrap(err, "failed to write data to conn")) + logErrorIfNonCleanExit(fmt.Errorf("failed to write data to conn: %w", err)) return } } @@ -300,7 +300,7 @@ func interactiveMode( err = common.WriteDataPacket(conn, common.EndShellSession, nil) if err != nil { - return errors.Wrap(err, "failed to send end shell session") + return fmt.Errorf("failed to send end shell session: %w", err) } if !waitErr.Load().set { @@ -313,14 +313,14 @@ func interactiveMode( func getSettings(path string) (*common.DebuggerSettings, error) { s, err := os.ReadFile(path) // #nosec G304 if err != nil { - return nil, errors.Wrapf(err, "failed to read %s", path) + return nil, fmt.Errorf("failed to read %s: %w", path, err) } var data common.DebuggerSettings err = json.Unmarshal(s, &data) if err != nil { - return nil, errors.Wrapf(err, "failed to unmarshal %s", path) + return nil, fmt.Errorf("failed to unmarshal %s: %w", path, err) } return &data, nil diff --git a/cmd/earthly/app/before.go b/cmd/earthly/app/before.go index 4091586432..f46d280e7c 100644 --- a/cmd/earthly/app/before.go +++ b/cmd/earthly/app/before.go @@ -2,6 +2,7 @@ package app import ( "context" + "errors" "fmt" "net/http" "os" @@ -19,7 +20,6 @@ import ( "github.com/EarthBuild/earthbuild/util/execstatssummary" "github.com/EarthBuild/earthbuild/util/fileutil" "github.com/google/uuid" - "github.com/pkg/errors" "github.com/urfave/cli/v3" ) @@ -72,7 +72,7 @@ func (app *EarthApp) before(ctx context.Context, cmd *cli.Command) (context.Cont flags.GithubAnnotations, ) if err != nil { - return ctx, errors.Wrap(err, "logbus setup") + return ctx, fmt.Errorf("logbus setup: %w", err) } app.BaseCLI.SetLogbusSetup(busSetup) @@ -87,14 +87,14 @@ func (app *EarthApp) before(ctx context.Context, cmd *cli.Command) (context.Cont yamlData, err = config.ReadConfigFile(flags.ConfigPath) if err != nil { if cmd.IsSet("config") || !errors.Is(err, os.ErrNotExist) { - return ctx, errors.Wrapf(err, "read config") + return ctx, fmt.Errorf("read config: %w", err) } } } cfg, err := config.ParseYAML(yamlData, flags.InstallationName) if err != nil { - return ctx, errors.Wrapf(err, "failed to parse %s", flags.ConfigPath) + return ctx, fmt.Errorf("failed to parse %s: %w", flags.ConfigPath, err) } app.BaseCLI.SetCfg(&cfg) @@ -122,7 +122,7 @@ func (app *EarthApp) before(ctx context.Context, cmd *cli.Command) (context.Cont err = newBootstrap.Action(ctx, cmd) if err != nil { - return ctx, errors.Wrap(err, "bootstrap unbootstrclied installation") + return ctx, fmt.Errorf("bootstrap unbootstrclied installation: %w", err) } } @@ -146,7 +146,7 @@ func (app *EarthApp) parseFrontend(ctx context.Context) error { stub, err := containerutil.NewStubFrontend(feCfg) if err != nil { - return errors.Wrap(err, "failed stub frontend initialization") + return fmt.Errorf("failed stub frontend initialization: %w", err) } app.BaseCLI.Flags().ContainerFrontend = stub diff --git a/cmd/earthly/app/create.go b/cmd/earthly/app/create.go index 55d48458cc..b6e3987654 100644 --- a/cmd/earthly/app/create.go +++ b/cmd/earthly/app/create.go @@ -34,10 +34,12 @@ func NewEarthApp(cliInstance *base.CLI, rootApp *subcmd.Root, buildApp *subcmd.B earthApp.BaseCLI.SetAppStopOnNthArg(new(1)) earthApp.BaseCLI.SetAction(buildApp.Action) earthApp.BaseCLI.SetVersion( - getVersionPlatform(earthApp.BaseCLI.Version(), earthApp.BaseCLI.GitSHA(), earthApp.BaseCLI.BuiltBy())) + getVersionPlatform(earthApp.BaseCLI.Version(), earthApp.BaseCLI.GitSHA(), earthApp.BaseCLI.BuiltBy()), + ) earthApp.BaseCLI.SetFlags( - cliInstance.Flags().RootFlags(cliInstance.DefaultInstallationName(), cliInstance.DefaultBuildkitdImage())) + cliInstance.Flags().RootFlags(cliInstance.DefaultInstallationName(), cliInstance.DefaultBuildkitdImage()), + ) earthApp.BaseCLI.SetFlags(append(earthApp.BaseCLI.App().Flags, buildApp.HiddenFlags()...)) earthApp.BaseCLI.SetCommands(rootApp.Cmds()) diff --git a/cmd/earthly/app/run.go b/cmd/earthly/app/run.go index 70f9e5b6f2..571e32103d 100644 --- a/cmd/earthly/app/run.go +++ b/cmd/earthly/app/run.go @@ -2,6 +2,7 @@ package app import ( "context" + "errors" "fmt" "os" "regexp" @@ -24,7 +25,6 @@ import ( "github.com/EarthBuild/earthbuild/util/syncutil" "github.com/fatih/color" "github.com/moby/buildkit/util/grpcerrors" - "github.com/pkg/errors" "github.com/urfave/cli/v3" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -143,28 +143,6 @@ func (app *EarthApp) run(ctx context.Context, args []string, lastSignal *syncuti func (app *EarthApp) handleError(ctx context.Context, err error, args []string, lastSignal *syncutil.Signal) int { ie, isInterpreterError := earthfile2llb.GetInterpreterError(err) - if app.BaseCLI.Flags().Debug { - // Get the stack trace from the deepest error that has it and print it. - type stackTracer interface { - StackTrace() errors.StackTrace - } - - errChain := []error{} - for it := err; it != nil; it = errors.Unwrap(it) { - errChain = append(errChain, it) - } - - for index := len(errChain) - 1; index > 0; index-- { - it := errChain[index] - - errWithStack, ok := it.(stackTracer) - if ok { - app.BaseCLI.Console().Warnf("Error stack trace:%+v\n", errWithStack.StackTrace()) - break - } - } - } - grpcErr, grpcErrOK := grpcerrors.AsGRPCStatus(err) hintErr := getHintErr(err, grpcErr) @@ -356,7 +334,8 @@ func (app *EarthApp) handleError(ctx context.Context, err error, args []string, ) app.BaseCLI.Console().Warn( "Error: It seems that buildkitd is shutting down or it has crashed. " + - "You can report crashes at https://github.com/EarthBuild/earthbuild/issues/new.") + "You can report crashes at https://github.com/EarthBuild/earthbuild/issues/new.", + ) if containerutil.IsLocal(app.BaseCLI.Flags().BuildkitdSettings.BuildkitAddress) { app.printCrashLogs(ctx) @@ -372,7 +351,8 @@ func (app *EarthApp) handleError(ctx context.Context, err error, args []string, ) app.BaseCLI.Console().Warn( "Error: It seems that buildkitd is shutting down or it has crashed. " + - "You can report crashes at https://github.com/EarthBuild/earthbuild/issues/new.") + "You can report crashes at https://github.com/EarthBuild/earthbuild/issues/new.", + ) if containerutil.IsLocal(app.BaseCLI.Flags().BuildkitdSettings.BuildkitAddress) { app.printCrashLogs(ctx) @@ -390,7 +370,8 @@ func (app *EarthApp) handleError(ctx context.Context, err error, args []string, if containerutil.IsLocal(app.BaseCLI.Flags().BuildkitdSettings.BuildkitAddress) { app.BaseCLI.Console().Warn( "Error: It seems that buildkitd had an issue. " + - "You can report crashes at https://github.com/EarthBuild/earthbuild/issues/new.") + "You can report crashes at https://github.com/EarthBuild/earthbuild/issues/new.", + ) app.printCrashLogs(ctx) } diff --git a/cmd/earthly/base/buildkit.go b/cmd/earthly/base/buildkit.go index 6f9a915645..0692c93f7e 100644 --- a/cmd/earthly/base/buildkit.go +++ b/cmd/earthly/base/buildkit.go @@ -2,10 +2,10 @@ package base import ( "context" + "fmt" "github.com/EarthBuild/earthbuild/buildkitd" "github.com/moby/buildkit/client" - "github.com/pkg/errors" "github.com/urfave/cli/v3" ) @@ -18,9 +18,10 @@ func (cli *CLI) GetBuildkitClient(ctx context.Context, cmd *cli.Command) (c *cli c, err = buildkitd.NewClient( ctx, cli.Console(), cli.Flags().BuildkitdImage, cli.Flags().ContainerName, cli.Flags().InstallationName, - cli.Flags().ContainerFrontend, cli.Version(), cli.Flags().BuildkitdSettings) + cli.Flags().ContainerFrontend, cli.Version(), cli.Flags().BuildkitdSettings, + ) if err != nil { - return nil, errors.Wrap(err, "could not construct new buildkit client") + return nil, fmt.Errorf("could not construct new buildkit client: %w", err) } return c, nil diff --git a/cmd/earthly/base/init_frontend.go b/cmd/earthly/base/init_frontend.go index 7f7aff4348..81ed04dcac 100644 --- a/cmd/earthly/base/init_frontend.go +++ b/cmd/earthly/base/init_frontend.go @@ -2,12 +2,13 @@ package base import ( "context" + "errors" + "fmt" "net/url" "path/filepath" "time" "github.com/EarthBuild/earthbuild/util/cliutil" - "github.com/pkg/errors" "github.com/urfave/cli/v3" ) @@ -36,7 +37,7 @@ func (cli *CLI) InitFrontend(_ context.Context, cmd *cli.Command) error { bkURL, err := url.Parse(cli.Flags().BuildkitHost) // Not validated because we already did that when we calculated it. if err != nil { - return errors.Wrap(err, "failed to parse generated buildkit URL") + return fmt.Errorf("failed to parse generated buildkit URL: %w", err) } if bkURL.Scheme == "tcp" && cli.Cfg().Global.TLSEnabled { @@ -79,7 +80,7 @@ func (cli *CLI) InitFrontend(_ context.Context, cmd *cli.Command) error { earthDir, err := cliutil.GetOrCreateEarthDir(cli.Flags().InstallationName) if err != nil { - return errors.Wrap(err, "failed to get earth dir") + return fmt.Errorf("failed to get earth dir: %w", err) } cli.Flags().BuildkitdSettings.StartUpLockPath = filepath.Join(earthDir, "buildkitd-startup.lock") diff --git a/cmd/earthly/bk/buildkitskipper_create.go b/cmd/earthly/bk/buildkitskipper_create.go index 4b055372da..36116fc97c 100644 --- a/cmd/earthly/bk/buildkitskipper_create.go +++ b/cmd/earthly/bk/buildkitskipper_create.go @@ -2,9 +2,9 @@ package bk import ( "context" + "fmt" "github.com/EarthBuild/earthbuild/util/buildkitskipper" - "github.com/pkg/errors" ) // BuildkitSkipper adds new auto-skip hashes to the backing datastore & allows @@ -22,7 +22,7 @@ func NewBuildkitSkipper(localSkipDB string) (BuildkitSkipper, error) { skipDB, err := buildkitskipper.NewLocal(localSkipDB) if err != nil { - return nil, errors.Wrapf(err, "failed to open buildkit skipper database %s", localSkipDB) + return nil, fmt.Errorf("failed to open buildkit skipper database %s: %w", localSkipDB, err) } return skipDB, nil diff --git a/cmd/earthly/common/shared.go b/cmd/earthly/common/shared.go index 72c1235481..b9d9c3bb81 100644 --- a/cmd/earthly/common/shared.go +++ b/cmd/earthly/common/shared.go @@ -18,7 +18,6 @@ import ( "github.com/EarthBuild/earthbuild/util/hint" "github.com/EarthBuild/earthbuild/variables" gsysinfo "github.com/elastic/go-sysinfo" - "github.com/pkg/errors" ) // Wrap formats strings by joining them with newlines and tabs. @@ -37,7 +36,7 @@ func CombineVariables(dotEnvMap map[string]string, flagArgs, buildFlagArgs []str overridingVars, err := variables.ParseCommandLineArgs(buildArgs) if err != nil { - return nil, errors.Wrap(err, "parse build args") + return nil, fmt.Errorf("parse build args: %w", err) } return variables.CombineScopes(overridingVars, dotEnvVars), nil @@ -64,7 +63,7 @@ func ProcessSecrets( // Not set. Use environment to fetch it. value, found := os.LookupEnv(secret) if !found { - err := errors.Errorf("failed to set secret %q via --secret flag without a value", secret) + err := fmt.Errorf("failed to set secret %q via --secret flag without a value", secret) return nil, hint.Wrapf(err, "Try to set an env var by the name %q with the secret value or pass the value as part of the --secret flag", @@ -75,7 +74,9 @@ func ProcessSecrets( } if _, ok := finalSecrets[key]; ok { - return nil, hint.Wrapf(errors.Errorf("failed to set secret %q via --secret flag", key), + err := fmt.Errorf("failed to set secret %q via --secret flag", key) + + return nil, hint.Wrapf(err, "Check the secret %q has not already been set in the file %q or passed more than once to the command", key, secretsFilePath) } @@ -86,7 +87,7 @@ func ProcessSecrets( for _, secret := range secretFiles { parts := strings.SplitN(secret, "=", 2) if len(parts) != 2 { - return nil, errors.Errorf("unable to parse --secret-file argument: %q", secret) + return nil, fmt.Errorf("unable to parse --secret-file argument: %q", secret) } k := parts[0] @@ -94,12 +95,15 @@ func ProcessSecrets( data, err := os.ReadFile(path) // #nosec G304 if err != nil { - return nil, errors.Wrapf(err, "failed to open %q", path) + return nil, fmt.Errorf("failed to open %q: %w", path, err) } if _, ok := finalSecrets[k]; ok { - return nil, hint.Wrapf(errors.Errorf("failed to set secret %q via --secret-file flag", k), - "Check the secret %q has not already been set in the file %q, or passed via --secret flag", k, secretsFilePath) + err := fmt.Errorf("failed to set secret %q via --secret-file flag", k) + + return nil, hint.Wrapf(err, + "Check the secret %q has not already been set in the file %q, or passed via --secret flag", + k, secretsFilePath) } finalSecrets[k] = data diff --git a/cmd/earthly/helper/autocomplete.go b/cmd/earthly/helper/autocomplete.go index 44a8798a97..26cc6877fb 100644 --- a/cmd/earthly/helper/autocomplete.go +++ b/cmd/earthly/helper/autocomplete.go @@ -2,6 +2,7 @@ package helper import ( "context" + "errors" "fmt" "math" "os" @@ -10,7 +11,6 @@ import ( "strconv" gwclient "github.com/moby/buildkit/frontend/gateway/client" - "github.com/pkg/errors" "github.com/EarthBuild/earthbuild/cmd/earthly/base" @@ -73,7 +73,7 @@ func AutoComplete(ctx context.Context, cli *base.CLI) (code int) { func autoCompleteImp(ctx context.Context, cli *base.CLI) (err error) { defer func() { if r := recover(); r != nil { - err = errors.Errorf("recovered panic in autocomplete %s: %s", r, debug.Stack()) + err = fmt.Errorf("recovered panic in autocomplete %s: %s", r, debug.Stack()) } }() @@ -86,7 +86,7 @@ func autoCompleteImp(ctx context.Context, cli *base.CLI) (err error) { } if compPointInt == 0 || compPointInt >= math.MaxInt { - err = errors.Errorf("compPointInt is out of bounds") + err = errors.New("compPointInt is out of bounds") return err } diff --git a/cmd/earthly/main.go b/cmd/earthly/main.go index 4045c6edd1..6f07eb5b0f 100644 --- a/cmd/earthly/main.go +++ b/cmd/earthly/main.go @@ -3,6 +3,7 @@ package main import ( "context" + "errors" "flag" "fmt" "io" @@ -26,7 +27,7 @@ import ( "github.com/fatih/color" "github.com/joho/godotenv" _ "github.com/moby/buildkit/client/connhelper/dockercontainer" // Load "docker-container://" helper. - "github.com/pkg/errors" + "github.com/sirupsen/logrus" urfavecli "github.com/urfave/cli/v3" semconv "go.opentelemetry.io/otel/semconv/v1.39.0" diff --git a/cmd/earthly/subcmd/bootstrap_cmds.go b/cmd/earthly/subcmd/bootstrap_cmds.go index 7fdb75f5cf..ccce1db1ed 100644 --- a/cmd/earthly/subcmd/bootstrap_cmds.go +++ b/cmd/earthly/subcmd/bootstrap_cmds.go @@ -17,7 +17,6 @@ import ( "github.com/EarthBuild/earthbuild/util/fileutil" "github.com/EarthBuild/earthbuild/util/termutil" "github.com/adrg/xdg" - "github.com/pkg/errors" "github.com/urfave/cli/v3" ) @@ -112,7 +111,7 @@ func (b *Bootstrap) Action(ctx context.Context, cmd *cli.Command) error { case "": break default: - return errors.Errorf("unhandled source %q", b.homebrewSource) + return fmt.Errorf("unhandled source %q", b.homebrewSource) } return b.bootstrap(ctx, cmd) @@ -162,13 +161,13 @@ func (b *Bootstrap) bootstrap(ctx context.Context, cmd *cli.Command) error { if !b.noBuildkit || b.genCerts { bkURL, err := url.Parse(b.cli.Flags().BuildkitHost) if err != nil { - return errors.Wrapf(err, "invalid buildkit_host: %s", b.cli.Flags().BuildkitHost) + return fmt.Errorf("invalid buildkit_host: %s: %w", b.cli.Flags().BuildkitHost, err) } if bkURL.Scheme == "tcp" && b.cli.Cfg().Global.TLSEnabled { err := buildkitd.GenCerts(*b.cli.Cfg(), b.certsHostName) if err != nil { - return errors.Wrap(err, "failed to generate TLS certs") + return fmt.Errorf("failed to generate TLS certs: %w", err) } } } @@ -192,7 +191,7 @@ func (b *Bootstrap) bootstrap(ctx context.Context, cmd *cli.Command) error { func (b *Bootstrap) insertBashCompleteEntry() error { u, err := user.Current() if err != nil { - return errors.Wrapf(err, "could not get current user") + return fmt.Errorf("could not get current user: %w", err) } isRootUser := u.Uid == "0" @@ -238,7 +237,7 @@ func (b *Bootstrap) insertBashCompleteEntryAt(path string) (bool, error) { dirPathExists, err := fileutil.DirExists(dirPath) if err != nil { - return false, errors.Wrapf(err, "failed checking if %s exists", dirPath) + return false, fmt.Errorf("failed checking if %s exists: %w", dirPath, err) } if !dirPathExists { @@ -247,7 +246,7 @@ func (b *Bootstrap) insertBashCompleteEntryAt(path string) (bool, error) { pathExists, err := fileutil.FileExists(path) if err != nil { - return false, errors.Wrapf(err, "failed checking if %s exists", path) + return false, fmt.Errorf("failed checking if %s exists: %w", path, err) } if pathExists { @@ -263,12 +262,12 @@ func (b *Bootstrap) insertBashCompleteEntryAt(path string) (bool, error) { bashEntry, err := bashCompleteEntry() if err != nil { - return false, errors.Wrapf(err, "failed to add entry") + return false, fmt.Errorf("failed to add entry: %w", err) } _, err = f.WriteString(bashEntry) if err != nil { - return false, errors.Wrapf(err, "failed writing to %s", path) + return false, fmt.Errorf("failed writing to %s: %w", path, err) } return true, nil @@ -283,7 +282,7 @@ func (b *Bootstrap) insertZSHCompleteEntry() error { for _, dirPath := range potentialPaths { dirPathExists, err := fileutil.DirExists(dirPath) if err != nil { - return errors.Wrapf(err, "failed to check if %s exists", dirPath) + return fmt.Errorf("failed to check if %s exists: %w", dirPath, err) } if dirPathExists { @@ -302,7 +301,7 @@ func (b *Bootstrap) insertZSHCompleteEntryUnderPath(dirPath string) error { pathExists, err := fileutil.FileExists(path) if err != nil { - return errors.Wrapf(err, "failed to check if %s exists", path) + return fmt.Errorf("failed to check if %s exists: %w", path, err) } if pathExists { @@ -324,7 +323,7 @@ func (b *Bootstrap) insertZSHCompleteEntryUnderPath(dirPath string) error { _, err = f.WriteString(compEntry) if err != nil { - return errors.Wrapf(err, "failed writing to %s", path) + return fmt.Errorf("failed writing to %s: %w", path, err) } return b.deleteZcompdump() @@ -339,12 +338,12 @@ func (b *Bootstrap) deleteZcompdump() error { homeDir, err = os.UserHomeDir() if err != nil { - return errors.Wrapf(err, "failed to lookup current user home dir") + return fmt.Errorf("failed to lookup current user home dir: %w", err) } } else { currentUser, err := user.Lookup(sudoUser) if err != nil { - return errors.Wrapf(err, "failed to lookup user %s", sudoUser) + return fmt.Errorf("failed to lookup user %s: %w", sudoUser, err) } homeDir = currentUser.HomeDir @@ -352,7 +351,7 @@ func (b *Bootstrap) deleteZcompdump() error { files, err := os.ReadDir(homeDir) if err != nil { - return errors.Wrapf(err, "failed to read dir %s", homeDir) + return fmt.Errorf("failed to read dir %s: %w", homeDir, err) } for _, f := range files { @@ -361,7 +360,7 @@ func (b *Bootstrap) deleteZcompdump() error { err := os.Remove(path) if err != nil { - return errors.Wrapf(err, "failed to remove %s", path) + return fmt.Errorf("failed to remove %s: %w", path, err) } } } @@ -372,7 +371,7 @@ func (b *Bootstrap) deleteZcompdump() error { func symlinkEarthlyToEarth() error { binPath, err := os.Executable() if err != nil { - return errors.Wrap(err, "failed to get current executable path") + return fmt.Errorf("failed to get current executable path: %w", err) } baseName := path.Base(binPath) @@ -384,7 +383,7 @@ func symlinkEarthlyToEarth() error { earthPathExists, err := fileutil.FileExists(earthPath) if err != nil { - return errors.Wrapf(err, "failed to check if %q exists", earthPath) + return fmt.Errorf("failed to check if %q exists: %w", earthPath, err) } if !earthPathExists && termutil.IsTTY() { @@ -399,12 +398,12 @@ func symlinkEarthlyToEarth() error { // to the new earth command. err = os.Remove(earthPath) if err != nil { - return errors.Wrapf(err, "failed to remove old install at %s", earthPath) + return fmt.Errorf("failed to remove old install at %s: %w", earthPath, err) } err = os.Symlink(binPath, earthPath) if err != nil { - return errors.Wrapf(err, "failed to symlink %s to %s", binPath, earthPath) + return fmt.Errorf("failed to symlink %s to %s: %w", binPath, earthPath, err) } return nil @@ -431,7 +430,7 @@ function _earthly { func renderEntryTemplate(template string) (string, error) { earthPath, err := os.Executable() if err != nil { - return "", errors.Wrapf(err, "failed to determine earth path: %s", err) + return "", fmt.Errorf("failed to determine earth path: %w: %w", err, err) } return strings.ReplaceAll(template, "__earthly__", earthPath), nil diff --git a/cmd/earthly/subcmd/build_cmd.go b/cmd/earthly/subcmd/build_cmd.go index e84e2ae823..2a5bd192c6 100644 --- a/cmd/earthly/subcmd/build_cmd.go +++ b/cmd/earthly/subcmd/build_cmd.go @@ -2,6 +2,7 @@ package subcmd import ( "context" + "errors" "fmt" "io" "net/url" @@ -52,7 +53,6 @@ import ( "github.com/moby/buildkit/session/sshforward/sshprovider" "github.com/moby/buildkit/util/entitlements" buildkitgitutil "github.com/moby/buildkit/util/gitutil" - "github.com/pkg/errors" "github.com/urfave/cli/v3" ) @@ -161,7 +161,7 @@ func (b *Build) Action(ctx context.Context, cmd *cli.Command) error { flagArgs, nonFlagArgs, err := variables.ParseFlagArgsWithNonFlags(cmd.Args().Slice()) if err != nil { - return errors.Wrapf(err, "parse args %s", strings.Join(cmd.Args().Slice(), " ")) + return fmt.Errorf("parse args %s: %w", strings.Join(cmd.Args().Slice(), " "), err) } return b.ActionBuildImp(ctx, cmd, flagArgs, nonFlagArgs) @@ -202,7 +202,8 @@ func (b *Build) parseTarget(cmd *cli.Command, nonFlagArgs []string) (domain.Targ _ = cli.ShowAppHelp(cmd) return target, artifact, "", params.Errorf( - "no image reference provided. Try %s --image +", common.GetBinaryName()) + "no image reference provided. Try %s --image +", common.GetBinaryName(), + ) } else if len(nonFlagArgs) != 1 { _ = cli.ShowAppHelp(cmd) return target, artifact, "", params.Errorf("invalid arguments %s", strings.Join(nonFlagArgs, " ")) @@ -221,7 +222,8 @@ func (b *Build) parseTarget(cmd *cli.Command, nonFlagArgs []string) (domain.Targ _ = cli.ShowAppHelp(cmd) return target, artifact, "", params.Errorf( - "no artifact reference provided. Try %s --artifact +/", common.GetBinaryName()) + "no artifact reference provided. Try %s --artifact +/", common.GetBinaryName(), + ) } else if len(nonFlagArgs) > 2 { _ = cli.ShowAppHelp(cmd) return target, artifact, "", params.Errorf("invalid arguments %s", strings.Join(nonFlagArgs, " ")) @@ -245,7 +247,8 @@ func (b *Build) parseTarget(cmd *cli.Command, nonFlagArgs []string) (domain.Targ _ = cli.ShowAppHelp(cmd) return target, artifact, "", params.Errorf( - "no target reference provided. Try %s +", common.GetBinaryName()) + "no target reference provided. Try %s +", common.GetBinaryName(), + ) } else if len(nonFlagArgs) != 1 { _ = cli.ShowAppHelp(cmd) return target, artifact, "", params.Errorf("invalid arguments %s", strings.Join(nonFlagArgs, " ")) @@ -283,7 +286,7 @@ func (b *Build) ActionBuildImp(ctx context.Context, cmd *cli.Command, flagArgs, if err != nil { // ignore ErrNotExist when using default .env file if cmd.IsSet(flag.EnvFileFlag) || !errors.Is(err, os.ErrNotExist) { - return errors.Wrapf(err, "read %s", b.cli.Flags().EnvFile) + return fmt.Errorf("read %s: %w", b.cli.Flags().EnvFile, err) } } @@ -292,7 +295,7 @@ func (b *Build) ActionBuildImp(ctx context.Context, cmd *cli.Command, flagArgs, showUnexpectedEnvWarnings = false } else if cmd.IsSet(flag.ArgFileFlag) || !errors.Is(err, os.ErrNotExist) { // ignore ErrNotExist when using default .env file - return errors.Wrapf(err, "read %s", b.cli.Flags().ArgFile) + return fmt.Errorf("read %s: %w", b.cli.Flags().ArgFile, err) } secretsFileMap, err := godotenv.Read(b.cli.Flags().SecretFile) @@ -300,7 +303,7 @@ func (b *Build) ActionBuildImp(ctx context.Context, cmd *cli.Command, flagArgs, showUnexpectedEnvWarnings = false } else if cmd.IsSet(flag.SecretFileFlag) || !errors.Is(err, os.ErrNotExist) { // ignore ErrNotExist when using default .env file - return errors.Wrapf(err, "read %s", b.cli.Flags().SecretFile) + return fmt.Errorf("read %s: %w", b.cli.Flags().SecretFile, err) } if showUnexpectedEnvWarnings { @@ -326,7 +329,8 @@ func (b *Build) ActionBuildImp(ctx context.Context, cmd *cli.Command, flagArgs, b.cli.Console().Warnf( "Deprecation: secret key %q does not follow the recommended naming convention "+ "(a letter followed by alphanumeric characters or underscores); "+ - "this will become an error in a future version of earthly.", secretKey) + "this will become an error in a future version of earthly.", secretKey, + ) } } @@ -352,7 +356,7 @@ func (b *Build) ActionBuildImp(ctx context.Context, cmd *cli.Command, flagArgs, err = b.cli.InitFrontend(ctx, cmd) if err != nil { - return errors.Wrapf(err, "could not init frontend") + return fmt.Errorf("could not init frontend: %w", err) } // After configuring frontend, buildkit address should not be empty. @@ -372,7 +376,7 @@ func (b *Build) ActionBuildImp(ctx context.Context, cmd *cli.Command, flagArgs, b.cli.Flags().BuildkitdSettings, ) if err != nil { - return errors.Wrap(err, "build new buildkitd client") + return fmt.Errorf("build new buildkitd client: %w", err) } defer bkClient.Close() @@ -388,12 +392,12 @@ func (b *Build) ActionBuildImp(ctx context.Context, cmd *cli.Command, flagArgs, localhostProvider, err := localhostprovider.NewLocalhostProvider() if err != nil { - return errors.Wrap(err, "failed to create localhostprovider") + return fmt.Errorf("failed to create localhostprovider: %w", err) } cacheLocalDir, err := os.MkdirTemp("", "earthly-cache") if err != nil { - return errors.Wrap(err, "make temp dir for cache") + return fmt.Errorf("make temp dir for cache: %w", err) } defer os.RemoveAll(cacheLocalDir) @@ -406,7 +410,7 @@ func (b *Build) ActionBuildImp(ctx context.Context, cmd *cli.Command, flagArgs, customSecretProviderCmd, err := secretprovider.NewSecretProviderCmd(b.cli.Cfg().Global.SecretProvider) if err != nil { - return errors.Wrap(err, "NewSecretProviderCmd") + return fmt.Errorf("NewSecretProviderCmd: %w", err) } secretProvider := secretprovider.New( @@ -456,7 +460,7 @@ func (b *Build) ActionBuildImp(ctx context.Context, cmd *cli.Command, flagArgs, Paths: []string{b.cli.Flags().SSHAuthSock}, }}) if err != nil { - return errors.Wrap(err, "ssh agent provider") + return fmt.Errorf("ssh agent provider: %w", err) } attachables = append(attachables, ssh) @@ -475,14 +479,14 @@ func (b *Build) ActionBuildImp(ctx context.Context, cmd *cli.Command, flagArgs, termErr := terminal.ConnectTerm(ctx, conn, debugTermConsole) if termErr != nil { - return errors.Wrap(termErr, "interactive terminal") + return fmt.Errorf("interactive terminal: %w", termErr) } return nil }, }) if err != nil { - return errors.Wrap(err, "ssh agent provider") + return fmt.Errorf("ssh agent provider: %w", err) } attachables = append(attachables, socketProvider) @@ -503,7 +507,7 @@ func (b *Build) ActionBuildImp(ctx context.Context, cmd *cli.Command, flagArgs, if b.cli.Flags().RemoteCache != "" { cacheImportImageName, _, err = flagutil.ParseImageNameAndAttrs(b.cli.Flags().RemoteCache) if err != nil { - return errors.Wrapf(err, "parse import cache error: %s", b.cli.Flags().RemoteCache) + return fmt.Errorf("parse import cache error: %s: %w", b.cli.Flags().RemoteCache, err) } cacheImports = append(cacheImports, cacheImportImageName) @@ -539,7 +543,7 @@ func (b *Build) ActionBuildImp(ctx context.Context, cmd *cli.Command, flagArgs, u, err = url.Parse(b.cli.Flags().LocalRegistryHost) if err != nil { - return errors.Wrapf(err, "parse local registry host %s", b.cli.Flags().LocalRegistryHost) + return fmt.Errorf("parse local registry host %s: %w", b.cli.Flags().LocalRegistryHost, err) } localRegistryAddr = u.Host @@ -589,7 +593,7 @@ func (b *Build) ActionBuildImp(ctx context.Context, cmd *cli.Command, flagArgs, build, err := builder.NewBuilder(builderOpts) if err != nil { - return errors.Wrap(err, "new builder") + return fmt.Errorf("new builder: %w", err) } b.cli.Console().PrintPhaseFooter(builder.PhaseInit) @@ -631,7 +635,7 @@ func (b *Build) ActionBuildImp(ctx context.Context, cmd *cli.Command, flagArgs, _, err = build.BuildTarget(ctx, target, buildOpts) if err != nil { - return errors.Wrap(err, "build target") + return fmt.Errorf("build target: %w", err) } if b.cli.Flags().SkipBuildkit && addHashFn != nil { @@ -690,9 +694,10 @@ func (b *Build) updateGitLookupConfig(gitLookup *buildcontext.GitLookup) error { err := gitLookup.AddMatcher( k, pattern, v.Substitute, v.User, v.Password, v.Prefix, suffix, auth, v.ServerKey, - common.IfNilBoolDefault(v.StrictHostKeyChecking, true), v.Port, v.SSHCommand) + common.IfNilBoolDefault(v.StrictHostKeyChecking, true), v.Port, v.SSHCommand, + ) if err != nil { - return errors.Wrap(err, "gitlookup") + return fmt.Errorf("gitlookup: %w", err) } } @@ -817,7 +822,7 @@ func (b *Build) runnerName(ctx context.Context) (string, bool, error) { } if isLocal && !b.cli.Flags().ContainerFrontend.IsAvailable(ctx) { - return "", false, errors.New("Frontend is not available to perform the build. Is Docker installed and running?") + return "", false, errors.New("frontend is not available to perform the build; is Docker installed and running?") } return runnerName, isLocal, nil @@ -828,7 +833,7 @@ func (b *Build) platformResolver( ) (*platutil.Resolver, error) { nativePlatform, err := platutil.GetNativePlatformViaBkClient(ctx, bkClient) if err != nil { - return nil, errors.Wrap(err, "get native platform via buildkit client") + return nil, fmt.Errorf("get native platform via buildkit client: %w", err) } b.cli.LogbusSetup().SetDefaultPlatform(platforms.Format(nativePlatform)) @@ -839,7 +844,7 @@ func (b *Build) platformResolver( for _, p := range b.platformsStr { platform, err := platr.Parse(p) if err != nil { - return nil, errors.Wrapf(err, "parse platform %s", p) + return nil, fmt.Errorf("parse platform %s: %w", p, err) } platformsSlice = append(platformsSlice, platform) @@ -850,7 +855,7 @@ func (b *Build) platformResolver( case 1: platr.UpdatePlatform(platformsSlice[0]) default: - return nil, errors.Errorf("multi-platform builds are not yet supported on the command line. "+ + return nil, fmt.Errorf("multi-platform builds are not yet supported on the command line. "+ "You may, however, create a target with the instruction BUILD --platform ... --platform ... %s", target) } @@ -888,7 +893,7 @@ func (b *Build) initAutoSkip( OverridingVars: overridingVars, }) if err != nil { - return nil, false, errors.Wrapf(err, "auto-skip is unable to calculate hash for %s", target) + return nil, false, fmt.Errorf("auto-skip is unable to calculate hash for %s: %w", target, err) } console.VerbosePrintf("targets visited: %d; targets hashed: %d; target cache hits: %d", @@ -907,7 +912,7 @@ func (b *Build) initAutoSkip( target, ok = gitutil.ReferenceWithGitMeta(target, meta).(domain.Target) if !ok { - return nil, false, errors.Errorf("want domain.Target, got %T", target) + return nil, false, fmt.Errorf("want domain.Target, got %T", target) } target.Tag = "" @@ -945,62 +950,64 @@ func (b *Build) actionDockerBuild(ctx context.Context, cmd *cli.Command) error { flagArgs, nonFlagArgs, err := variables.ParseFlagArgsWithNonFlags(cmd.Args().Slice()) if err != nil { - return errors.Wrapf(err, "parse args %s", strings.Join(cmd.Args().Slice(), " ")) + return fmt.Errorf("parse args %s: %w", strings.Join(cmd.Args().Slice(), " "), err) } if len(nonFlagArgs) == 0 { _ = cli.ShowAppHelp(cmd) - return errors.Errorf( - "no build context path provided. Try %s docker-build ", common.GetBinaryName()) + return fmt.Errorf( + "no build context path provided. Try %s docker-build ", common.GetBinaryName(), + ) } if len(nonFlagArgs) != 1 { _ = cli.ShowAppHelp(cmd) - return errors.Errorf("invalid arguments %s", strings.Join(nonFlagArgs, " ")) + return fmt.Errorf("invalid arguments %s", strings.Join(nonFlagArgs, " ")) } buildContextPath, err := filepath.Abs(nonFlagArgs[0]) if err != nil { - return errors.Wrapf(err, "failed to get absolute path for build context") + return fmt.Errorf("failed to get absolute path for build context: %w", err) } tempDir, err := os.MkdirTemp("", "docker-build") if err != nil { - return errors.Wrap(err, "docker-build: failed to create temporary dir for Earthfile") + return fmt.Errorf("docker-build: failed to create temporary dir for Earthfile: %w", err) } defer os.RemoveAll(tempDir) argMap, err := godotenv.Read(b.cli.Flags().ArgFile) if err != nil && (cmd.IsSet(flag.ArgFileFlag) || !errors.Is(err, os.ErrNotExist)) { - return errors.Wrapf(err, "read %q", b.cli.Flags().ArgFile) + return fmt.Errorf("read %q: %w", b.cli.Flags().ArgFile, err) } buildArgs, err := common.CombineVariables(argMap, flagArgs, b.buildArgs) if err != nil { - return errors.Wrapf(err, "combining build args") + return fmt.Errorf("combining build args: %w", err) } platforms := flagutil.SplitFlagString(b.platformsStr) content, err := docker2earth.GenerateEarthfile( buildContextPath, b.cli.Flags().DockerfilePath, b.dockerTags, - buildArgs.Sorted(), platforms, b.dockerTarget) + buildArgs.Sorted(), platforms, b.dockerTarget, + ) if err != nil { - return errors.Wrap(err, "docker-build: failed to wrap Dockerfile with an Earthfile") + return fmt.Errorf("docker-build: failed to wrap Dockerfile with an Earthfile: %w", err) } earthfilePath := filepath.Join(tempDir, buildcontext.Earthfile) out, err := os.Create(earthfilePath) // #nosec G304 if err != nil { - return errors.Wrapf(err, "docker-build: failed to create Earthfile %q", earthfilePath) + return fmt.Errorf("docker-build: failed to create Earthfile %q: %w", earthfilePath, err) } defer out.Close() _, err = out.WriteString(content) if err != nil { - return errors.Wrapf(err, "docker-build: failed to write to %q", earthfilePath) + return fmt.Errorf("docker-build: failed to write to %q: %w", earthfilePath, err) } // The following should not be set in the context of executing the build from the generated Earthfile: diff --git a/cmd/earthly/subcmd/config_cmds.go b/cmd/earthly/subcmd/config_cmds.go index 718dd53ec2..29fbfac64f 100644 --- a/cmd/earthly/subcmd/config_cmds.go +++ b/cmd/earthly/subcmd/config_cmds.go @@ -2,11 +2,11 @@ package subcmd import ( "context" + "errors" "fmt" "os" "github.com/EarthBuild/earthbuild/config" - "github.com/pkg/errors" "github.com/urfave/cli/v3" ) @@ -90,7 +90,7 @@ func (a *Config) action(_ context.Context, cmd *cli.Command) error { inConfig, err := config.ReadConfigFile(a.cli.Flags().ConfigPath) if err != nil { if cmd.IsSet("config") || !errors.Is(err, os.ErrNotExist) { - return errors.Wrapf(err, "read config") + return fmt.Errorf("read config: %w", err) } } @@ -100,20 +100,20 @@ func (a *Config) action(_ context.Context, cmd *cli.Command) error { case "-h", "--help": err = config.PrintHelp(args[0]) if err != nil { - return errors.Wrap(err, "help") + return fmt.Errorf("help: %w", err) } return nil // exit now without writing any changes to config case "--delete": outConfig, err = config.Delete(inConfig, args[0]) if err != nil { - return errors.Wrap(err, "delete config") + return fmt.Errorf("delete config: %w", err) } default: // args are key/value pairs, e.g. ["global.conversion_parallelism","5"] outConfig, err = config.Upsert(inConfig, args[0], args[1]) if err != nil { - return errors.Wrap(err, "upsert config") + return fmt.Errorf("upsert config: %w", err) } } @@ -124,7 +124,7 @@ func (a *Config) action(_ context.Context, cmd *cli.Command) error { err = config.WriteConfigFile(a.cli.Flags().ConfigPath, outConfig) if err != nil { - return errors.Wrap(err, "write config") + return fmt.Errorf("write config: %w", err) } a.cli.Console().Printf("Updated config file %s", a.cli.Flags().ConfigPath) diff --git a/cmd/earthly/subcmd/debug_cmds.go b/cmd/earthly/subcmd/debug_cmds.go index 117468369f..3c85d5cbde 100644 --- a/cmd/earthly/subcmd/debug_cmds.go +++ b/cmd/earthly/subcmd/debug_cmds.go @@ -3,6 +3,7 @@ package subcmd import ( "context" "encoding/json" + "errors" "fmt" "os" "strings" @@ -13,7 +14,6 @@ import ( "github.com/containerd/platforms" "github.com/dustin/go-humanize" "github.com/moby/buildkit/client" - "github.com/pkg/errors" "github.com/urfave/cli/v3" ) @@ -119,7 +119,7 @@ func (a *Debug) actionAst(_ context.Context, cmd *cli.Command) error { efDt, err := json.Marshal(ef) if err != nil { - return errors.Wrap(err, "marshal ast") + return fmt.Errorf("marshal ast: %w", err) } fmt.Print(string(efDt)) @@ -132,13 +132,13 @@ func (a *Debug) actionBuildkitSessionHistory(ctx context.Context, cmd *cli.Comma bkClient, err := a.cli.GetBuildkitClient(ctx, cmd) if err != nil { - return errors.Wrap(err, "build new buildkitd client") + return fmt.Errorf("build new buildkitd client: %w", err) } defer bkClient.Close() history, err := bkClient.SessionHistory(ctx) if err != nil { - return errors.Wrap(err, "get buildkit session history") + return fmt.Errorf("get buildkit session history: %w", err) } byt, _ := json.MarshalIndent(history, "", " ") @@ -152,13 +152,13 @@ func (a *Debug) actionBuildkitInfo(ctx context.Context, cmd *cli.Command) error bkClient, err := a.cli.GetBuildkitClient(ctx, cmd) if err != nil { - return errors.Wrap(err, "build new buildkitd client") + return fmt.Errorf("build new buildkitd client: %w", err) } defer bkClient.Close() info, err := bkClient.Info(ctx) if err != nil { - return errors.Wrap(err, "get buildkit info") + return fmt.Errorf("get buildkit info: %w", err) } fmt.Printf("Buildkit version: %s\n", info.BuildkitVersion.Version) @@ -174,13 +174,13 @@ func (a *Debug) actionBuildkitDiskUsage(ctx context.Context, cmd *cli.Command) e bkClient, err := a.cli.GetBuildkitClient(ctx, cmd) if err != nil { - return errors.Wrap(err, "build new buildkitd client") + return fmt.Errorf("build new buildkitd client: %w", err) } defer bkClient.Close() infos, err := bkClient.DiskUsage(ctx) if err != nil { - return errors.Wrap(err, "get buildkit disk usage") + return fmt.Errorf("get buildkit disk usage: %w", err) } w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) @@ -229,13 +229,13 @@ func (a *Debug) actionBuildkitWorkers(ctx context.Context, cmd *cli.Command) err bkClient, err := a.cli.GetBuildkitClient(ctx, cmd) if err != nil { - return errors.Wrap(err, "build new buildkitd client") + return fmt.Errorf("build new buildkitd client: %w", err) } defer bkClient.Close() workers, err := bkClient.ListWorkers(ctx) if err != nil { - return errors.Wrap(err, "get buildkit workers") + return fmt.Errorf("get buildkit workers: %w", err) } for _, info := range workers { @@ -284,7 +284,8 @@ func (a *Debug) actionBuildkitWorkers(ctx context.Context, cmd *cli.Command) err fmt.Printf("\tGC Last end time: %s\n", humanizeTime(info.GCAnalytics.LastEndTime)) fmt.Printf( "\tGC Last duration: %s\n", - humanizeDuration(info.GCAnalytics.LastEndTime.Sub(*info.GCAnalytics.LastStartTime))) + humanizeDuration(info.GCAnalytics.LastEndTime.Sub(*info.GCAnalytics.LastStartTime)), + ) fmt.Printf("\tGC Last num records before: %d\n", info.GCAnalytics.LastNumRecordsBefore) fmt.Printf("\tGC Last size before: %s\n", humanizeBytes(info.GCAnalytics.LastSizeBefore)) fmt.Printf("\tGC Last num records cleared: %d\n", info.GCAnalytics.LastNumRecordsCleared) @@ -303,13 +304,13 @@ func (a *Debug) actionBuildkitShutdownIfIdle(ctx context.Context, cmd *cli.Comma bkClient, err := a.cli.GetBuildkitClient(ctx, cmd) if err != nil { - return errors.Wrap(err, "build new buildkitd client") + return fmt.Errorf("build new buildkitd client: %w", err) } defer bkClient.Close() ok, numSessions, err := bkClient.ShutdownIfIdle(ctx) if err != nil { - return errors.Wrap(err, "shutdown buildkit if idle") + return fmt.Errorf("shutdown buildkit if idle: %w", err) } fmt.Printf("Shutting down: %t\n", ok) diff --git a/cmd/earthly/subcmd/doc_cmds.go b/cmd/earthly/subcmd/doc_cmds.go index 92056f8e28..28a6363682 100644 --- a/cmd/earthly/subcmd/doc_cmds.go +++ b/cmd/earthly/subcmd/doc_cmds.go @@ -2,6 +2,7 @@ package subcmd import ( "context" + "errors" "fmt" "io" "os" @@ -16,7 +17,6 @@ import ( "github.com/EarthBuild/earthbuild/util/hint" "github.com/EarthBuild/earthbuild/util/platutil" gwclient "github.com/moby/buildkit/frontend/gateway/client" - "github.com/pkg/errors" "github.com/urfave/cli/v3" ) @@ -101,7 +101,7 @@ func (a *Doc) action(ctx context.Context, cmd *cli.Command) error { bc, err := resolver.Resolve(ctx, gwClient, platr, target) if err != nil { - return errors.Wrap(err, "failed to resolve target") + return fmt.Errorf("failed to resolve target: %w", err) } const docsIndent = " " @@ -109,7 +109,7 @@ func (a *Doc) action(ctx context.Context, cmd *cli.Command) error { if singleTgt { tgt, err := findTarget(bc.Earthfile, target.Target) if err != nil { - return errors.Wrap(err, "failed to look up target") + return fmt.Errorf("failed to look up target: %w", err) } return a.documentSingleTarget("", bc.Features, bc.Earthfile.BaseRecipe, tgt, true) @@ -141,7 +141,8 @@ func parseDocTarget(tgtPath string) (target domain.Target, singleTgt bool, err e case '.', '/', '+': default: return domain.Target{}, false, errors.New( - "remote-paths are not currently supported - documentation targets must start with one of ['.', '/', '+']") + "remote-paths are not currently supported - documentation targets must start with one of ['.', '/', '+']", + ) } } @@ -154,7 +155,7 @@ func parseDocTarget(tgtPath string) (target domain.Target, singleTgt bool, err e target, err = domain.ParseTarget(tgtPath) if err != nil { - return domain.Target{}, false, errors.Errorf("unable to parse target %q", tgtPath) + return domain.Target{}, false, fmt.Errorf("unable to parse target %q", tgtPath) } return target, singleTgt, nil @@ -163,7 +164,7 @@ func parseDocTarget(tgtPath string) (target domain.Target, singleTgt bool, err e func docString(body string, names ...string) (string, error) { firstWordEnd := strings.IndexRune(body, ' ') if firstWordEnd == -1 { - return "", errors.Errorf("failed to parse first word of documentation comments") + return "", errors.New("failed to parse first word of documentation comments") } firstWord := body[:firstWordEnd] @@ -259,7 +260,7 @@ func addArg(b *blockIO, ft *features.Features, stmt earthfile.Statement, isBase, ident, dflt, isRequired, isGlobal, err := earthfile2llb.ArgName(cmd, isBase, ft.ExplicitGlobal) if err != nil { - return errors.Wrap(err, "failed to parse ARG statement") + return fmt.Errorf("failed to parse ARG statement: %w", err) } if onlyGlobal && !isGlobal { @@ -291,7 +292,7 @@ func parseDocSections(ft *features.Features, baseRcp, cmds earthfile.Block) (*bl for _, base := range baseRcp { err := addArg(&b, ft, base, true, true) if err != nil { - return nil, errors.Wrap(err, "failed to parse global ARG in base recipe") + return nil, fmt.Errorf("failed to parse global ARG in base recipe: %w", err) } } @@ -306,12 +307,12 @@ func parseDocSections(ft *features.Features, baseRcp, cmds earthfile.Block) (*bl case earthfile.CmdArg: err := addArg(&b, ft, rb, false, false) if err != nil { - return nil, errors.Wrap(err, "failed to parse non-global ARG") + return nil, fmt.Errorf("failed to parse non-global ARG: %w", err) } case earthfile.CmdSaveArtifact: name, localName, err := earthfile2llb.ArtifactName(cmd) if err != nil { - return nil, errors.Wrap(err, "could not parse SAVE ARTIFACT name") + return nil, fmt.Errorf("could not parse SAVE ARTIFACT name: %w", err) } idents := []string{name} @@ -336,7 +337,7 @@ func parseDocSections(ft *features.Features, baseRcp, cmds earthfile.Block) (*bl case earthfile.CmdSaveImage: identifiers, err := earthfile2llb.ImageNames(cmd) if err != nil { - return nil, errors.Wrap(err, "could not parse SAVE IMAGE name(s)") + return nil, fmt.Errorf("could not parse SAVE IMAGE name(s): %w", err) } if len(identifiers) == 0 { @@ -373,7 +374,7 @@ func (a *Doc) documentSingleTarget( blockIO, err := parseDocSections(ft, baseRcp, tgt.Recipe) if err != nil { - return errors.Wrapf(err, "failed to parse body of recipe '%v'", tgt.Name) + return fmt.Errorf("failed to parse body of recipe '%v': %w", tgt.Name, err) } const scopeIndent = " " @@ -421,5 +422,5 @@ func findTarget(ef earthfile.Tree, name string) (earthfile.Target, error) { } } - return earthfile.Target{}, errors.Errorf("could not find target named %q", name) + return earthfile.Target{}, fmt.Errorf("could not find target named %q", name) } diff --git a/cmd/earthly/subcmd/init_cmds.go b/cmd/earthly/subcmd/init_cmds.go index 7da1c19c28..b20aee5fb6 100644 --- a/cmd/earthly/subcmd/init_cmds.go +++ b/cmd/earthly/subcmd/init_cmds.go @@ -2,6 +2,8 @@ package subcmd import ( "context" + "errors" + "fmt" "io" "io/fs" "os" @@ -10,7 +12,6 @@ import ( "github.com/EarthBuild/earthbuild/buildcontext" "github.com/EarthBuild/earthbuild/util/hint" "github.com/EarthBuild/earthbuild/util/proj" - "github.com/pkg/errors" "github.com/urfave/cli/v3" ) @@ -43,12 +44,12 @@ func (a *Init) Cmds() []*cli.Command { func (a *Init) action(ctx context.Context, _ *cli.Command) error { wd, err := os.Getwd() if err != nil { - return errors.Wrap(err, "could not load current working directory") + return fmt.Errorf("could not load current working directory: %w", err) } absWd, err := filepath.Abs(wd) if err != nil { - return errors.Wrapf(err, "could not get absolute path for %q", wd) + return fmt.Errorf("could not get absolute path for %q: %w", wd, err) } efPath := filepath.Join(absWd, buildcontext.Earthfile) @@ -60,33 +61,33 @@ func (a *Init) action(ctx context.Context, _ *cli.Command) error { } if !errors.Is(err, fs.ErrNotExist) { - return errors.Wrap(err, "could not check for existing Earthfile") + return fmt.Errorf("could not check for existing Earthfile: %w", err) } projs, err := proj.All(ctx, absWd) if err != nil { - return errors.Wrapf(err, "could not get projects for %q", absWd) + return fmt.Errorf("could not get projects for %q: %w", absWd, err) } if len(projs) == 0 { - return errors.Errorf("no supported projects found in directory %q", absWd) + return fmt.Errorf("no supported projects found in directory %q", absWd) } f, err := os.Create(efPath) // #nosec G304 if err != nil { - return errors.Wrapf(err, "could not create %q", efPath) + return fmt.Errorf("could not create %q: %w", efPath, err) } defer f.Close() _, err = f.WriteString("VERSION --arg-scope-and-set 0.7\n\n") if err != nil { - return errors.Wrapf(err, "could not write version string in %q", efPath) + return fmt.Errorf("could not write version string in %q: %w", efPath, err) } if len(projs) > 1 { // This is easy enough to support when we have more than one project // type, but for now there's no point. - return errors.Errorf("%d projects detected, but multiple project types are not supported by init yet", len(projs)) + return fmt.Errorf("%d projects detected, but multiple project types are not supported by init yet", len(projs)) } p := projs[0] @@ -94,7 +95,7 @@ func (a *Init) action(ctx context.Context, _ *cli.Command) error { // In the distant future, this may be used to generate multiple // Earthfiles over multiple directories and call them from a main // Earthfile target with BUILD. - return errors.Errorf("project type %T wants to generate an Earthfile in an unsupported directory: %q", p, p.Root(ctx)) + return fmt.Errorf("project type %T wants to generate an Earthfile in an unsupported directory: %q", p, p.Root(ctx)) } return initSingleProject(f, p) @@ -103,7 +104,7 @@ func (a *Init) action(ctx context.Context, _ *cli.Command) error { func initSingleProject(w io.Writer, p proj.Project) error { tgts, err := p.Targets() if err != nil { - return errors.Wrapf(err, "could not generate targets for project type %T", p) + return fmt.Errorf("could not generate targets for project type %T: %w", p, err) } for i, tgt := range tgts { @@ -112,13 +113,13 @@ func initSingleProject(w io.Writer, p proj.Project) error { if i > 0 { _, err = w.Write([]byte("\n")) if err != nil { - return errors.Wrapf(err, "could not write newline separator between targets") + return fmt.Errorf("could not write newline separator between targets: %w", err) } } err := tgt.Format(w, efIndent) if err != nil { - return errors.Wrapf(err, "could not format target for project type %T", p) + return fmt.Errorf("could not format target for project type %T: %w", p, err) } } diff --git a/cmd/earthly/subcmd/ls_cmds.go b/cmd/earthly/subcmd/ls_cmds.go index c394810eaa..0404daa398 100644 --- a/cmd/earthly/subcmd/ls_cmds.go +++ b/cmd/earthly/subcmd/ls_cmds.go @@ -2,6 +2,7 @@ package subcmd import ( "context" + "errors" "fmt" "sort" "strings" @@ -11,7 +12,6 @@ import ( "github.com/EarthBuild/earthbuild/earthfile2llb" "github.com/EarthBuild/earthbuild/internal/earthfile" gwclient "github.com/moby/buildkit/frontend/gateway/client" - "github.com/pkg/errors" "github.com/urfave/cli/v3" ) @@ -85,27 +85,27 @@ func (a *List) action(ctx context.Context, cmd *cli.Command) error { gitLookup := buildcontext.NewGitLookup(a.cli.Console(), a.cli.Flags().SSHAuthSock) resolver := buildcontext.NewResolver( - nil, gitLookup, a.cli.Console(), "", a.cli.Flags().GitBranchOverride, a.cli.Flags().GitLFSPullInclude, 0, "") + nil, gitLookup, a.cli.Console(), "", a.cli.Flags().GitBranchOverride, a.cli.Flags().GitLFSPullInclude, 0, "", + ) // TODO this is a nil pointer which causes a panic if we try to expand a remotelyreferenced earthfile // it's expensive to create this gwclient, so we need to implement a lazy eval which returns it when required. var ( - gwClient gwclient.Client - notExistErr buildcontext.EarthfileNotExistError + gwClient gwclient.Client ) // the +base is required to make ParseTarget work; however is ignored by GetTargets target, err := domain.ParseTarget(targetToParse + "+base") - if errors.As(err, ¬ExistErr) { - return errors.Errorf("unable to locate Earthfile under %s", targetToDisplay) + if _, ok := errors.AsType[buildcontext.EarthfileNotExistError](err); ok { + return fmt.Errorf("unable to locate Earthfile under %s", targetToDisplay) } else if err != nil { return err } targets, err := earthfile2llb.GetTargets(ctx, resolver, gwClient, target) if err != nil { - if errors.As(errors.Cause(err), ¬ExistErr) { - return errors.Errorf("unable to locate Earthfile under %s", targetToDisplay) + if _, ok := errors.AsType[buildcontext.EarthfileNotExistError](err); ok { + return fmt.Errorf("unable to locate Earthfile under %s", targetToDisplay) } return err diff --git a/cmd/earthly/subcmd/prune_cmds.go b/cmd/earthly/subcmd/prune_cmds.go index 800ba5660a..8bd41c3660 100644 --- a/cmd/earthly/subcmd/prune_cmds.go +++ b/cmd/earthly/subcmd/prune_cmds.go @@ -2,13 +2,14 @@ package subcmd import ( "context" + "errors" + "fmt" "time" "github.com/EarthBuild/earthbuild/buildkitd" "github.com/EarthBuild/earthbuild/util/flagutil" "github.com/dustin/go-humanize" "github.com/moby/buildkit/client" - "github.com/pkg/errors" "github.com/urfave/cli/v3" "golang.org/x/sync/errgroup" ) @@ -88,9 +89,10 @@ func (a *Prune) action(ctx context.Context, cmd *cli.Command) error { err = buildkitd.ResetCache( ctx, a.cli.Console(), a.cli.Flags().BuildkitdImage, a.cli.Flags().ContainerName, - a.cli.Flags().InstallationName, a.cli.Flags().ContainerFrontend, a.cli.Flags().BuildkitdSettings) + a.cli.Flags().InstallationName, a.cli.Flags().ContainerFrontend, a.cli.Flags().BuildkitdSettings, + ) if err != nil { - return errors.Wrap(err, "reset cache") + return fmt.Errorf("reset cache: %w", err) } return nil @@ -98,7 +100,7 @@ func (a *Prune) action(ctx context.Context, cmd *cli.Command) error { bkClient, err := a.cli.GetBuildkitClient(ctx, cmd) if err != nil { - return errors.Wrap(err, "prune new buildkitd client") + return fmt.Errorf("prune new buildkitd client: %w", err) } defer bkClient.Close() @@ -117,7 +119,7 @@ func (a *Prune) action(ctx context.Context, cmd *cli.Command) error { eg.Go(func() error { err = bkClient.Prune(ctx, ch, opts...) if err != nil { - return errors.Wrap(err, "buildkit prune") + return fmt.Errorf("buildkit prune: %w", err) } close(ch) @@ -145,7 +147,7 @@ func (a *Prune) action(ctx context.Context, cmd *cli.Command) error { err = eg.Wait() if err != nil { - return errors.Wrap(err, "err group") + return fmt.Errorf("err group: %w", err) } a.cli.Console().Printf("Freed %s\n", humanize.Bytes(total)) diff --git a/config/config.go b/config/config.go index 4fc9f4efec..471911e9ad 100644 --- a/config/config.go +++ b/config/config.go @@ -3,6 +3,7 @@ package config import ( + "errors" "fmt" "hash/crc32" "os" @@ -13,7 +14,6 @@ import ( "time" "github.com/EarthBuild/earthbuild/util/cliutil" - "github.com/pkg/errors" "gopkg.in/yaml.v3" ) @@ -63,10 +63,10 @@ const ( var ( // ErrInvalidTransport occurs when a URL transport type is invalid. - ErrInvalidTransport = errors.Errorf("invalid transport") + ErrInvalidTransport = errors.New("invalid transport") // ErrInvalidAuth occurs when the auth type is invalid. - ErrInvalidAuth = errors.Errorf("invalid auth") + ErrInvalidAuth = errors.New("invalid auth") ) // GlobalConfig contains global config values. @@ -161,7 +161,7 @@ func ParseYAML(yamlData []byte, installationName string) (Config, error) { err := yaml.Unmarshal(yamlData, &config) if err != nil { - return Config{}, errors.Wrap(err, "failed to parse YAML config") + return Config{}, fmt.Errorf("failed to parse YAML config: %w", err) } if config.Git == nil { @@ -170,7 +170,7 @@ func ParseYAML(yamlData []byte, installationName string) (Config, error) { err = parseRelPaths(installationName, &config) if err != nil { - return Config{}, errors.Wrap(err, "failed to parse relative path") + return Config{}, fmt.Errorf("failed to parse relative path: %w", err) } return config, nil @@ -215,10 +215,10 @@ func Upsert(config []byte, path, value string) ([]byte, error) { if otherErr != nil { // Give up. if err != nil { - return []byte{}, errors.Wrapf(err, "failed to parse config file") + return []byte{}, fmt.Errorf("failed to parse config file: %w", err) } - return []byte{}, errors.Wrapf(otherErr, "failed to parse config file") + return []byte{}, fmt.Errorf("failed to parse config file: %w", otherErr) } base.Content = []*yaml.Node{{Kind: yaml.MappingNode}} @@ -228,16 +228,16 @@ func Upsert(config []byte, path, value string) ([]byte, error) { t, _, err := validatePath(reflect.TypeFor[Config](), pathParts) if err != nil { - return []byte{}, errors.Wrap(err, "path is not valid") + return []byte{}, fmt.Errorf("path is not valid: %w", err) } yamlValue, err := valueToYaml(value) if err != nil { - return []byte{}, errors.Wrap(err, "could not parse value") + return []byte{}, fmt.Errorf("could not parse value: %w", err) } if !keyAndValueCompatible(t, yamlValue) { - return []byte{}, errors.Errorf("cannot set %s to %v, as the types are incompatible", path, value) + return []byte{}, fmt.Errorf("cannot set %s to %v, as the types are incompatible", path, value) } setYamlValue(base, pathParts, yamlValue) @@ -257,7 +257,7 @@ func Delete(config []byte, path string) ([]byte, error) { err := yaml.Unmarshal(config, base) if err != nil { - return []byte{}, errors.Wrapf(err, "failed to parse config file") + return []byte{}, fmt.Errorf("failed to parse config file: %w", err) } if base.IsZero() { @@ -268,7 +268,7 @@ func Delete(config []byte, path string) ([]byte, error) { _, _, err = validatePath(reflect.TypeFor[Config](), pathParts) if err != nil { - return []byte{}, errors.Wrap(err, "path is not valid") + return []byte{}, fmt.Errorf("path is not valid: %w", err) } deleteYamlValue(base, pathParts) @@ -286,7 +286,7 @@ func Delete(config []byte, path string) ([]byte, error) { func PrintHelp(path string) error { t, help, err := validatePath(reflect.TypeFor[Config](), splitPath(path)) if err != nil { - return errors.Wrapf(err, "'%s' is not a valid config value", path) + return fmt.Errorf("'%s' is not a valid config value: %w", path, err) } fmt.Printf("(%s): %s\n", t.Kind(), help) @@ -310,7 +310,7 @@ func splitPath(path string) []string { func validatePath(t reflect.Type, path []string) (reflect.Type, string, error) { if len(path) == 0 { - return nil, "", errors.New("No path present") + return nil, "", errors.New("no path present") } if t.Kind() == reflect.Map { @@ -341,7 +341,7 @@ func validatePath(t reflect.Type, path []string) (reflect.Type, string, error) { } } - return nil, "", errors.Errorf("no path for %s", strings.Join(path, ".")) + return nil, "", fmt.Errorf("no path for %s", strings.Join(path, ".")) } func valueToYaml(value string) (*yaml.Node, error) { @@ -349,7 +349,7 @@ func valueToYaml(value string) (*yaml.Node, error) { err := yaml.Unmarshal([]byte(value), valueNode) if err != nil { - return nil, errors.Errorf("%s is not a valid YAML value", value) + return nil, fmt.Errorf("%s is not a valid YAML value", value) } // Unfold all the yaml so it's not mixed inline and flow styles in the final document @@ -513,7 +513,7 @@ func deleteYamlValue(node *yaml.Node, path []string) []string { func ReadConfigFile(configPath string) ([]byte, error) { yamlData, err := os.ReadFile(configPath) // #nosec G304 if err != nil { - return []byte{}, errors.Wrapf(err, "failed to read from %s", configPath) + return []byte{}, fmt.Errorf("failed to read from %s: %w", configPath, err) } return yamlData, nil @@ -532,7 +532,7 @@ func WriteConfigFile(configPath string, data []byte) error { func parseRelPaths(instName string, cfg *Config) error { err := parseTLSPaths(instName, cfg) if err != nil { - return errors.Wrap(err, "could not parse relative TLS paths") + return fmt.Errorf("could not parse relative TLS paths: %w", err) } return nil @@ -554,7 +554,7 @@ func parseTLSPaths(instName string, cfg *Config) error { for name, field := range fields { err := parsePath(instName, field) if err != nil { - return errors.Wrapf(err, "could not parse %v path %q", name, *field) + return fmt.Errorf("could not parse %v path %q: %w", name, *field, err) } } diff --git a/debugger/server/server.go b/debugger/server/server.go index 5cd87a31f2..cb65f6a55b 100644 --- a/debugger/server/server.go +++ b/debugger/server/server.go @@ -10,8 +10,6 @@ import ( "sync" "github.com/EarthBuild/earthbuild/slog" - - "github.com/pkg/errors" ) // Server provides a debugger server. @@ -39,7 +37,7 @@ func (s *Server) handleConn(conn net.Conn, readFrom, writeTo chan []byte) { n, err := conn.Read(buf) if err != nil { - s.log.Error(errors.Wrap(err, "reading from connection failed")) + s.log.Error(fmt.Errorf("reading from connection failed: %w", err)) break } @@ -60,7 +58,7 @@ func (s *Server) handleConn(conn net.Conn, readFrom, writeTo chan []byte) { case data := <-readFrom: _, err := conn.Write(data) if err != nil { - s.log.Error(errors.Wrap(err, "writing to connection failed")) + s.log.Error(fmt.Errorf("writing to connection failed: %w", err)) } } } @@ -86,7 +84,7 @@ func (s *Server) handleRequest(conn net.Conn) { _, err := conn.Read(buf) if err != nil { - connLog.Error(errors.Wrap(err, "reading from connection failed")) + connLog.Error(fmt.Errorf("reading from connection failed: %w", err)) return } diff --git a/debugger/terminal/terminal_other.go b/debugger/terminal/terminal_other.go index 57701c5acb..6a14b5397e 100644 --- a/debugger/terminal/terminal_other.go +++ b/debugger/terminal/terminal_other.go @@ -5,6 +5,8 @@ package terminal import ( "context" "encoding/json" + "errors" + "fmt" "io" "os" "os/signal" @@ -13,16 +15,14 @@ import ( "github.com/EarthBuild/earthbuild/conslogging" "github.com/EarthBuild/earthbuild/debugger/common" - "github.com/creack/pty" - "github.com/pkg/errors" "golang.org/x/term" ) func handlePtyData(data []byte) error { _, err := os.Stdout.Write(data) if err != nil { - return errors.Wrap(err, "failed to write data to stdout") + return fmt.Errorf("failed to write data to stdout: %w", err) } return nil @@ -179,7 +179,7 @@ func (ts *termState) makeRaw() error { // #nosec G115 - Fd() returns a small int ts.oldState, err = term.MakeRaw(int(os.Stdin.Fd())) if err != nil { - return errors.Wrap(err, "failed to initialize terminal in raw mode") + return fmt.Errorf("failed to initialize terminal in raw mode: %w", err) } } @@ -194,7 +194,7 @@ func (ts *termState) restore() error { // #nosec G115 - Fd() returns a small int err := term.Restore(int(os.Stdin.Fd()), ts.oldState) if err != nil { - return errors.Wrap(err, "failed to restore terminal mode") + return fmt.Errorf("failed to restore terminal mode: %w", err) } ts.oldState = nil diff --git a/debugger/terminal/terminal_windows.go b/debugger/terminal/terminal_windows.go index df32d6243d..2db2a742b5 100644 --- a/debugger/terminal/terminal_windows.go +++ b/debugger/terminal/terminal_windows.go @@ -4,11 +4,10 @@ package terminal import ( "context" + "errors" "io" "github.com/EarthBuild/earthbuild/conslogging" - - "github.com/pkg/errors" ) func ConnectTerm(ctx context.Context, addr io.ReadWriteCloser, console conslogging.ConsoleLogger) error { diff --git a/docker2earth/convert.go b/docker2earth/convert.go index f2f5d87ce4..2b93380c16 100644 --- a/docker2earth/convert.go +++ b/docker2earth/convert.go @@ -3,6 +3,7 @@ package docker2earth import ( "bufio" "bytes" + "errors" "fmt" "io" "os" @@ -15,7 +16,6 @@ import ( "github.com/moby/buildkit/frontend/dockerfile/instructions" "github.com/moby/buildkit/frontend/dockerfile/parser" - "github.com/pkg/errors" ) // Ideally this would point to "the current version" rather than being hard-coded, but the single @@ -33,7 +33,7 @@ func getArtifactName(s string) string { // an Earthfile in the current directory and error is returned if an Earthfile already exists. func Docker2Earth(dockerfilePath, earthfilePath, imageTag string) error { if exists, _ := fileutil.FileExists(earthfilePath); exists { - return errors.Errorf("earthfile already exists; please delete it if you wish to continue") + return errors.New("earthfile already exists; please delete it if you wish to continue") } var in io.Reader @@ -42,7 +42,7 @@ func Docker2Earth(dockerfilePath, earthfilePath, imageTag string) error { } else { in2, err := os.Open(dockerfilePath) // #nosec G304 if err != nil { - return errors.Wrapf(err, "failed to open %q", dockerfilePath) + return fmt.Errorf("failed to open %q: %w", dockerfilePath, err) } defer in2.Close() @@ -61,12 +61,12 @@ func Docker2Earth(dockerfilePath, earthfilePath, imageTag string) error { dockerfile, err := parser.Parse(in) if err != nil { - return errors.Wrapf(err, "failed to parse Dockerfile located at %q", dockerfilePath) + return fmt.Errorf("failed to parse Dockerfile located at %q: %w", dockerfilePath, err) } stages, initialArgs, err := instructions.Parse(dockerfile.AST) if err != nil { - return errors.Wrapf(err, "failed to parse Dockerfile located at %q", dockerfilePath) + return fmt.Errorf("failed to parse Dockerfile located at %q: %w", dockerfilePath, err) } names := map[string]int{} @@ -96,12 +96,12 @@ func Docker2Earth(dockerfilePath, earthfilePath, imageTag string) error { if strings.HasPrefix(l, "COPY ") && strings.Contains(l, "--from") { parts := strings.Split(l, " ") if len(parts) != 4 { - return errors.Errorf("failed to parse %q", l) + return fmt.Errorf("failed to parse %q", l) } kv := strings.Split(parts[1], "=") if len(kv) != 2 { - return errors.Errorf("failed to parse %q", l) + return fmt.Errorf("failed to parse %q", l) } fromStageName := kv[1] @@ -112,7 +112,7 @@ func Docker2Earth(dockerfilePath, earthfilePath, imageTag string) error { } if strings.HasPrefix(l, "ADD ") { - return errors.Errorf("earth does not support ADD, please convert to COPY instead") + return errors.New("earth does not support ADD, please convert to COPY instead") } targets[i+1] = append(targets[i+1], l) @@ -132,7 +132,7 @@ func Docker2Earth(dockerfilePath, earthfilePath, imageTag string) error { } else { out2, err := os.Create(earthfilePath) // #nosec G304 if err != nil { - return errors.Wrapf(err, "failed to create Earthfile under %q", earthfilePath) + return fmt.Errorf("failed to create Earthfile under %q: %w", earthfilePath, err) } defer out2.Close() @@ -203,7 +203,7 @@ func GenerateEarthfile( ) (string, error) { t, err := template.New("earthfile").Parse(earthfileTemplate) if err != nil { - return "", errors.Wrapf(err, "failed to parse Earthfile template") + return "", fmt.Errorf("failed to parse Earthfile template: %w", err) } buf := &bytes.Buffer{} @@ -211,7 +211,7 @@ func GenerateEarthfile( if !filepath.IsAbs(dockerfilePath) { dockerfilePath, err = filepath.Abs(filepath.Join(buildContextPath, dockerfilePath)) if err != nil { - return "", errors.Wrapf(err, "failed to get get absolute path for dockerfile") + return "", fmt.Errorf("failed to get get absolute path for dockerfile: %w", err) } } @@ -226,7 +226,7 @@ func GenerateEarthfile( Platforms: platforms, }) if err != nil { - return "", errors.Wrapf(err, "failed to create Earthfile content from template") + return "", fmt.Errorf("failed to create Earthfile content from template: %w", err) } return buf.String(), nil diff --git a/docker2earth/convert_test.go b/docker2earth/convert_test.go index e0a9c0f6a5..ffbc47acfd 100644 --- a/docker2earth/convert_test.go +++ b/docker2earth/convert_test.go @@ -205,7 +205,8 @@ build: got, err := docker2earth.GenerateEarthfile( tt.args.buildContextPath, tt.args.dockerfilePath, tt.args.imageTags, - tt.args.buildArgs, tt.args.platforms, tt.args.target) + tt.args.buildArgs, tt.args.platforms, tt.args.target, + ) if !errors.Is(err, tt.wantErr) { t.Errorf("GenerateEarthfile() error = %v, wantErr %v", err, tt.wantErr) return diff --git a/dockertar/dockertar.go b/dockertar/dockertar.go index 978e14854c..cd34c4ef52 100644 --- a/dockertar/dockertar.go +++ b/dockertar/dockertar.go @@ -5,18 +5,17 @@ import ( "archive/tar" "bufio" "encoding/json" + "fmt" "io" "os" "strings" - - "github.com/pkg/errors" ) // GetID returns the docker sha256 ID of the image stored within the given .tar file. func GetID(tarFilePath string) (string, error) { tarFile, err := os.Open(tarFilePath) // #nosec G304 if err != nil { - return "", errors.Wrapf(err, "open file %s for reading", tarFilePath) + return "", fmt.Errorf("open file %s for reading: %w", tarFilePath, err) } defer tarFile.Close() @@ -30,13 +29,13 @@ func GetID(tarFilePath string) (string, error) { } if err != nil { - return "", errors.Wrapf(err, "reading tar %s", tarFilePath) + return "", fmt.Errorf("reading tar %s: %w", tarFilePath, err) } if header.Name == "manifest.json" && !header.FileInfo().IsDir() { dt, err := io.ReadAll(tarR) if err != nil { - return "", errors.Wrapf(err, "read manifest.json from tar %s", tarFilePath) + return "", fmt.Errorf("read manifest.json from tar %s: %w", tarFilePath, err) } var jsonData []struct { @@ -45,16 +44,16 @@ func GetID(tarFilePath string) (string, error) { err = json.Unmarshal(dt, &jsonData) if err != nil { - return "", errors.Wrapf(err, "unmarshal json tar manifest for %s", tarFilePath) + return "", fmt.Errorf("unmarshal json tar manifest for %s: %w", tarFilePath, err) } if len(jsonData) != 1 { - return "", errors.Errorf("unexpected len != 1 docker manifest in %s", tarFilePath) + return "", fmt.Errorf("unexpected len != 1 docker manifest in %s", tarFilePath) } return strings.TrimSuffix(jsonData[0].Config, ".json"), nil } } - return "", errors.Errorf("docker tar manifest.json not found in tar %s", tarFilePath) + return "", fmt.Errorf("docker tar manifest.json not found in tar %s", tarFilePath) } diff --git a/domain/artifact.go b/domain/artifact.go index 49525394a6..45da647d0b 100644 --- a/domain/artifact.go +++ b/domain/artifact.go @@ -4,8 +4,6 @@ import ( "fmt" "path" "strings" - - "github.com/pkg/errors" ) // Artifact is an earth artifact identifier. @@ -37,19 +35,19 @@ func ParseArtifact(artifactName string) (Artifact, error) { } if len(parts) != 2 { - return Artifact{}, errors.Errorf("invalid artifact name %s", artifactName) + return Artifact{}, fmt.Errorf("invalid artifact name %s", artifactName) } partsSlash := strings.SplitN(parts[1], "/", 2) if len(partsSlash) != 2 { - return Artifact{}, errors.Errorf("invalid artifact name %s", artifactName) + return Artifact{}, fmt.Errorf("invalid artifact name %s", artifactName) } earthTargetName := escapePlus(parts[0]) + "+" + partsSlash[0] target, err := ParseTarget(earthTargetName) if err != nil { - return Artifact{}, errors.Wrapf(err, "invalid artifact name %s", artifactName) + return Artifact{}, fmt.Errorf("invalid artifact name %s: %w", artifactName, err) } artifactPath := "/" + partsSlash[1] diff --git a/domain/command.go b/domain/command.go index ad6f7d105f..378ed9bc56 100644 --- a/domain/command.go +++ b/domain/command.go @@ -3,8 +3,6 @@ package domain import ( "fmt" "regexp" - - "github.com/pkg/errors" ) var _ Reference = Command{} @@ -113,7 +111,7 @@ func ParseCommand(fullCommandName string) (Command, error) { ok := commandNameRegex.MatchString(command) if !ok { - return Command{}, errors.Errorf("command name %s does not match %s", command, commandNamePattern) + return Command{}, fmt.Errorf("command name %s does not match %s", command, commandNamePattern) } return Command{ diff --git a/domain/importtracker.go b/domain/importtracker.go index 320bb4bb07..5e03eaa0fd 100644 --- a/domain/importtracker.go +++ b/domain/importtracker.go @@ -1,13 +1,12 @@ package domain import ( + "errors" "fmt" "maps" "strings" "github.com/EarthBuild/earthbuild/conslogging" - - "github.com/pkg/errors" ) // ImportTrackerVal is used to resolve imports. @@ -56,7 +55,7 @@ func (ir *ImportTracker) Add(importStr string, as string, global, currentlyPrivi parsedImport, err := ParseTarget(aTarget) if err != nil { - return errors.Wrapf(err, "could not parse IMPORT %s", importStr) + return fmt.Errorf("could not parse IMPORT %s: %w", importStr, err) } importStr = parsedImport.ProjectCanonical() // normalize @@ -67,7 +66,7 @@ func (ir *ImportTracker) Add(importStr string, as string, global, currentlyPrivi switch { case parsedImport.IsImportReference(): - return errors.Errorf("IMPORT %s not supported", importStr) + return fmt.Errorf("IMPORT %s not supported", importStr) case parsedImport.IsRemote(): path = parsedImport.GetGitURL() allowPrivileged = allowPrivileged && allowPrivilegedFlag @@ -78,17 +77,17 @@ func (ir *ImportTracker) Add(importStr string, as string, global, currentlyPrivi ir.console.Printf("the --allow-privileged flag has no effect when referencing a local target\n") } default: - return errors.Errorf("IMPORT %s not supported", importStr) + return fmt.Errorf("IMPORT %s not supported", importStr) } pathParts := strings.Split(path, "/") if len(pathParts) < 1 { - return errors.Errorf("IMPORT %s not supported", importStr) + return fmt.Errorf("IMPORT %s not supported", importStr) } defaultAs := pathParts[len(pathParts)-1] if defaultAs == "" { - return errors.Errorf("IMPORT %s not supported", importStr) + return fmt.Errorf("IMPORT %s not supported", importStr) } if (defaultAs == "." || defaultAs == "..") && as == "" { @@ -100,13 +99,13 @@ func (ir *ImportTracker) Add(importStr string, as string, global, currentlyPrivi } if strings.ContainsAny(as, "/:") { - return errors.Errorf("invalid IMPORT AS %s", as) + return fmt.Errorf("invalid IMPORT AS %s", as) } if global { _, exists := ir.global[as] if exists { - return errors.Errorf("import ref %s already exists in this scope", as) + return fmt.Errorf("import ref %s already exists in this scope", as) } ir.global[as] = ImportTrackerVal{ @@ -116,7 +115,7 @@ func (ir *ImportTracker) Add(importStr string, as string, global, currentlyPrivi } else { _, exists := ir.local[as] if exists { - return errors.Errorf("import ref %s already exists in this scope", as) + return fmt.Errorf("import ref %s already exists in this scope", as) } ir.local[as] = ImportTrackerVal{ @@ -140,7 +139,7 @@ func (ir *ImportTracker) Deref( if !ok { resolvedImport, ok = ir.global[ref.GetImportRef()] if !ok { - return nil, false, false, errors.Errorf("import reference %s could not be resolved", ref.GetImportRef()) + return nil, false, false, fmt.Errorf("import reference %s could not be resolved", ref.GetImportRef()) } } diff --git a/domain/reference.go b/domain/reference.go index d7b9c18bfe..67006900f2 100644 --- a/domain/reference.go +++ b/domain/reference.go @@ -1,13 +1,12 @@ package domain import ( + "errors" "fmt" "os" "path" "path/filepath" "strings" - - "github.com/pkg/errors" ) // Reference is a target or a command reference. @@ -77,8 +76,9 @@ func JoinReferences(r1 Reference, r2 Reference) (Reference, error) { if r2.IsLocalExternal() { if path.IsAbs(r2.GetLocalPath()) { - return Target{}, errors.Errorf( - "absolute path %s not supported as reference in external target context", r2.GetLocalPath()) + return Target{}, fmt.Errorf( + "absolute path %s not supported as reference in external target context", r2.GetLocalPath(), + ) } gitURL = path.Join(r1.GetGitURL(), localPath) @@ -119,7 +119,7 @@ func JoinReferences(r1 Reference, r2 Reference) (Reference, error) { Command: name, }, nil default: - return nil, errors.Errorf("joining references not supported for type %T", r2) + return nil, fmt.Errorf("joining references not supported for type %T", r2) } } @@ -197,7 +197,7 @@ func parseCommon(fullName string) (gitURL, tag, localPath, importRef, name strin } if len(partsPlus) != 2 { - return "", "", "", "", "", errors.Errorf("invalid target ref %s", fullName) + return "", "", "", "", "", fmt.Errorf("invalid target ref %s", fullName) } if partsPlus[0] == "" { @@ -273,7 +273,7 @@ func splitUnescapePlus(str string) ([]string, error) { } if escape { - return nil, errors.Errorf("cannot split by +: unterminated escape sequence at the end of %s", str) + return nil, fmt.Errorf("cannot split by +: unterminated escape sequence at the end of %s", str) } if len(word) > 0 { diff --git a/domain/target.go b/domain/target.go index 6f03809d95..5cc00d9e52 100644 --- a/domain/target.go +++ b/domain/target.go @@ -3,8 +3,6 @@ package domain import ( "fmt" "regexp" - - "github.com/pkg/errors" ) var _ Reference = Target{} @@ -113,7 +111,7 @@ func ParseTarget(fullTargetName string) (Target, error) { ok := targetNameRegex.MatchString(target) if !ok { - return Target{}, errors.Errorf("target name %s does not match %s", target, targetNamePattern) + return Target{}, fmt.Errorf("target name %s does not match %s", target, targetNamePattern) } return Target{ diff --git a/earthfile2llb/cachedmetaresolver.go b/earthfile2llb/cachedmetaresolver.go index 5bb30d4433..db014c6a4e 100644 --- a/earthfile2llb/cachedmetaresolver.go +++ b/earthfile2llb/cachedmetaresolver.go @@ -2,12 +2,12 @@ package earthfile2llb import ( "context" + "fmt" "github.com/EarthBuild/earthbuild/util/syncutil/synccache" "github.com/containerd/platforms" "github.com/moby/buildkit/client/llb" "github.com/opencontainers/go-digest" - "github.com/pkg/errors" ) var _ llb.ImageMetaResolver = &CachedMetaResolver{} @@ -70,7 +70,7 @@ func (cmr *CachedMetaResolver) ResolveImageConfig( entry, ok := value.(cachedMetaResolverEntry) if !ok { - return "", "", nil, errors.Errorf("want cachedMetaResolverEntry, got %T", value) + return "", "", nil, fmt.Errorf("want cachedMetaResolverEntry, got %T", value) } return entry.ref, entry.dgst, entry.config, nil diff --git a/earthfile2llb/converter.go b/earthfile2llb/converter.go index 65bc1d30a4..96857f5e8d 100644 --- a/earthfile2llb/converter.go +++ b/earthfile2llb/converter.go @@ -7,6 +7,7 @@ import ( "encoding/binary" "encoding/hex" "encoding/json" + "errors" "fmt" "io/fs" "maps" @@ -60,7 +61,6 @@ import ( "github.com/moby/buildkit/session/localhost" solverpb "github.com/moby/buildkit/solver/pb" "github.com/moby/buildkit/util/apicaps" - "github.com/pkg/errors" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -161,7 +161,7 @@ func NewConverter( opt.Runner, ) if err != nil { - return nil, errors.Wrap(err, "new logbus target") + return nil, fmt.Errorf("new logbus target: %w", err) } logbusTarget.SetStart(time.Now()) @@ -272,7 +272,7 @@ func (c *Converter) fromTarget( ) (retErr error) { cmdID, cmd, err := c.newLogbusCommand(ctx, "FROM "+targetName) if err != nil { - return errors.Wrap(err, "failed to create command") + return fmt.Errorf("failed to create command: %w", err) } defer func() { @@ -281,13 +281,13 @@ func (c *Converter) fromTarget( depTarget, err := domain.ParseTarget(targetName) if err != nil { - return errors.Wrapf(err, "parse target name %s", targetName) + return fmt.Errorf("parse target name %s: %w", targetName, err) } mts, err := c. buildTarget(ctx, depTarget.String(), platform, allowPrivileged, passArgs, buildArgs, false, fromCmd, cmdID, nil) if err != nil { - return errors.Wrapf(err, "apply build %s", depTarget.String()) + return fmt.Errorf("apply build %s: %w", depTarget.String(), err) } if mts.Final.RanInteractive { @@ -325,7 +325,7 @@ func (c *Converter) FromDockerfile( ctx, err = c.ftrs.WithContext(ctx) if err != nil { - return errors.Wrap(err, "failed to add feature flags to context") + return fmt.Errorf("failed to add feature flags to context: %w", err) } err = c.checkAllowed(fromDockerfileCmd) @@ -344,7 +344,7 @@ func (c *Converter) FromDockerfile( cmdID, cmd, err := c.newLogbusCommand(ctx, "FROM DOCKERFILE "+dfPath) if err != nil { - return errors.Wrap(err, "failed to create command") + return fmt.Errorf("failed to create command: %w", err) } defer func() { @@ -384,28 +384,28 @@ func (c *Converter) FromDockerfile( dockerfileMetaTargetRef, err = c.joinRefs(dockerfileMetaTarget) if err != nil { - return errors.Wrap(err, "join targets") + return fmt.Errorf("join targets: %w", err) } var ok bool dockerfileMetaTarget, ok = dockerfileMetaTargetRef.(domain.Target) if !ok { - return errors.Errorf("want domain.Target, got %T", dockerfileMetaTargetRef) + return fmt.Errorf("want domain.Target, got %T", dockerfileMetaTargetRef) } var data *buildcontext.Data data, err = c.opt.Resolver.Resolve(ctx, c.opt.GwClient, c.platr, dockerfileMetaTarget) if err != nil { - return errors.Wrap(err, "resolve build context for dockerfile") + return fmt.Errorf("resolve build context for dockerfile: %w", err) } c.opt.BuildContextProvider.AddDirs(data.LocalDirs) dfData, err = os.ReadFile(data.BuildFilePath) if err != nil { - return errors.Wrapf(err, "read file %s", data.BuildFilePath) + return fmt.Errorf("read file %s: %w", data.BuildFilePath, err) } } } @@ -457,7 +457,7 @@ func (c *Converter) FromDockerfile( joinWrap(buildArgs, "(", " ", ") "), contextArtifact.String(), )) if err != nil { - return errors.Wrapf(err, "copyOp FROM DOCKERFILE") + return fmt.Errorf("copyOp FROM DOCKERFILE: %w", err) } BuildContextFactory = llbfactory.PreconstructedState(copyState) @@ -479,21 +479,21 @@ func (c *Converter) FromDockerfile( dockerfileMetaTargetRef, err = c.joinRefs(dockerfileMetaTarget) if err != nil { - return errors.Wrap(err, "join targets") + return fmt.Errorf("join targets: %w", err) } var ok bool dockerfileMetaTarget, ok = dockerfileMetaTargetRef.(domain.Target) if !ok { - return errors.Errorf("want domain.Target, got %T", dockerfileMetaTargetRef) + return fmt.Errorf("want domain.Target, got %T", dockerfileMetaTargetRef) } var data *buildcontext.Data data, err = c.opt.Resolver.Resolve(ctx, c.opt.GwClient, c.platr, dockerfileMetaTarget) if err != nil { - return errors.Wrap(err, "resolve build context for dockerfile") + return fmt.Errorf("resolve build context for dockerfile: %w", err) } c.opt.BuildContextProvider.AddDirs(data.LocalDirs) @@ -502,7 +502,7 @@ func (c *Converter) FromDockerfile( // Imply dockerfile as being ./Dockerfile in the root of the build context. dfData, err = os.ReadFile(data.BuildFilePath) if err != nil { - return errors.Wrapf(err, "read file %s", data.BuildFilePath) + return fmt.Errorf("read file %s: %w", data.BuildFilePath, err) } } @@ -511,7 +511,7 @@ func (c *Converter) FromDockerfile( bc, err := dockerui.NewClient(c.opt.GwClient) if err != nil { - return errors.Wrap(err, "dockerui.NewClient") + return fmt.Errorf("dockerui.NewClient: %w", err) } var pncvf variables.ProcessNonConstantVariableFunc @@ -541,19 +541,19 @@ func (c *Converter) FromDockerfile( done() if err != nil { - return errors.Wrapf(err, "dockerfile2llb %s", dfPath) + return fmt.Errorf("dockerfile2llb %s: %w", dfPath, err) } // Convert dockerfile2llb image into earthfile2llb image via JSON. imgDt, err := json.Marshal(dfImg) if err != nil { - return errors.Wrap(err, "marshal dockerfile image") + return fmt.Errorf("marshal dockerfile image: %w", err) } var img image.Image err = json.Unmarshal(imgDt, &img) if err != nil { - return errors.Wrap(err, "unmarshal dockerfile image") + return fmt.Errorf("unmarshal dockerfile image: %w", err) } state2, img2, envVars := c.applyFromImage(pllb.FromRawState(*state), &img) @@ -583,7 +583,7 @@ func (c *Converter) Locally(ctx context.Context) error { workingDir, err := filepath.Abs(c.localWorkingDir) if err != nil { - return errors.Wrapf(err, "unable to get abs path of %s", c.localWorkingDir) + return fmt.Errorf("unable to get abs path of %s: %w", c.localWorkingDir, err) } c.varCollection.SetLocally(true) @@ -614,7 +614,7 @@ func (c *Converter) CopyArtifactLocal( artifact, err := domain.ParseArtifact(artifactName) if err != nil { - return errors.Wrapf(err, "parse artifact name %s", artifactName) + return fmt.Errorf("parse artifact name %s: %w", artifactName, err) } prefix, cmdID, err := c.newVertexMeta(ctx, false, false, false, nil) @@ -626,7 +626,7 @@ func (c *Converter) CopyArtifactLocal( ctx, artifact.Target.String(), platform, allowPrivileged, passArgs, buildArgs, false, copyCmd, cmdID, nil, ) if err != nil { - return errors.Wrapf(err, "apply build %s", artifact.Target.String()) + return fmt.Errorf("apply build %s: %w", artifact.Target.String(), err) } if artifact.Target.IsLocalInternal() { @@ -690,7 +690,7 @@ func (c *Converter) CopyArtifact( artifact, err := domain.ParseArtifact(artifactName) if err != nil { - return errors.Wrapf(err, "parse artifact name %s", artifactName) + return fmt.Errorf("parse artifact name %s: %w", artifactName, err) } prefix, cmdID, err := c.newVertexMeta(ctx, false, false, false, nil) @@ -702,7 +702,7 @@ func (c *Converter) CopyArtifact( ctx, artifact.Target.String(), platform, allowPrivileged, passArgs, buildArgs, false, copyCmd, cmdID, nil, ) if err != nil { - return errors.Wrapf(err, "apply build %s", artifact.Target.String()) + return fmt.Errorf("apply build %s: %w", artifact.Target.String(), err) } if artifact.Target.IsLocalInternal() { @@ -726,7 +726,7 @@ func (c *Converter) CopyArtifact( dest, )) if err != nil { - return errors.Wrapf(err, "copyOp CopyArtifact") + return fmt.Errorf("copyOp CopyArtifact: %w", err) } return nil @@ -782,7 +782,7 @@ func (c *Converter) CopyClassical( dest, )) if err != nil { - return errors.Wrapf(err, "copyOp CopyClassical") + return fmt.Errorf("copyOp CopyClassical: %w", err) } return nil @@ -856,7 +856,7 @@ func (c *Converter) RunExitCode(ctx context.Context, opts ConvertRunOpts) (int, exitCodeDir, err = os.MkdirTemp(os.TempDir(), "earthlyexitcode") if err != nil { - return 0, errors.Wrap(err, "create temp dir") + return 0, fmt.Errorf("create temp dir: %w", err) } exitCodeFile = filepath.Join(exitCodeDir, "/exit_code") @@ -899,7 +899,7 @@ func (c *Converter) RunExitCode(ctx context.Context, opts ConvertRunOpts) (int, if opts.Locally { codeDt, err = os.ReadFile(exitCodeFile) // #nosec G304 if err != nil { - return 0, errors.Wrap(err, "read exit code file") + return 0, fmt.Errorf("read exit code file: %w", err) } } else { var ref gwclient.Reference @@ -909,20 +909,20 @@ func (c *Converter) RunExitCode(ctx context.Context, opts ConvertRunOpts) (int, c.platr, c.opt.CacheImports.AsSlice(), ) if err != nil { - return 0, errors.Wrap(err, "run exit code state to ref") + return 0, fmt.Errorf("run exit code state to ref: %w", err) } codeDt, err = ref.ReadFile(ctx, gwclient.ReadRequest{ Filename: exitCodeFile, }) if err != nil { - return 0, errors.Wrap(err, "read exit code") + return 0, fmt.Errorf("read exit code: %w", err) } } exitCode, err := strconv.Atoi(string(bytes.TrimSpace(codeDt))) if err != nil { - return 0, errors.Wrap(err, "parse exit code as int") + return 0, fmt.Errorf("parse exit code as int: %w", err) } return exitCode, err @@ -980,7 +980,7 @@ func (c *Converter) runCommand( outputDir, err = os.MkdirTemp(os.TempDir(), "earthlyexproutput") if err != nil { - return "", errors.Wrap(err, "create temp dir") + return "", fmt.Errorf("create temp dir: %w", err) } outputFile = filepath.Join(outputDir, "/output") @@ -1026,7 +1026,7 @@ func (c *Converter) runCommand( if opts.Locally { outputDt, err = os.ReadFile(outputFile) // #nosec G304 if err != nil { - return "", errors.Wrap(err, "read output file") + return "", fmt.Errorf("read output file: %w", err) } } else { ref, err := llbutil.StateToRef( @@ -1034,12 +1034,12 @@ func (c *Converter) runCommand( c.platr, c.opt.CacheImports.AsSlice(), ) if err != nil { - return "", errors.Wrapf(err, "build arg state to ref") + return "", fmt.Errorf("build arg state to ref: %w", err) } outputDt, err = ref.ReadFile(ctx, gwclient.ReadRequest{Filename: outputFile}) if err != nil { - return "", errors.Wrapf(err, "non constant build arg read request") + return "", fmt.Errorf("non constant build arg read request: %w", err) } } // echo adds a trailing \n. @@ -1129,7 +1129,7 @@ func (c *Converter) SaveArtifact( artifact.String(), )) if err != nil { - return errors.Wrapf(err, "copyOp save artifact") + return fmt.Errorf("copyOp save artifact: %w", err) } if saveAsLocalTo == "" { @@ -1164,7 +1164,7 @@ func (c *Converter) SaveArtifact( saveAsLocalTo, )) if err != nil { - return errors.Wrapf(err, "copyOp save artifact as local") + return fmt.Errorf("copyOp save artifact as local: %w", err) } } else { prefix, _, err := c.newVertexMeta(ctx, false, false, false, nil) @@ -1186,7 +1186,7 @@ func (c *Converter) SaveArtifact( saveAsLocalTo, )) if err != nil { - return errors.Wrapf(err, "copyOp save artifact as local") + return fmt.Errorf("copyOp save artifact as local: %w", err) } } @@ -1243,12 +1243,12 @@ func (c *Converter) SaveArtifact( func (c *Converter) canSave(saveAsLocalTo string) (bool, error) { basepath, err := filepath.Abs(c.target.LocalPath) if err != nil { - return false, errors.Wrapf(err, "failed to get absolute path of %s", basepath) + return false, fmt.Errorf("failed to get absolute path of %s: %w", basepath, err) } basePathExists, err := fileutil.DirExists(basepath) if err != nil { - return false, errors.Wrapf(err, "failed to check if %s exists", basepath) + return false, fmt.Errorf("failed to check if %s exists: %w", basepath, err) } if !basePathExists { @@ -1266,7 +1266,7 @@ func (c *Converter) canSave(saveAsLocalTo string) (bool, error) { saveAsLocalToAdj, err = filepath.Abs(saveAsLocalToAdj) if err != nil { - return false, errors.Wrapf(err, "failed to get absolute path of %q", saveAsLocalTo) + return false, fmt.Errorf("failed to get absolute path of %q: %w", saveAsLocalTo, err) } if hasTrailingSlash { @@ -1329,7 +1329,7 @@ func (c *Converter) SaveArtifactFromLocal( c.ftrs.UseCopyLink, ) if err != nil { - return errors.Wrapf(err, "copyOp save artifact from local") + return fmt.Errorf("copyOp save artifact from local: %w", err) } err = c.forceExecution(ctx, c.mts.Final.ArtifactsState, c.platr) @@ -1401,7 +1401,7 @@ func (c *Converter) SaveImage( _, cmd, err := c.newLogbusCommand(ctx, "SAVE IMAGE "+strings.Join(imageNames, " ")) if err != nil { - return errors.Wrap(err, "failed to create command") + return fmt.Errorf("failed to create command: %w", err) } defer func() { @@ -1517,7 +1517,7 @@ func (c *Converter) Build( cmdID, cmd, err := c.newLogbusCommand(ctx, "BUILD "+fullTargetName) if err != nil { - return errors.Wrap(err, "failed to create command") + return fmt.Errorf("failed to create command: %w", err) } _, err = c.buildTarget( @@ -1555,13 +1555,13 @@ func (c *Converter) BuildAsync( rel, err := sem.Acquire(ctx, 1) if err != nil { - return errors.Wrapf(err, "acquiring parallelism semaphore for %s", fullTargetName) + return fmt.Errorf("acquiring parallelism semaphore for %s: %w", fullTargetName, err) } defer rel() mts, err := Earthfile2LLB(ctx, target, opt, false) if err != nil { - return errors.Wrapf(err, "async earthfile2llb for %s", fullTargetName) + return fmt.Errorf("async earthfile2llb for %s: %w", fullTargetName, err) } if apf != nil { @@ -1571,7 +1571,7 @@ func (c *Converter) BuildAsync( // synchronization (needs to be run after target has executed). err := c.forceExecution(ctx, mts.Final.MainState, mts.Final.PlatformResolver) if err != nil { - return errors.Wrapf(err, "async force execution for %s", fullTargetName) + return fmt.Errorf("async force execution for %s: %w", fullTargetName, err) } } @@ -1896,7 +1896,7 @@ func (c *Converter) GitClone(ctx context.Context, gitURL, sshCommand, branch, de branch, gitURLScrubbed, dest, )) if err != nil { - return errors.Wrapf(err, "copyOp git clone") + return fmt.Errorf("copyOp git clone: %w", err) } return nil @@ -2023,7 +2023,7 @@ func (c *Converter) Cache(_ context.Context, mountTarget string, opts cmdopts.Ca case "locked", "": shareMode = llb.CacheMountLocked default: - return errors.Errorf("invalid cache sharing mode %q", opts.Sharing) + return fmt.Errorf("invalid cache sharing mode %q", opts.Sharing) } if _, exists := c.persistentCacheDirs[mountTarget]; exists { @@ -2039,7 +2039,7 @@ func (c *Converter) Cache(_ context.Context, mountTarget string, opts cmdopts.Ca if opts.Mode != "" { mountMode, err = ParseMode(opts.Mode) if err != nil { - return errors.Errorf("failed to parse mount mode %s", opts.Mode) + return fmt.Errorf("failed to parse mount mode %s", opts.Mode) } } @@ -2047,7 +2047,7 @@ func (c *Converter) Cache(_ context.Context, mountTarget string, opts cmdopts.Ca if c.ftrs.CachePersistOption { persisted = opts.Persist } else if opts.Persist { - return errors.Errorf("the --persist flag is only available when VERSION --cache-persist-option is enabled") + return errors.New("the --persist flag is only available when VERSION --cache-persist-option is enabled") } c.persistentCacheDirs[mountTarget] = states.CacheMount{ @@ -2239,7 +2239,7 @@ func (c *Converter) FinalizeStates(ctx context.Context) (*states.MultiTarget, er c.opt.ErrorGroup.Go(func() error { rel, err := c.opt.Parallelism.Acquire(ctx, 1) if err != nil { - return errors.Wrapf(err, "acquiring parallelism semaphore for %s", c.mts.FinalTarget().String()) + return fmt.Errorf("acquiring parallelism semaphore for %s: %w", c.mts.FinalTarget().String(), err) } defer rel() @@ -2247,7 +2247,7 @@ func (c *Converter) FinalizeStates(ctx context.Context) (*states.MultiTarget, er err = c.forceExecution(ctx, c.mts.Final.MainState, c.mts.Final.PlatformResolver) if err != nil { c.RecordTargetFailure(ctx, err) - return errors.Wrapf(err, "async force execution for %s", c.mts.FinalTarget().String()) + return fmt.Errorf("async force execution for %s: %w", c.mts.FinalTarget().String(), err) } if c.opt.OnExecutionSuccess != nil { @@ -2268,7 +2268,7 @@ func (c *Converter) RecordTargetFailure(_ context.Context, err error) { var st logstream.RunStatus switch { - case errors.Is(err, context.Canceled) || status.Code(errors.Cause(err)) == codes.Canceled: + case errors.Is(err, context.Canceled) || status.Code(err) == codes.Canceled: st = logstream.RunStatus_RUN_STATUS_CANCELED default: st = logstream.RunStatus_RUN_STATUS_FAILURE @@ -2304,7 +2304,7 @@ func (c *Converter) absolutizeTarget( ) (domain.Target, domain.Target, bool, error) { relTarget, err := domain.ParseTarget(fullTargetName) if err != nil { - return domain.Target{}, domain.Target{}, false, errors.Wrapf(err, "earth target parse %s", fullTargetName) + return domain.Target{}, domain.Target{}, false, fmt.Errorf("earth target parse %s: %w", fullTargetName, err) } derefedTarget, allowPrivilegedImport, isImport, err := c.varCollection.Imports().Deref(relTarget) @@ -2318,12 +2318,12 @@ func (c *Converter) absolutizeTarget( targetRef, err := c.joinRefs(derefedTarget) if err != nil { - return domain.Target{}, domain.Target{}, false, errors.Wrap(err, "join targets") + return domain.Target{}, domain.Target{}, false, fmt.Errorf("join targets: %w", err) } target, ok := targetRef.(domain.Target) if !ok { - return domain.Target{}, domain.Target{}, false, errors.Errorf("want domain.Target, got %T", targetRef) + return domain.Target{}, domain.Target{}, false, fmt.Errorf("want domain.Target, got %T", targetRef) } return target, relTarget, allowPrivileged, nil @@ -2368,7 +2368,7 @@ func (c *Converter) checkAutoSkip( OverridingVars: overriding, }) if err != nil { - return false, nil, errors.Wrapf(err, "auto-skip is unable to calculate hash for %s", target) + return false, nil, fmt.Errorf("auto-skip is unable to calculate hash for %s: %w", target, err) } exists, err := c.opt.BuildkitSkipper.Exists(ctx, targetHash) @@ -2403,7 +2403,7 @@ func (c *Converter) prepOverridingVars( overriding, err := variables.ParseArgs(buildArgs, buildArgFunc, c.varCollection) if err != nil { - return nil, false, errors.Wrap(err, "parse build args") + return nil, false, fmt.Errorf("parse build args: %w", err) } // Don't allow transitive overriding variables to cross project boundaries (unless --pass-args is used). @@ -2495,7 +2495,7 @@ func (c *Converter) buildTarget( mts, err := Earthfile2LLB(ctx, target, opt, false) if err != nil { - return nil, errors.Wrapf(err, "earthfile2llb for %s", fullTargetName) + return nil, fmt.Errorf("earthfile2llb for %s: %w", fullTargetName, err) } c.directDeps = append(c.directDeps, mts.Final) @@ -2598,7 +2598,7 @@ func (c *Converter) internalRun(ctx context.Context, opts ConvertRunOpts) (pllb. case opts.Push: return pllb.State{}, errors.New("--push not supported with LOCALLY") case opts.Transient: - return pllb.State{}, errors.New("Transient run not supported with LOCALLY") + return pllb.State{}, errors.New("transient run not supported with LOCALLY") case opts.NoNetwork: return pllb.State{}, errors.New("--network=none is not supported with LOCALLY") } @@ -2628,7 +2628,7 @@ func (c *Converter) internalRun(ctx context.Context, opts ConvertRunOpts) (pllb. mountRunOpts, err := c.parseMounts(opts.Mounts) if err != nil { - return pllb.State{}, errors.Wrap(err, "parse mounts") + return pllb.State{}, fmt.Errorf("parse mounts: %w", err) } if opts.NoNetwork { @@ -2712,7 +2712,7 @@ func (c *Converter) internalRun(ctx context.Context, opts ConvertRunOpts) (pllb. if errors.As(err, &capErr) { if c.opt.InteractiveDebuggerEnabled || isInteractive { - return pllb.State{}, errors.Wrap(err, "interactive debugger requires a newer version of buildkit") + return pllb.State{}, fmt.Errorf("interactive debugger requires a newer version of buildkit: %w", err) } } else { c.opt.Console.Warnf("failed to check LLBCaps for CapExecMountSock: %v", err) // keep going @@ -2729,7 +2729,7 @@ func (c *Converter) internalRun(ctx context.Context, opts ConvertRunOpts) (pllb. localPathAbs, err = filepath.Abs(c.target.LocalPath) if err != nil { - return pllb.State{}, errors.Wrapf(err, "unable to determine absolute path of %s", c.target.LocalPath) + return pllb.State{}, fmt.Errorf("unable to determine absolute path of %s: %w", c.target.LocalPath, err) } saveFiles := []debuggercommon.SaveFilesSettings{} @@ -2778,12 +2778,12 @@ func (c *Converter) internalRun(ctx context.Context, opts ConvertRunOpts) (pllb. debuggerSettingsData, err = json.Marshal(&debuggerSettings) if err != nil { - return pllb.State{}, errors.Wrap(err, "debugger settings json marshal") + return pllb.State{}, fmt.Errorf("debugger settings json marshal: %w", err) } err = c.opt.InternalSecretStore.SetSecret(ctx, c.secretID(debuggerSettingsSecretsKey), debuggerSettingsData) if err != nil { - return pllb.State{}, errors.Wrap(err, "InternalSecretStore.SetSecret") + return pllb.State{}, fmt.Errorf("InternalSecretStore.SetSecret: %w", err) } secretOpts := []llb.SecretOption{ @@ -3029,7 +3029,7 @@ func (c *Converter) parseSecretFlag(secretKeyValue string) (secretID string, env return secretID, parts[0], nil } - err = errors.Errorf( + err = fmt.Errorf( "secret definition %s not supported. Format must be either =+secrets/ or ", secretKeyValue, ) @@ -3048,7 +3048,7 @@ func (c *Converter) forceExecution(ctx context.Context, state pllb.State, platr platr, c.opt.CacheImports.AsSlice(), ) if err != nil { - return errors.Wrap(err, "force execution state to ref") + return fmt.Errorf("force execution state to ref: %w", err) } if ref == nil { @@ -3058,7 +3058,7 @@ func (c *Converter) forceExecution(ctx context.Context, state pllb.State, platr // want to un-lazy the ref so that the commands have executed. _, err = ref.ReadDir(ctx, gwclient.ReadDirRequest{Path: "/"}) if err != nil { - return errors.Wrap(err, "unlazy force execution") + return fmt.Errorf("unlazy force execution: %w", err) } return nil @@ -3069,7 +3069,7 @@ func (c *Converter) readArtifact( ) ([]byte, error) { if mts.Final.ArtifactsState.Output() == nil { // ArtifactsState is scratch - no artifact has been copied. - return nil, errors.Errorf( + return nil, fmt.Errorf( "artifact %s not found; no SAVE ARTIFACT command was issued in %s", artifact.String(), artifact.Target.String(), ) } @@ -3079,14 +3079,14 @@ func (c *Converter) readArtifact( mts.Final.PlatformResolver, c.opt.CacheImports.AsSlice(), ) if err != nil { - return nil, errors.Wrap(err, "state to ref solve artifact") + return nil, fmt.Errorf("state to ref solve artifact: %w", err) } artDt, err := ref.ReadFile(ctx, gwclient.ReadRequest{ Filename: artifact.Artifact, }) if err != nil { - return nil, errors.Wrapf(err, "read artifact %s", artifact.String()) + return nil, fmt.Errorf("read artifact %s: %w", artifact.String(), err) } return artDt, nil @@ -3108,7 +3108,7 @@ func (c *Converter) internalFromClassical( sourceRef, err := reference.ParseNormalizedNamed(imageName) if err != nil { - return pllb.State{}, nil, nil, errors.Wrapf(err, "parse normalized named %s", imageName) + return pllb.State{}, nil, nil, fmt.Errorf("parse normalized named %s: %w", imageName, err) } baseImageName := reference.TagNameOnly(sourceRef).String() @@ -3126,25 +3126,25 @@ func (c *Converter) internalFromClassical( }, ) if err != nil { - return pllb.State{}, nil, nil, errors.Wrapf(err, "resolve image config for %s", imageName) + return pllb.State{}, nil, nil, fmt.Errorf("resolve image config for %s: %w", imageName, err) } sourceRef, err = reference.ParseNormalizedNamed(ref) if err != nil { - return pllb.State{}, nil, nil, errors.Wrapf(err, "parse normalized named %s", ref) + return pllb.State{}, nil, nil, fmt.Errorf("parse normalized named %s: %w", ref, err) } var img image.Image err = json.Unmarshal(dt, &img) if err != nil { - return pllb.State{}, nil, nil, errors.Wrapf(err, "unmarshal image config for %s", imageName) + return pllb.State{}, nil, nil, fmt.Errorf("unmarshal image config for %s: %w", imageName, err) } if dgst != "" { sourceRef, err = reference.WithDigest(sourceRef, dgst) if err != nil { - return pllb.State{}, nil, nil, errors.Wrapf(err, "reference add digest %v for %s", dgst, imageName) + return pllb.State{}, nil, nil, fmt.Errorf("reference add digest %v for %s: %w", dgst, imageName, err) } } @@ -3165,7 +3165,7 @@ func (c *Converter) checkOldPlatformIncompatibility(platform platutil.Platform) } if !c.platr.PlatformEquals(c.platr.Default(), platform) { - return errors.Errorf( + return fmt.Errorf( "platform contradiction: \"%s\" vs \"%s\"", platform.String(), c.platr.Default().String(), ) @@ -3408,7 +3408,7 @@ func (c *Converter) checkAllowed(command cmdType) error { } if c.mts.Final.RanInteractive && command != saveImageCmd && command != saveArtifactCmd { - return errors.New("If present, a single --interactive command must be the last command in a target") + return errors.New("if present, a single --interactive command must be the last command in a target") } if !c.mts.Final.RanFromLike { @@ -3503,7 +3503,7 @@ func (c *Converter) expandWildcardTargets(ctx context.Context, fullTargetName st childTarget, err := domain.ParseTarget(childTargetName) if err != nil { - return nil, errors.Wrapf(err, "failed to parse target %q", childTargetName) + return nil, fmt.Errorf("failed to parse target %q: %w", childTargetName, err) } data, _, _, err := c.ResolveReference(ctx, childTarget) @@ -3513,7 +3513,7 @@ func (c *Converter) expandWildcardTargets(ctx context.Context, fullTargetName st continue } - return nil, errors.Wrapf(err, "unable to resolve target %q", childTargetName) + return nil, fmt.Errorf("unable to resolve target %q: %w", childTargetName, err) } var found bool @@ -3533,7 +3533,7 @@ func (c *Converter) expandWildcardTargets(ctx context.Context, fullTargetName st } if len(targets) == 0 { - return nil, errors.Errorf("no matching targets found for pattern %q", parsedTarget.GetLocalPath()) + return nil, fmt.Errorf("no matching targets found for pattern %q", parsedTarget.GetLocalPath()) } return targets, nil diff --git a/earthfile2llb/earthfile2llb.go b/earthfile2llb/earthfile2llb.go index 413834672c..55e3154f98 100644 --- a/earthfile2llb/earthfile2llb.go +++ b/earthfile2llb/earthfile2llb.go @@ -3,6 +3,7 @@ package earthfile2llb import ( "context" + "fmt" "maps" "github.com/EarthBuild/earthbuild/buildcontext" @@ -25,7 +26,6 @@ import ( "github.com/moby/buildkit/client/llb" gwclient "github.com/moby/buildkit/frontend/gateway/client" "github.com/moby/buildkit/util/apicaps" - "github.com/pkg/errors" ) const commandName = "WITH DOCKER RUN " @@ -237,7 +237,7 @@ func Earthfile2LLB( // Resolve build context. bc, err := opt.Resolver.Resolve(ctx, opt.GwClient, opt.PlatformResolver, target) if err != nil { - return nil, errors.Wrapf(err, "resolve build context for target %s", target.String()) + return nil, fmt.Errorf("resolve build context for target %s: %w", target.String(), err) } if opt.Visited == nil { @@ -262,7 +262,7 @@ func Earthfile2LLB( targetWithMetadata, ok := bc.Ref.(domain.Target) if !ok { - return nil, errors.Errorf("want domain.Target, got %T", bc.Ref) + return nil, fmt.Errorf("want domain.Target, got %T", bc.Ref) } sts, found, err := opt.Visited. @@ -291,7 +291,7 @@ func Earthfile2LLB( //nolint:nestif // TODO(jhorsts): simplify if found { if opt.TargetInputHashStackSet[tiHash] { - return nil, errors.Errorf("infinite cycle detected for target %s", target.String()) + return nil, fmt.Errorf("infinite cycle detected for target %s", target.String()) } // Wait for the existing sts to complete first. @@ -315,7 +315,7 @@ func Earthfile2LLB( if opt.DoSaves || opt.DoPushes { err = sts.Wait(ctx) if err != nil { - return nil, errors.Wrapf(err, "wait failed on target %s", target.String()) + return nil, fmt.Errorf("wait failed on target %s: %w", target.String(), err) } } diff --git a/earthfile2llb/earthfile_info.go b/earthfile2llb/earthfile_info.go index 2e106b0556..ef28fea0d1 100644 --- a/earthfile2llb/earthfile_info.go +++ b/earthfile2llb/earthfile_info.go @@ -11,7 +11,6 @@ import ( "github.com/EarthBuild/earthbuild/util/flagutil" "github.com/EarthBuild/earthbuild/util/platutil" gwclient "github.com/moby/buildkit/frontend/gateway/client" - "github.com/pkg/errors" ) // These are functions that are used for getting information about an Earthfile, @@ -26,7 +25,7 @@ func GetTargets( bc, err := resolver.Resolve(ctx, gwClient, platr, target) if err != nil { - return nil, errors.Wrapf(err, "resolve build context for target %s", target.String()) + return nil, fmt.Errorf("resolve build context for target %s: %w", target.String(), err) } targets := make([]string, 0, len(bc.Earthfile.Targets)) @@ -45,7 +44,7 @@ func GetTargetArgs( bc, err := resolver.Resolve(ctx, gwClient, platr, target) if err != nil { - return nil, errors.Wrapf(err, "resolve build context for target %s", target.String()) + return nil, fmt.Errorf("resolve build context for target %s: %w", target.String(), err) } var t *earthfile.Target @@ -71,7 +70,7 @@ func GetTargetArgs( _, argName, _, err := flagutil.ParseArgArgs(*stmt.Command, isBase, explicitGlobal) if err != nil { - return nil, errors.Wrapf(err, "failed to parse ARG arguments %v", stmt.Command.Args) + return nil, fmt.Errorf("failed to parse ARG arguments %v: %w", stmt.Command.Args, err) } args = append(args, argName) @@ -87,12 +86,12 @@ func ArgName( cmd earthfile.Command, isBase, explicitGlobal bool, ) (_ string, _ *string, isRequired, isGlobal bool, _ error) { if cmd.Name != "ARG" { - return "", nil, false, false, errors.Errorf("ArgName was called with non-arg command type '%v'", cmd.Name) + return "", nil, false, false, fmt.Errorf("ArgName was called with non-arg command type '%v'", cmd.Name) } opts, argName, dflt, err := flagutil.ParseArgArgs(cmd, isBase, explicitGlobal) if err != nil { - return "", nil, false, false, errors.Wrapf(err, "could not parse opts for ARG [%v]", cmd) + return "", nil, false, false, fmt.Errorf("could not parse opts for ARG [%v]: %w", cmd, err) } return argName, dflt, opts.Required, opts.Global, nil @@ -103,7 +102,7 @@ func ArgName( func ArtifactName(cmd earthfile.Command) (string, *string, error) { from, to, asLocal, ok := parseSaveArtifactArgs(cmd.Args) if !ok { - return "", nil, errors.Errorf("could not parse opts for SAVE TARGET [%v]", cmd) + return "", nil, fmt.Errorf("could not parse opts for SAVE TARGET [%v]", cmd) } if to == "./" { @@ -123,7 +122,7 @@ func ImageNames(cmd earthfile.Command) ([]string, error) { args, err := flagutil.ParseArgs("SAVE IMAGE", &opts, flagutil.GetArgsCopy(cmd)) if err != nil { - return nil, errors.Wrapf(err, "invalid SAVE IMAGE arguments %v", cmd.Args) + return nil, fmt.Errorf("invalid SAVE IMAGE arguments %v: %w", cmd.Args, err) } return args, nil diff --git a/earthfile2llb/interpreter.go b/earthfile2llb/interpreter.go index b6eec2ecd4..023cec10c1 100644 --- a/earthfile2llb/interpreter.go +++ b/earthfile2llb/interpreter.go @@ -2,6 +2,7 @@ package earthfile2llb import ( "context" + "errors" "fmt" "net" "os" @@ -27,7 +28,6 @@ import ( "github.com/docker/go-connections/nat" "github.com/google/uuid" "github.com/jessevdk/go-flags" - "github.com/pkg/errors" ) const maxCommandRenameWarnings = 3 @@ -707,7 +707,7 @@ func (i *Interpreter) getAllowPrivilegedTarget(targetName string, allowPrivilege depTarget, err := domain.ParseTarget(targetName) if err != nil { - return false, errors.Wrapf(err, "parse target name %s", targetName) + return false, fmt.Errorf("parse target name %s: %w", targetName, err) } return i.getAllowPrivileged(depTarget, allowPrivileged) @@ -728,7 +728,7 @@ func (i *Interpreter) getAllowPrivileged(depTarget domain.Target, allowPrivilege func (i *Interpreter) getAllowPrivilegedArtifact(artifactName string, allowPrivileged bool) (bool, error) { artifact, err := domain.ParseArtifact(artifactName) if err != nil { - return false, errors.Wrapf(err, "parse artifact name %s", artifactName) + return false, fmt.Errorf("parse artifact name %s: %w", artifactName, err) } return i.getAllowPrivileged(artifact.Target, allowPrivileged) @@ -1862,7 +1862,7 @@ func (i *Interpreter) handleLet(ctx context.Context, cmd earthfile.Command) erro args, err := flagutil.ParseArgsCleaned("LET", &opts, argsCpy) if err != nil { - return errors.Wrap(err, "failed to parse LET args") + return fmt.Errorf("failed to parse LET args: %w", err) } if len(args) != 3 || args[1] != "=" { @@ -1892,7 +1892,7 @@ func parseSetArgs(cmd earthfile.Command) (name, value string, _ error) { args, err := flagutil.ParseArgsCleaned("SET", &opts, argsCpy) if err != nil { - return "", "", errors.Wrap(err, "failed to parse SET args") + return "", "", fmt.Errorf("failed to parse SET args: %w", err) } if len(args) != 3 { @@ -1913,7 +1913,7 @@ func (i *Interpreter) handleSet(ctx context.Context, cmd earthfile.Command) erro key, value, err := parseSetArgs(cmd) if err != nil { - return errors.Wrapf(err, "failed to parse SET arguments") + return fmt.Errorf("failed to parse SET arguments: %w", err) } newVal, err := i.expandArgs(ctx, value, true, false) diff --git a/earthfile2llb/interpretererror.go b/earthfile2llb/interpretererror.go index 86d14cd8a8..c88c02bd54 100644 --- a/earthfile2llb/interpretererror.go +++ b/earthfile2llb/interpretererror.go @@ -1,13 +1,13 @@ package earthfile2llb import ( + "errors" "fmt" "regexp" "strconv" "github.com/EarthBuild/earthbuild/internal/earthfile" "github.com/EarthBuild/earthbuild/util/stringutil" - "github.com/pkg/errors" ) var _ error = &InterpreterError{} @@ -53,7 +53,7 @@ func WrapError( func (ie InterpreterError) Error() string { var err error if ie.cause != nil { - err = errors.Wrap(ie.cause, ie.text) + err = fmt.Errorf("%s: %w", ie.text, ie.cause) } else { err = errors.New(ie.text) } @@ -65,7 +65,8 @@ func (ie InterpreterError) Error() string { ret := fmt.Sprintf( "%s:%d:%d %s", ie.SourceLocation.File, ie.SourceLocation.StartLine, ie.SourceLocation.StartColumn, - err.Error()) + err.Error(), + ) if ie.stack != "" { ret = fmt.Sprintf("%s\nin\t\t%s", ret, ie.stack) } @@ -73,11 +74,6 @@ func (ie InterpreterError) Error() string { return ret } -// Cause returns the cause of the error (if any). -func (ie InterpreterError) Cause() error { - return errors.Cause(ie.cause) -} - // Unwrap unwraps the error. func (ie InterpreterError) Unwrap() error { return ie.cause diff --git a/earthfile2llb/interpretererror_test.go b/earthfile2llb/interpretererror_test.go index 4ed55fa4a8..5ec044db60 100644 --- a/earthfile2llb/interpretererror_test.go +++ b/earthfile2llb/interpretererror_test.go @@ -1,10 +1,10 @@ package earthfile2llb import ( + "errors" "testing" "github.com/EarthBuild/earthbuild/internal/earthfile" - "github.com/pkg/errors" "github.com/stretchr/testify/assert" ) diff --git a/earthfile2llb/runmount.go b/earthfile2llb/runmount.go index a0c8b099a8..3d4f4e824f 100644 --- a/earthfile2llb/runmount.go +++ b/earthfile2llb/runmount.go @@ -3,6 +3,8 @@ package earthfile2llb import ( "crypto/sha256" "encoding/hex" + "errors" + "fmt" "math" "os" "path" @@ -12,7 +14,6 @@ import ( "github.com/EarthBuild/earthbuild/domain" "github.com/EarthBuild/earthbuild/util/llbutil/pllb" "github.com/moby/buildkit/client/llb" - "github.com/pkg/errors" ) func (c *Converter) parseMounts(mounts []string) ([]llb.RunOption, error) { @@ -21,7 +22,7 @@ func (c *Converter) parseMounts(mounts []string) ([]llb.RunOption, error) { for _, mount := range mounts { mountRunOpts, err := c.parseMount(mount) if err != nil { - return nil, errors.Wrap(err, "parse mount") + return nil, fmt.Errorf("parse mount: %w", err) } runOpts = append(runOpts, mountRunOpts...) @@ -47,42 +48,42 @@ func (c *Converter) parseMount(mount string) ([]llb.RunOption, error) { for kvPair := range kvPairs { kvSplit := strings.SplitN(kvPair, "=", 2) if len(kvSplit) == 0 { - return nil, errors.Errorf("invalid mount arg %s", kvPair) + return nil, fmt.Errorf("invalid mount arg %s", kvPair) } switch kvSplit[0] { case "id": if len(kvSplit) != 2 { - return nil, errors.Errorf("invalid mount arg %s", kvPair) + return nil, fmt.Errorf("invalid mount arg %s", kvPair) } mountID = kvSplit[1] case "type": if len(kvSplit) != 2 { - return nil, errors.Errorf("invalid mount arg %s", kvPair) + return nil, fmt.Errorf("invalid mount arg %s", kvPair) } mountType = kvSplit[1] case "source": if len(kvSplit) != 2 { - return nil, errors.Errorf("invalid mount arg %s", kvPair) + return nil, fmt.Errorf("invalid mount arg %s", kvPair) } mountSource = kvSplit[1] case "target": if len(kvSplit) != 2 { - return nil, errors.Errorf("invalid mount arg %s", kvPair) + return nil, fmt.Errorf("invalid mount arg %s", kvPair) } mountTarget = kvSplit[1] case "ro", "readonly": if len(kvSplit) != 1 { - return nil, errors.Errorf("invalid mount arg %s", kvPair) + return nil, fmt.Errorf("invalid mount arg %s", kvPair) } mountOpts = append(mountOpts, llb.Readonly) case "uid": - return nil, errors.Errorf("not yet supported %s", kvPair) + return nil, fmt.Errorf("not yet supported %s", kvPair) // if len(kvSplit) != 2 { // return nil, errors.Errorf("invalid mount arg %s", kvPair) // } @@ -92,7 +93,7 @@ func (c *Converter) parseMount(mount string) ([]llb.RunOption, error) { // return nil, errors.Errorf("invalid mount arg %s", kvPair) // } case "gid": - return nil, errors.Errorf("not yet supported %s", kvPair) + return nil, fmt.Errorf("not yet supported %s", kvPair) // if len(kvSplit) != 2 { // return nil, errors.Errorf("invalid mount arg %s", kvPair) // } @@ -103,18 +104,18 @@ func (c *Converter) parseMount(mount string) ([]llb.RunOption, error) { // } case "mode", "chmod": if len(kvSplit) != 2 { - return nil, errors.Errorf("invalid mount arg %s", kvPair) + return nil, fmt.Errorf("invalid mount arg %s", kvPair) } var err error mountMode, err = ParseMode(kvSplit[1]) if err != nil { - return nil, errors.Errorf("failed to parse mount %s %s", kvSplit[0], kvSplit[1]) + return nil, fmt.Errorf("failed to parse mount %s %s", kvSplit[0], kvSplit[1]) } case "sharing": if len(kvSplit) != 2 { - return nil, errors.Errorf("invalid mount arg %s", kvPair) + return nil, fmt.Errorf("invalid mount arg %s", kvPair) } switch kvSplit[1] { @@ -125,31 +126,31 @@ func (c *Converter) parseMount(mount string) ([]llb.RunOption, error) { case "locked": sharingMode = llb.CacheMountLocked default: - return nil, errors.Errorf("invalid mount arg %s", kvPair) + return nil, fmt.Errorf("invalid mount arg %s", kvPair) } case "from": - return nil, errors.Errorf("not yet supported %s", kvPair) + return nil, fmt.Errorf("not yet supported %s", kvPair) default: - return nil, errors.Errorf("invalid mount arg %s", kvPair) + return nil, fmt.Errorf("invalid mount arg %s", kvPair) } } if mountType == "" { - return nil, errors.Errorf("mount type not specified") + return nil, errors.New("mount type not specified") } switch mountType { case "bind-experimental": if mountSource == "" { - return nil, errors.Errorf("mount source not specified") + return nil, errors.New("mount source not specified") } if mountTarget == "" { - return nil, errors.Errorf("mount target not specified") + return nil, errors.New("mount target not specified") } if mountMode != 0 { - return nil, errors.Errorf("mode is not supported for type=bind-experimental") + return nil, errors.New("mode is not supported for type=bind-experimental") } mountOpts = append(mountOpts, llb.HostBind(), llb.SourcePath(mountSource)) @@ -157,7 +158,7 @@ func (c *Converter) parseMount(mount string) ([]llb.RunOption, error) { return []llb.RunOption{llb.AddMount(mountTarget, llb.Scratch(), mountOpts...)}, nil case "cache": if mountTarget == "" { - return nil, errors.Errorf("mount target not specified") + return nil, errors.New("mount target not specified") } if mountMode == 0 { @@ -180,11 +181,11 @@ func (c *Converter) parseMount(mount string) ([]llb.RunOption, error) { return []llb.RunOption{pllb.AddMount(mountTarget, state, mountOpts...)}, nil case "tmpfs": if mountTarget == "" { - return nil, errors.Errorf("mount target not specified") + return nil, errors.New("mount target not specified") } if mountMode != 0 { - return nil, errors.Errorf("mode is not supported for type=tmpfs") + return nil, errors.New("mode is not supported for type=tmpfs") } state = c.platr.Scratch() @@ -204,13 +205,13 @@ func (c *Converter) parseMount(mount string) ([]llb.RunOption, error) { } if mountMode != 0 { - return nil, errors.Errorf("mode is not supported for type=ssh-experimental") + return nil, errors.New("mode is not supported for type=ssh-experimental") } return []llb.RunOption{llb.AddSSHSocket(sshOpts...)}, nil case "secret": if mountTarget == "" { - return nil, errors.Errorf("mount target not specified") + return nil, errors.New("mount target not specified") } if mountMode == 0 { @@ -225,7 +226,7 @@ func (c *Converter) parseMount(mount string) ([]llb.RunOption, error) { if mountMode <= math.MaxInt32 { mode = int(mountMode) } else { - return nil, errors.Errorf("mode is too large: 0%o", mountMode) + return nil, fmt.Errorf("mode is too large: 0%o", mountMode) } secretID := mountID @@ -241,7 +242,7 @@ func (c *Converter) parseMount(mount string) ([]llb.RunOption, error) { return []llb.RunOption{llb.AddSecret(mountTarget, secretOpts...)}, nil default: - return nil, errors.Errorf("invalid mount type %s", mountType) + return nil, fmt.Errorf("invalid mount type %s", mountType) } } diff --git a/earthfile2llb/wait_block.go b/earthfile2llb/wait_block.go index f4e4c5e5e8..3cf26db313 100644 --- a/earthfile2llb/wait_block.go +++ b/earthfile2llb/wait_block.go @@ -16,9 +16,7 @@ import ( "github.com/EarthBuild/earthbuild/util/syncutil/semutil" "github.com/EarthBuild/earthbuild/util/syncutil/serrgroup" "github.com/EarthBuild/earthbuild/util/waitutil" - gwclient "github.com/moby/buildkit/frontend/gateway/client" - "github.com/pkg/errors" ) type waitBlock struct { @@ -178,9 +176,10 @@ func (wb *waitBlock) saveImages(ctx context.Context) error { ref, err := llbutil.StateToRef( ctx, item.c.opt.GwClient, item.si.State, item.c.opt.NoCache, - item.c.platr, item.c.opt.CacheImports.AsSlice()) + item.c.platr, item.c.opt.CacheImports.AsSlice(), + ) if err != nil { - return errors.Wrapf(err, "failed to solve image required for %s", item.si.DockerTag) + return fmt.Errorf("failed to solve image required for %s: %w", item.si.DockerTag, err) } var ( @@ -199,25 +198,28 @@ func (wb *waitBlock) saveImages(ctx context.Context) error { if item.si.CheckDuplicate && item.si.DockerTag != "" { if _, found := platformImgNames[platformImgName]; found { - return errors.Errorf( + return fmt.Errorf( "image %s is defined multiple times for the same platform (%s)", - item.si.DockerTag, item.si.Platform.String()) + item.si.DockerTag, item.si.Platform.String(), + ) } platformImgNames[platformImgName] = true } } else if item.si.CheckDuplicate && item.si.DockerTag != "" { if _, found := singPlatImgNames[item.si.DockerTag]; found { - return errors.Errorf( + return fmt.Errorf( "image %s is defined multiple times for the same default platform", - item.si.DockerTag) + item.si.DockerTag, + ) } singPlatImgNames[item.si.DockerTag] = true } refPrefix, err := gwCrafter.AddPushImageEntry( - ref, refID, item.si.DockerTag, item.doPush, item.si.InsecurePush, item.si.Image, platformBytes) + ref, refID, item.si.DockerTag, item.doPush, item.si.InsecurePush, item.si.Image, platformBytes, + ) if err != nil { return err } @@ -282,7 +284,7 @@ func (wb *waitBlock) saveImages(ctx context.Context) error { Metadata: metadata, }) if err != nil { - return errors.Wrap(err, "failed to SAVE IMAGE") + return fmt.Errorf("failed to SAVE IMAGE: %w", err) } return nil @@ -316,7 +318,7 @@ func (wb *waitBlock) waitStates(ctx context.Context) error { errGroup.Go(func() error { rel, err := sem.Acquire(ctx, 1) if err != nil { - return errors.Wrapf(err, "acquiring parallelism semaphore during waitStates for %s", item.c.target.String()) + return fmt.Errorf("acquiring parallelism semaphore during waitStates for %s: %w", item.c.target.String(), err) } defer rel() @@ -371,7 +373,8 @@ func (wb *waitBlock) saveArtifactLocal(ctx context.Context) error { } dirID, err := gwCrafter.AddSaveArtifactLocal( - ref, refID, artifact.String(), saveLocalItem.saveLocal.ArtifactPath, saveLocalItem.saveLocal.DestPath) + ref, refID, artifact.String(), saveLocalItem.saveLocal.ArtifactPath, saveLocalItem.saveLocal.DestPath, + ) if err != nil { return err } @@ -411,7 +414,8 @@ func (wb *waitBlock) saveArtifactLocal(ctx context.Context) error { for _, entry := range artifacts { err = saveartifactlocally.SaveArtifactLocally( - exportCoordinator, console, entry.artifact, entry.artifactDir, entry.destPath, entry.salt, entry.ifExists) + exportCoordinator, console, entry.artifact, entry.artifactDir, entry.destPath, entry.salt, entry.ifExists, + ) if err != nil { return err } diff --git a/earthfile2llb/with_docker_run_base.go b/earthfile2llb/with_docker_run_base.go index de45451f76..f1edafe05f 100644 --- a/earthfile2llb/with_docker_run_base.go +++ b/earthfile2llb/with_docker_run_base.go @@ -13,7 +13,6 @@ import ( "github.com/containerd/platforms" "github.com/moby/buildkit/client/llb" gwclient "github.com/moby/buildkit/frontend/gateway/client" - "github.com/pkg/errors" "gopkg.in/yaml.v3" ) @@ -116,7 +115,7 @@ func (w *withDockerRunBase) getComposePulls(ctx context.Context, opt WithDockerO err = yaml.Unmarshal(composeConfigDt, &config) if err != nil { - return nil, errors.Wrapf(err, "parse compose config for %v", opt.ComposeFiles) + return nil, fmt.Errorf("parse compose config for %v: %w", opt.ComposeFiles, err) } // Collect relevant images from the compose config. @@ -138,8 +137,7 @@ func (w *withDockerRunBase) getComposePulls(ctx context.Context, opt WithDockerO if serviceInfo.Platform != "" { p, err := platforms.Parse(serviceInfo.Platform) if err != nil { - return nil, errors.Wrapf( - err, "parse platform for image %s: %s", serviceInfo.Image, serviceInfo.Platform) + return nil, fmt.Errorf("parse platform for image %s: %s: %w", serviceInfo.Image, serviceInfo.Platform, err) } platform = platutil.FromLLBPlatform(p) @@ -191,16 +189,17 @@ func (w *withDockerRunBase) getComposeConfig(ctx context.Context, opt WithDocker ref, err := llbutil.StateToRef( ctx, w.c.opt.GwClient, state, w.c.opt.NoCache, - w.c.platr, w.c.opt.CacheImports.AsSlice()) + w.c.platr, w.c.opt.CacheImports.AsSlice(), + ) if err != nil { - return nil, errors.Wrap(err, "state to ref compose config") + return nil, fmt.Errorf("state to ref compose config: %w", err) } composeConfigDt, err := ref.ReadFile(ctx, gwclient.ReadRequest{ Filename: "/tmp/earthbuild/" + composeConfigFile, }) if err != nil { - return nil, errors.Wrap(err, "read compose config file") + return nil, fmt.Errorf("read compose config file: %w", err) } return composeConfigDt, nil diff --git a/earthfile2llb/with_docker_run_local_reg.go b/earthfile2llb/with_docker_run_local_reg.go index ea53edd6ae..576eeef88e 100644 --- a/earthfile2llb/with_docker_run_local_reg.go +++ b/earthfile2llb/with_docker_run_local_reg.go @@ -11,7 +11,6 @@ import ( "github.com/EarthBuild/earthbuild/states" "github.com/EarthBuild/earthbuild/util/containerutil" "github.com/EarthBuild/earthbuild/util/syncutil/semutil" - "github.com/pkg/errors" ) type withDockerRunLocalReg struct { @@ -42,7 +41,7 @@ func (w *withDockerRunLocalReg) Run(ctx context.Context, args []string, opt With _, cmd, err := w.c.newLogbusCommand(ctx, commandName) if err != nil { - return errors.Wrap(err, "failed to create command") + return fmt.Errorf("failed to create command: %w", err) } defer func() { @@ -61,7 +60,7 @@ func (w *withDockerRunLocalReg) Run(ctx context.Context, args []string, opt With imageDefChan, err = w.load(ctx, loadOpt) if err != nil { - return errors.Wrap(err, "load") + return fmt.Errorf("load: %w", err) } imageDefChans = append(imageDefChans, imageDefChan) @@ -78,7 +77,7 @@ func (w *withDockerRunLocalReg) Run(ctx context.Context, args []string, opt With res, err := w.c.opt.MultiImageSolver.SolveImages(ctx, imagesToBuild) if err != nil { - return errors.Wrap(err, "solving images") + return fmt.Errorf("solving images: %w", err) } defer res.ReleaseFunc() @@ -113,7 +112,7 @@ func (w *withDockerRunLocalReg) Run(ctx context.Context, args []string, opt With TargetRef: result.FinalImageName, }) if err != nil { - return errors.Wrapf(err, "tag image %q", result.FinalImageName) + return fmt.Errorf("tag image %q: %w", result.FinalImageName, err) } } @@ -148,7 +147,7 @@ func (w *withDockerRunLocalReg) load(ctx context.Context, opt DockerLoadOpt) (ch depTarget, err := domain.ParseTarget(opt.Target) if err != nil { - return nil, errors.Wrapf(err, "parse target %s", opt.Target) + return nil, fmt.Errorf("parse target %s: %w", opt.Target, err) } afterFun := func(_ context.Context, mts *states.MultiTarget) error { @@ -159,7 +158,7 @@ func (w *withDockerRunLocalReg) load(ctx context.Context, opt DockerLoadOpt) (ch } if len(mts.Final.SaveImages) > 1 { - return errors.Wrap(errNoImageTag, "multiple tags mentioned in SAVE IMAGE") + return fmt.Errorf("multiple tags mentioned in SAVE IMAGE: %w", errNoImageTag) } opt.ImageName = mts.Final.SaveImages[0].DockerTag @@ -176,13 +175,15 @@ func (w *withDockerRunLocalReg) load(ctx context.Context, opt DockerLoadOpt) (ch if w.enableParallel { err = w.c.BuildAsync( - ctx, depTarget.String(), opt.Platform, opt.AllowPrivileged, opt.PassArgs, opt.BuildArgs, loadCmd, afterFun, w.sem) + ctx, depTarget.String(), opt.Platform, opt.AllowPrivileged, opt.PassArgs, opt.BuildArgs, loadCmd, afterFun, w.sem, + ) if err != nil { return nil, err } } else { mts, err := w.c.buildTarget( - ctx, depTarget.String(), opt.Platform, opt.AllowPrivileged, opt.PassArgs, opt.BuildArgs, false, loadCmd, "", nil) + ctx, depTarget.String(), opt.Platform, opt.AllowPrivileged, opt.PassArgs, opt.BuildArgs, false, loadCmd, "", nil, + ) if err != nil { return nil, err } diff --git a/earthfile2llb/with_docker_run_local_tar.go b/earthfile2llb/with_docker_run_local_tar.go index e3a5dab782..4583775164 100644 --- a/earthfile2llb/with_docker_run_local_tar.go +++ b/earthfile2llb/with_docker_run_local_tar.go @@ -2,6 +2,8 @@ package earthfile2llb import ( "context" + "errors" + "fmt" "os" "path" "sort" @@ -12,7 +14,6 @@ import ( "github.com/EarthBuild/earthbuild/util/syncutil/semutil" "github.com/moby/buildkit/client/llb" "github.com/moby/buildkit/session/localhost" - "github.com/pkg/errors" ) type withDockerRunLocalTar struct { @@ -50,7 +51,7 @@ func (w *withDockerRunLocalTar) Run(ctx context.Context, args []string, opt With cmdID, cmd, err := w.c.newLogbusCommand(ctx, commandName) if err != nil { - return errors.Wrap(err, "failed to create command") + return fmt.Errorf("failed to create command: %w", err) } defer func() { @@ -64,7 +65,7 @@ func (w *withDockerRunLocalTar) Run(ctx context.Context, args []string, opt With lp, err = w.load(ctx, cmdID, loadOpt) if err != nil { - return errors.Wrap(err, "load") + return fmt.Errorf("load: %w", err) } loadPromises = append(loadPromises, lp) @@ -121,7 +122,7 @@ func (w *withDockerRunLocalTar) load(ctx context.Context, cmdID string, opt Dock depTarget, err := domain.ParseTarget(opt.Target) if err != nil { - return nil, errors.Wrapf(err, "parse target %s", opt.Target) + return nil, fmt.Errorf("parse target %s: %w", opt.Target, err) } afterFun := func(ctx context.Context, mts *states.MultiTarget) error { @@ -129,13 +130,15 @@ func (w *withDockerRunLocalTar) load(ctx context.Context, cmdID string, opt Dock // Infer image name from the SAVE IMAGE statement. if len(mts.Final.SaveImages) == 0 || mts.Final.SaveImages[0].DockerTag == "" { return errors.New( - "no docker image tag specified in load and it cannot be inferred from the SAVE IMAGE statement") + "no docker image tag specified in load and it cannot be inferred from the SAVE IMAGE statement", + ) } if len(mts.Final.SaveImages) > 1 { return errors.New( "no docker image tag specified in load and it cannot be inferred from the SAVE IMAGE statement: " + - "multiple tags mentioned in SAVE IMAGE") + "multiple tags mentioned in SAVE IMAGE", + ) } opt.ImageName = mts.Final.SaveImages[0].DockerTag @@ -152,13 +155,15 @@ func (w *withDockerRunLocalTar) load(ctx context.Context, cmdID string, opt Dock } if w.enableParallel { err = w.c.BuildAsync( - ctx, depTarget.String(), opt.Platform, opt.AllowPrivileged, opt.PassArgs, opt.BuildArgs, loadCmd, afterFun, w.sem) + ctx, depTarget.String(), opt.Platform, opt.AllowPrivileged, opt.PassArgs, opt.BuildArgs, loadCmd, afterFun, w.sem, + ) if err != nil { return nil, err } } else { mts, err := w.c.buildTarget( - ctx, depTarget.String(), opt.Platform, opt.AllowPrivileged, opt.PassArgs, opt.BuildArgs, false, loadCmd, cmdID, nil) + ctx, depTarget.String(), opt.Platform, opt.AllowPrivileged, opt.PassArgs, opt.BuildArgs, false, loadCmd, cmdID, nil, + ) if err != nil { return nil, err } @@ -177,7 +182,7 @@ func (w *withDockerRunLocalTar) solveImage( ) error { outDir, err := os.MkdirTemp(os.TempDir(), "earthly-docker-load") if err != nil { - return errors.Wrap(err, "mk temp dir for docker load") + return fmt.Errorf("mk temp dir for docker load: %w", err) } w.c.opt.CleanCollection.Add(func() error { @@ -188,7 +193,7 @@ func (w *withDockerRunLocalTar) solveImage( err = w.c.opt.DockerImageSolverTar.SolveImage(ctx, mts, dockerTag, outFile, !w.c.ftrs.NoTarBuildOutput) if err != nil { - return errors.Wrapf(err, "build target %s for docker load", opName) + return fmt.Errorf("build target %s for docker load: %w", opName, err) } w.mu.Lock() diff --git a/earthfile2llb/with_docker_run_reg.go b/earthfile2llb/with_docker_run_reg.go index 3e36efc025..2c55b9343c 100644 --- a/earthfile2llb/with_docker_run_reg.go +++ b/earthfile2llb/with_docker_run_reg.go @@ -2,6 +2,7 @@ package earthfile2llb import ( "context" + "errors" "fmt" "sort" "strings" @@ -15,7 +16,6 @@ import ( "github.com/EarthBuild/earthbuild/util/platutil" "github.com/EarthBuild/earthbuild/util/syncutil/semutil" "github.com/moby/buildkit/client/llb" - "github.com/pkg/errors" ) type withDockerRunRegistry struct { @@ -72,7 +72,7 @@ func (w *withDockerRunRegistry) prepareImages( imageDefChan, err := w.load(ctx, cmdID, loadOpt) if err != nil { - return nil, errors.Wrap(err, "load") + return nil, fmt.Errorf("load: %w", err) } imageDefChans = append(imageDefChans, imageDefChan) @@ -114,7 +114,7 @@ func (w *withDockerRunRegistry) prepareImages( for _, pullOpt := range opt.Pulls { imageDef, err := w.pull(ctx, pullOpt) if err != nil { - return nil, errors.Wrap(err, "pull") + return nil, fmt.Errorf("pull: %w", err) } imagesToBuild = append(imagesToBuild, imageDef) @@ -133,7 +133,7 @@ func (w *withDockerRunRegistry) Run(ctx context.Context, args []string, opt With cmdID, cmd, err := w.c.newLogbusCommand(ctx, commandName) if err != nil { - return errors.Wrap(err, "failed to create command") + return fmt.Errorf("failed to create command: %w", err) } defer func() { @@ -155,7 +155,7 @@ func (w *withDockerRunRegistry) Run(ctx context.Context, args []string, opt With res, err := w.c.opt.MultiImageSolver.SolveImages(ctx, imagesToBuild) if err != nil { - return errors.Wrap(err, "solving images") + return fmt.Errorf("solving images: %w", err) } defer res.ReleaseFunc() @@ -178,7 +178,7 @@ func (w *withDockerRunRegistry) Run(ctx context.Context, args []string, opt With // Wait for all images to build (channel will be closed when finished). results, err := readImgResults(ctx, res.ResultChan) if err != nil { - return errors.Wrap(err, "error while preparing WITH DOCKER images") + return fmt.Errorf("error while preparing WITH DOCKER images: %w", err) } // Sort the results for LLB consistency. @@ -192,7 +192,8 @@ func (w *withDockerRunRegistry) Run(ctx context.Context, args []string, opt With // This will be decoded in the wrapper. if result.NewInterImgFormat { pullImages = append( - pullImages, fmt.Sprintf("%s|%s", result.IntermediateImageName, result.FinalImageName)) + pullImages, fmt.Sprintf("%s|%s", result.IntermediateImageName, result.FinalImageName), + ) } else { pullImages = append(pullImages, result.IntermediateImageName) } @@ -230,7 +231,7 @@ func (w *withDockerRunRegistry) Run(ctx context.Context, args []string, opt With if opt.CacheID == "" { dindID, err = w.c.mts.Final.TargetInput().Hash() if err != nil { - return errors.Wrap(err, "make dind ID") + return fmt.Errorf("make dind ID: %w", err) } } else { // Note that the "cache_" prefix here is used to prevent auto-cleanup @@ -240,19 +241,22 @@ func (w *withDockerRunRegistry) Run(ctx context.Context, args []string, opt With // to prevent busting the cache, as the intermediate image names are // different every time. dockerLoadRegistrySecretID := fmt.Sprintf( - "%s-%s-EARTHLY_DOCKER_LOAD_REGISTRY", internalWithDockerSecretPrefix, dindID) + "%s-%s-EARTHLY_DOCKER_LOAD_REGISTRY", internalWithDockerSecretPrefix, dindID, + ) crOpts.extraRunOpts = append( crOpts.extraRunOpts, llb.AddSecret( "EARTHLY_DOCKER_LOAD_REGISTRY", llb.SecretID(dockerLoadRegistrySecretID), llb.SecretAsEnv(true), - )) + ), + ) err = w.c.opt.InternalSecretStore.SetSecret( - ctx, dockerLoadRegistrySecretID, []byte(strings.Join(pullImages, " "))) + ctx, dockerLoadRegistrySecretID, []byte(strings.Join(pullImages, " ")), + ) if err != nil { - return errors.Wrap(err, "set docker load registry secret") + return fmt.Errorf("set docker load registry secret: %w", err) } w.c.opt.CleanCollection.Add(func() error { //nolint:contextcheck @@ -318,7 +322,7 @@ func (w *withDockerRunRegistry) load( depTarget, err := domain.ParseTarget(opt.Target) if err != nil { - return nil, errors.Wrapf(err, "parse target %s", opt.Target) + return nil, fmt.Errorf("parse target %s: %w", opt.Target, err) } afterFn := func(_ context.Context, mts *states.MultiTarget) error { @@ -329,7 +333,7 @@ func (w *withDockerRunRegistry) load( } if len(mts.Final.SaveImages) > 1 { - return errors.Wrap(errNoImageTag, "multiple tags mentioned in SAVE IMAGE") + return fmt.Errorf("multiple tags mentioned in SAVE IMAGE: %w", errNoImageTag) } opt.ImageName = mts.Final.SaveImages[0].DockerTag @@ -346,13 +350,15 @@ func (w *withDockerRunRegistry) load( if w.enableParallel { err = w.c.BuildAsync( - ctx, depTarget.String(), opt.Platform, opt.AllowPrivileged, opt.PassArgs, opt.BuildArgs, loadCmd, afterFn, w.sem) + ctx, depTarget.String(), opt.Platform, opt.AllowPrivileged, opt.PassArgs, opt.BuildArgs, loadCmd, afterFn, w.sem, + ) if err != nil { return nil, err } } else { mts, err := w.c.buildTarget( - ctx, depTarget.String(), opt.Platform, opt.AllowPrivileged, opt.PassArgs, opt.BuildArgs, false, loadCmd, cmdID, nil) + ctx, depTarget.String(), opt.Platform, opt.AllowPrivileged, opt.PassArgs, opt.BuildArgs, false, loadCmd, cmdID, nil, + ) if err != nil { return nil, err } diff --git a/earthfile2llb/with_docker_run_tar.go b/earthfile2llb/with_docker_run_tar.go index a38479a59a..dea96340fa 100644 --- a/earthfile2llb/with_docker_run_tar.go +++ b/earthfile2llb/with_docker_run_tar.go @@ -4,6 +4,7 @@ import ( "context" "crypto/sha256" "encoding/hex" + "errors" "fmt" "os" "path" @@ -17,7 +18,6 @@ import ( "github.com/EarthBuild/earthbuild/util/platutil" "github.com/EarthBuild/earthbuild/util/syncutil/semutil" "github.com/moby/buildkit/client/llb" - "github.com/pkg/errors" ) type withDockerRunTar struct { @@ -79,7 +79,7 @@ func (w *withDockerRunTar) prepareImages(ctx context.Context, opt *WithDockerOpt optPromise, err := w.load(ctx, loadOpt) if err != nil { - return errors.Wrap(err, "load") + return fmt.Errorf("load: %w", err) } loadOptPromises = append(loadOptPromises, optPromise) @@ -122,7 +122,7 @@ func (w *withDockerRunTar) prepareImages(ctx context.Context, opt *WithDockerOpt for _, pullImageName := range opt.Pulls { pullPromise, err := w.pull(ctx, pullImageName) if err != nil { - return errors.Wrap(err, "pull") + return fmt.Errorf("pull: %w", err) } pullPromises = append(pullPromises, pullPromise) @@ -202,7 +202,7 @@ func (w *withDockerRunTar) Run(ctx context.Context, args []string, opt WithDocke dindID, err := w.c.mts.Final.TargetInput().Hash() if err != nil { - return errors.Wrap(err, "make dind ID") + return fmt.Errorf("make dind ID: %w", err) } crOpts.shellWrap = makeWithDockerdWrapFun(dindID, tarPaths, nil, opt) @@ -261,7 +261,7 @@ func (w *withDockerRunTar) pull(ctx context.Context, opt DockerPullOpt) (chan st w.c.opt.ErrorGroup.Go(func() error { release, acquireErr := w.sem.Acquire(ctx, 1) if acquireErr != nil { - return errors.Wrapf(acquireErr, "acquiring parallelism semaphore for pull load %s", opt.ImageName) + return fmt.Errorf("acquiring parallelism semaphore for pull load %s: %w", opt.ImageName, acquireErr) } defer release() @@ -282,7 +282,7 @@ func (w *withDockerRunTar) load(ctx context.Context, opt DockerLoadOpt) (chan Do depTarget, err := domain.ParseTarget(opt.Target) if err != nil { - return nil, errors.Wrapf(err, "parse target %s", opt.Target) + return nil, fmt.Errorf("parse target %s: %w", opt.Target, err) } afterFun := func(ctx context.Context, mts *states.MultiTarget) error { @@ -290,13 +290,15 @@ func (w *withDockerRunTar) load(ctx context.Context, opt DockerLoadOpt) (chan Do // Infer image name from the SAVE IMAGE statement. if len(mts.Final.SaveImages) == 0 || mts.Final.SaveImages[0].DockerTag == "" { return errors.New( - "no docker image tag specified in load and it cannot be inferred from the SAVE IMAGE statement") + "no docker image tag specified in load and it cannot be inferred from the SAVE IMAGE statement", + ) } if len(mts.Final.SaveImages) > 1 { return errors.New( "no docker image tag specified in load and it cannot be inferred from the SAVE IMAGE statement: " + - "multiple tags mentioned in SAVE IMAGE") + "multiple tags mentioned in SAVE IMAGE", + ) } opt.ImageName = mts.Final.SaveImages[0].DockerTag @@ -313,13 +315,15 @@ func (w *withDockerRunTar) load(ctx context.Context, opt DockerLoadOpt) (chan Do } if w.enableParallel { err = w.c.BuildAsync( - ctx, depTarget.String(), opt.Platform, opt.AllowPrivileged, opt.PassArgs, opt.BuildArgs, loadCmd, afterFun, w.sem) + ctx, depTarget.String(), opt.Platform, opt.AllowPrivileged, opt.PassArgs, opt.BuildArgs, loadCmd, afterFun, w.sem, + ) if err != nil { return nil, err } } else { mts, err := w.c.buildTarget( - ctx, depTarget.String(), opt.Platform, opt.AllowPrivileged, opt.PassArgs, opt.BuildArgs, false, loadCmd, "", nil) + ctx, depTarget.String(), opt.Platform, opt.AllowPrivileged, opt.PassArgs, opt.BuildArgs, false, loadCmd, "", nil, + ) if err != nil { return nil, err } @@ -336,7 +340,7 @@ func (w *withDockerRunTar) load(ctx context.Context, opt DockerLoadOpt) (chan Do func (w *withDockerRunTar) solveImage(ctx context.Context, mts *states.MultiTarget, opName, dockerTag string) error { solveID, err := states.KeyFromHashAndTag(mts.Final, dockerTag) if err != nil { - return errors.Wrap(err, "state key func") + return fmt.Errorf("state key func: %w", err) } tarContext, err := w.c.opt.SolveCache.Do(ctx, solveID, func( @@ -348,7 +352,7 @@ func (w *withDockerRunTar) solveImage(ctx context.Context, mts *states.MultiTarg outDir, err = os.MkdirTemp(os.TempDir(), "earthly-docker-load") if err != nil { - return pllb.State{}, errors.Wrap(err, "mk temp dir for docker load") + return pllb.State{}, fmt.Errorf("mk temp dir for docker load: %w", err) } w.c.opt.CleanCollection.Add(func() error { @@ -359,14 +363,14 @@ func (w *withDockerRunTar) solveImage(ctx context.Context, mts *states.MultiTarg err = w.c.opt.DockerImageSolverTar.SolveImage(ctx, mts, dockerTag, outFile, !w.c.ftrs.NoTarBuildOutput) if err != nil { - return pllb.State{}, errors.Wrapf(err, "build target %s for docker load", opName) + return pllb.State{}, fmt.Errorf("build target %s for docker load: %w", opName, err) } var dockerImageID string dockerImageID, err = dockertar.GetID(outFile) if err != nil { - return pllb.State{}, errors.Wrap(err, "inspect docker tar after build") + return pllb.State{}, fmt.Errorf("inspect docker tar after build: %w", err) } // Use the docker image ID + dockerTag as sessionID. This will cause // buildkit to use cache when these are the same as before (eg a docker image diff --git a/examples/readme/proto/pb/api.pb.go b/examples/readme/proto/pb/api.pb.go index ac6c73ee10..a9ad7fa643 100644 --- a/examples/readme/proto/pb/api.pb.go +++ b/examples/readme/proto/pb/api.pb.go @@ -5,8 +5,9 @@ package pb import ( fmt "fmt" - proto "github.com/golang/protobuf/proto" math "math" + + proto "github.com/golang/protobuf/proto" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/features/features.go b/features/features.go index e81d8a393e..80392d6946 100644 --- a/features/features.go +++ b/features/features.go @@ -3,6 +3,7 @@ package features import ( "context" + "errors" "fmt" "reflect" "sort" @@ -12,7 +13,6 @@ import ( "github.com/EarthBuild/earthbuild/internal/earthfile" "github.com/EarthBuild/earthbuild/util/flagutil" goflags "github.com/jessevdk/go-flags" - "github.com/pkg/errors" ) // Features is used to denote which features to flip on or off; this is for use in maintaining @@ -232,12 +232,12 @@ func Get(version *earthfile.Version) (*Features, bool, error) { ftrs.Major, err = strconv.Atoi(majorAndMinor[0]) if err != nil { - return nil, false, errors.Wrapf(err, "failed to parse major version %q", majorAndMinor[0]) + return nil, false, fmt.Errorf("failed to parse major version %q: %w", majorAndMinor[0], err) } ftrs.Minor, err = strconv.Atoi(majorAndMinor[1]) if err != nil { - return nil, false, errors.Wrapf(err, "failed to parse minor version %q", majorAndMinor[1]) + return nil, false, fmt.Errorf("failed to parse minor version %q: %w", majorAndMinor[1], err) } return &ftrs, hasVersion, nil diff --git a/go.mod b/go.mod index 8c461213a3..90daf3a44a 100644 --- a/go.mod +++ b/go.mod @@ -24,7 +24,6 @@ require ( github.com/gofrs/flock v0.13.0 github.com/google/go-cmp v0.7.0 github.com/google/uuid v1.6.0 - github.com/hashicorp/go-multierror v1.1.1 github.com/iancoleman/strcase v0.3.0 github.com/jdxcode/netrc v1.0.0 github.com/jessevdk/go-flags v1.6.1 @@ -39,7 +38,6 @@ require ( github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec v1.1.1 github.com/otiai10/copy v1.14.1 - github.com/pkg/errors v0.9.1 github.com/sirupsen/logrus v1.9.4 github.com/stretchr/testify v1.11.1 github.com/tonistiigi/fsutil v0.0.0-20260609174605-b61e79c0c046 @@ -103,7 +101,6 @@ require ( github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect - github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/in-toto/in-toto-golang v0.5.0 // indirect github.com/klauspost/compress v1.18.0 // indirect @@ -114,6 +111,7 @@ require ( github.com/opencontainers/runc v1.1.9 // indirect github.com/opencontainers/runtime-spec v1.1.0 // indirect github.com/otiai10/mint v1.6.3 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/poy/onpar v1.1.2 // indirect github.com/prometheus/client_golang v1.23.2 // indirect diff --git a/go.sum b/go.sum index 84159c2879..596d147424 100644 --- a/go.sum +++ b/go.sum @@ -199,13 +199,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= -github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= -github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= diff --git a/inputgraph/error.go b/inputgraph/error.go index 31ee5670ea..d8c962a6ac 100644 --- a/inputgraph/error.go +++ b/inputgraph/error.go @@ -1,11 +1,11 @@ package inputgraph import ( + "errors" "fmt" "strings" "github.com/EarthBuild/earthbuild/internal/earthfile" - "github.com/pkg/errors" ) // Error represents an auto-skip error that can include the source file name and diff --git a/inputgraph/loader.go b/inputgraph/loader.go index 1e77e9c403..0dd0a5ac76 100644 --- a/inputgraph/loader.go +++ b/inputgraph/loader.go @@ -4,6 +4,7 @@ import ( "bufio" "context" "encoding/hex" + "errors" "fmt" "os" "path/filepath" @@ -22,7 +23,6 @@ import ( "github.com/EarthBuild/earthbuild/util/buildkitskipper/hasher" "github.com/EarthBuild/earthbuild/util/flagutil" "github.com/EarthBuild/earthbuild/variables" - "github.com/pkg/errors" ) var ( @@ -126,22 +126,22 @@ func (l *loader) handleBuild(ctx context.Context, cmd earthfile.Command) error { func (l *loader) derefedTarget(targetName string) (domain.Target, error) { target, err := domain.ParseTarget(targetName) if err != nil { - return domain.Target{}, errors.Wrapf(err, "failed to parse target %s", targetName) + return domain.Target{}, fmt.Errorf("failed to parse target %s: %w", targetName, err) } derefed, _, _, err := l.varCollection.Imports().Deref(target) if err != nil { - return domain.Target{}, errors.Wrapf(err, "failed to deref target %s", target) + return domain.Target{}, fmt.Errorf("failed to deref target %s: %w", target, err) } targetRef, err := domain.JoinReferences(l.varCollection.AbsRef(), derefed) if err != nil { - return domain.Target{}, errors.Wrapf(err, "failed to join %s and %s", l.target, target) + return domain.Target{}, fmt.Errorf("failed to join %s and %s: %w", l.target, target, err) } target, ok := targetRef.(domain.Target) if !ok { - return domain.Target{}, errors.Errorf("want domain.Target, got %T", targetRef) + return domain.Target{}, fmt.Errorf("want domain.Target, got %T", targetRef) } return target, nil @@ -322,7 +322,7 @@ func (l *loader) expandCopyFiles(src string, mustExist bool) ([]string, error) { if strings.Contains(src, "*") { matches, err := filepath.Glob(src) if err != nil { - return nil, errors.Wrap(err, "unable to expand glob pattern") + return nil, fmt.Errorf("unable to expand glob pattern: %w", err) } return l.expandDirs(matches...) @@ -334,7 +334,7 @@ func (l *loader) expandCopyFiles(src string, mustExist bool) ([]string, error) { return []string{src}, nil } - return nil, errors.Wrap(err, "failed to stat file") + return nil, fmt.Errorf("failed to stat file: %w", err) } if stat.IsDir() { @@ -353,13 +353,13 @@ func (l *loader) expandDirs(dirs ...string) ([]string, error) { for _, dir := range dirs { stat, err := os.Stat(dir) if err != nil { - return nil, errors.Wrap(err, "failed to stat file") + return nil, fmt.Errorf("failed to stat file: %w", err) } if stat.IsDir() { entries, err := os.ReadDir(dir) if err != nil { - return nil, errors.Wrap(err, "failed to read dir") + return nil, fmt.Errorf("failed to read dir: %w", err) } children := []string{} @@ -834,7 +834,7 @@ func (l *loader) handleFor(ctx context.Context, forStmt earthfile.ForStatement) args, err := flagutil.ParseArgsCleaned("FOR", opts, forStmt.Args) if err != nil { - return errors.Wrap(err, "failed to parse FOR args") + return fmt.Errorf("failed to parse FOR args: %w", err) } expandedArgs, err := l.expandArgsSlice(args) diff --git a/inputgraph/util.go b/inputgraph/util.go index 55e84ede5b..3ede0f9e78 100644 --- a/inputgraph/util.go +++ b/inputgraph/util.go @@ -2,13 +2,13 @@ package inputgraph import ( "context" + "errors" "strings" "github.com/EarthBuild/earthbuild/buildcontext" "github.com/EarthBuild/earthbuild/conslogging" "github.com/EarthBuild/earthbuild/domain" "github.com/EarthBuild/earthbuild/internal/earthfile" - "github.com/pkg/errors" ) // ParseProjectCommand parses a project command from arguments. diff --git a/logbus/command.go b/logbus/command.go index 194d143aa6..fa37351e67 100644 --- a/logbus/command.go +++ b/logbus/command.go @@ -2,13 +2,15 @@ package logbus import ( "context" + "errors" + "fmt" "sync" "sync/atomic" "time" "github.com/EarthBuild/earthbuild/logstream" "github.com/EarthBuild/earthbuild/util/circbuf" - "github.com/pkg/errors" + "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -35,7 +37,7 @@ type Command struct { func newCommand(b *Bus, commandID string, targetID string) *Command { to, err := circbuf.NewBuffer(tailErrorBufferSizeBytes) if err != nil { - panic(errors.Wrap(err, "failed to create tail buffer")) + panic(fmt.Errorf("failed to create tail buffer: %w", err)) } return &Command{ @@ -60,7 +62,7 @@ func (c *Command) Write(dt []byte, ts time.Time, stream int32) (int, error) { c.mu.Unlock() if err != nil { - return 0, errors.Wrap(err, "write to tail output") + return 0, fmt.Errorf("write to tail output: %w", err) } c.b.WriteRawLog(&logstream.DeltaLog{ diff --git a/logbus/formatter/formatter.go b/logbus/formatter/formatter.go index 9d80b736c3..22964e0c91 100644 --- a/logbus/formatter/formatter.go +++ b/logbus/formatter/formatter.go @@ -6,6 +6,7 @@ import ( "bytes" "context" "encoding/json" + "errors" "fmt" "os" "strings" @@ -21,9 +22,7 @@ import ( "github.com/EarthBuild/earthbuild/util/stringutil" runc "github.com/containerd/go-runc" humanize "github.com/dustin/go-humanize" - "github.com/hashicorp/go-multierror" "github.com/mattn/go-isatty" - "github.com/pkg/errors" "google.golang.org/protobuf/proto" ) @@ -72,7 +71,7 @@ type Formatter struct { interactives map[string]struct{} // set of command IDs timingTable map[string]time.Duration // targetID -> duration commands map[string]*command - errors []error + err error console conslogging.ConsoleLogger ongoingTick time.Duration mu sync.Mutex @@ -149,7 +148,7 @@ func (f *Formatter) Write(delta *logstream.Delta) { err := f.processDelta(delta) if err != nil { - f.errors = append(f.errors, err) + f.err = errors.Join(f.err, err) } } @@ -169,12 +168,7 @@ func (f *Formatter) Close() error { f.mu.Lock() defer f.mu.Unlock() - var retErr error - for _, err := range f.errors { - retErr = multierror.Append(retErr, err) - } - - return retErr + return f.err } // Manifest returns a copy of the manifest. @@ -190,14 +184,14 @@ func (f *Formatter) Manifest() *logstream.RunManifest { func (f *Formatter) processDelta(delta *logstream.Delta) error { err := deltautil.ApplyDelta(f.manifest, delta) if err != nil { - return errors.Wrap(err, "failed to apply delta") + return fmt.Errorf("failed to apply delta: %w", err) } switch d := delta.GetDeltaTypeOneof().(type) { case *logstream.Delta_DeltaManifest: err := f.handleDeltaManifest(d.DeltaManifest) if err != nil { - return errors.Wrap(err, "failed to handle delta manifest") + return fmt.Errorf("failed to handle delta manifest: %w", err) } case *logstream.Delta_DeltaLog: err := f.handleDeltaLog(d.DeltaLog) @@ -226,7 +220,7 @@ func (f *Formatter) ongoingTickLoop(ctx context.Context) { err := f.processOngoingTick() if err != nil { - f.errors = append(f.errors, err) + f.err = errors.Join(f.err, err) } f.mu.Unlock() @@ -332,7 +326,7 @@ func (f *Formatter) handleDeltaLog(dl *logstream.DeltaLog) error { err := json.Unmarshal(output, &stats) if err != nil { - return errors.Wrap(err, "failed to parse stats") + return fmt.Errorf("failed to parse stats: %w", err) } totalCPU := time.Duration(stats.Cpu.Usage.Total) // #nosec G115 // Total is reported in nanoseconds diff --git a/logbus/setup/setup.go b/logbus/setup/setup.go index e8e801684d..9a6b5b04b7 100644 --- a/logbus/setup/setup.go +++ b/logbus/setup/setup.go @@ -3,6 +3,8 @@ package setup import ( "context" + "errors" + "fmt" "os" "strings" @@ -13,8 +15,6 @@ import ( "github.com/EarthBuild/earthbuild/logstream" "github.com/EarthBuild/earthbuild/util/deltautil" "github.com/EarthBuild/earthbuild/util/execstatssummary" - "github.com/hashicorp/go-multierror" - "github.com/pkg/errors" "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/proto" ) @@ -53,7 +53,8 @@ func New( } bs.Formatter = formatter.New( ctx, bs.Bus, debug, verbose, displayStats, - forceColor, noColor, disableOngoingUpdates, execStatsTracker, isGitHubActions) + forceColor, noColor, disableOngoingUpdates, execStatsTracker, isGitHubActions, + ) bs.Bus.AddRawSubscriber(bs.Formatter) bs.Bus.AddFormattedSubscriber(bs.ConsoleWriter) bs.SolverMonitor = solvermon.New(bs.Bus) @@ -61,7 +62,7 @@ func New( if busDebugFile != "" { f, err := os.OpenFile(busDebugFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o644) // #nosec G302, G304 if err != nil { - return nil, errors.Wrapf(err, "failed to open bus debug file %s", busDebugFile) + return nil, fmt.Errorf("failed to open bus debug file %s: %w", busDebugFile, err) } useJSON := strings.HasSuffix(busDebugFile, ".json") @@ -95,7 +96,7 @@ func (bs *BusSetup) DumpManifestToFile(path string) error { f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o644) // #nosec G302, G304 if err != nil { - return errors.Wrapf(err, "failed to open bus manifest debug file %s", path) + return fmt.Errorf("failed to open bus manifest debug file %s: %w", path, err) } useJSON := strings.HasSuffix(path, ".json") @@ -115,12 +116,12 @@ func (bs *BusSetup) DumpManifestToFile(path string) error { } if err != nil { - return errors.Wrapf(err, "failed to marshal manifest") + return fmt.Errorf("failed to marshal manifest: %w", err) } _, err = f.Write(dt) if err != nil { - return errors.Wrapf(err, "failed to write manifest") + return fmt.Errorf("failed to write manifest: %w", err) } return nil @@ -128,31 +129,31 @@ func (bs *BusSetup) DumpManifestToFile(path string) error { // Close the bus setup & gather all errors. func (bs *BusSetup) Close() error { - var ret error + var err error if bs.execStatsTracker != nil { - err := bs.execStatsTracker.Close() - if err != nil { - ret = multierror.Append(ret, errors.Wrap(err, "exec stats summary")) + trackerErr := bs.execStatsTracker.Close() + if trackerErr != nil { + err = errors.Join(err, fmt.Errorf("exec stats summary: %w", trackerErr)) } } - if errs := bs.ConsoleWriter.Errors(); len(errs) > 0 { - multi := &multierror.Error{Errors: errs} - ret = multierror.Append(ret, errors.Wrap(multi, "console writer")) + consoleErr := bs.ConsoleWriter.Err() + if consoleErr != nil { + err = errors.Join(err, fmt.Errorf("console writer: %w", consoleErr)) } - err := bs.Formatter.Close() - if err != nil { - ret = multierror.Append(ret, errors.Wrap(err, "formatter")) + formatterErr := bs.Formatter.Close() + if formatterErr != nil { + err = errors.Join(err, fmt.Errorf("formatter: %w", formatterErr)) } if bs.BusDebugWriter != nil { - if errs := bs.BusDebugWriter.Errors(); len(errs) > 0 { - multi := &multierror.Error{Errors: errs} - ret = multierror.Append(ret, errors.Wrap(multi, "bus debug writer")) + debugErr := bs.BusDebugWriter.Err() + if debugErr != nil { + err = errors.Join(err, fmt.Errorf("bus debug writer: %w", debugErr)) } } - return ret + return err } diff --git a/logbus/solvermon/solvermon.go b/logbus/solvermon/solvermon.go index e78ac97e9c..017431e8f9 100644 --- a/logbus/solvermon/solvermon.go +++ b/logbus/solvermon/solvermon.go @@ -3,6 +3,7 @@ package solvermon import ( "context" + "fmt" "sync" "time" @@ -14,7 +15,6 @@ import ( "github.com/EarthBuild/earthbuild/util/xcontext" "github.com/moby/buildkit/client" "github.com/opencontainers/go-digest" - "github.com/pkg/errors" ) // SolverMonitor is a buildkit solver monitor. @@ -57,7 +57,7 @@ func (sm *SolverMonitor) MonitorProgress(ctx context.Context, ch chan *client.So for { select { case <-delayedCtx.Done(): - return errors.Wrap(ctx.Err(), "timed out waiting for status channel to close") + return fmt.Errorf("timed out waiting for status channel to close: %w", ctx.Err()) case status, ok := <-ch: if !ok { return nil @@ -114,7 +114,8 @@ func (sm *SolverMonitor) handleBuildkitStatus(status *client.SolveStatus) error cp, err = bp.NewCommand( cmdID, operation, meta.TargetID, category, meta.Platform, vertex.Cached, meta.Local, meta.Interactive, meta.SourceLocation, - meta.RepoGitURL, meta.RepoGitHash, meta.RepoFileRelToRepo) + meta.RepoGitURL, meta.RepoGitHash, meta.RepoFileRelToRepo, + ) if err != nil { return err } diff --git a/logbus/solvermon/vertexmon.go b/logbus/solvermon/vertexmon.go index f20ba72436..9f0638cb0e 100644 --- a/logbus/solvermon/vertexmon.go +++ b/logbus/solvermon/vertexmon.go @@ -2,6 +2,7 @@ package solvermon import ( "encoding/json" + "errors" "fmt" "math" "regexp" @@ -16,7 +17,6 @@ import ( "github.com/EarthBuild/earthbuild/util/stringutil" "github.com/EarthBuild/earthbuild/util/vertexmeta" "github.com/moby/buildkit/client" - "github.com/pkg/errors" ) const ( @@ -221,18 +221,18 @@ func (vm *vertexMonitor) Write(dt []byte, ts time.Time, stream int) (int, error) if stream == BuildkitStatsStream { stats, err := vm.ssp.Parse(dt) if err != nil { - return 0, errors.Wrap(err, "failed decoding stats stream") + return 0, fmt.Errorf("failed decoding stats stream: %w", err) } for _, statsSample := range stats { statsJSON, err := json.Marshal(statsSample) if err != nil { - return 0, errors.Wrap(err, "stats json encode failed") + return 0, fmt.Errorf("stats json encode failed: %w", err) } _, err = vm.cp.Write(statsJSON, ts, int32(stream)) // #nosec G115 if err != nil { - return 0, errors.Wrap(err, "write stats") + return 0, fmt.Errorf("write stats: %w", err) } } @@ -241,7 +241,7 @@ func (vm *vertexMonitor) Write(dt []byte, ts time.Time, stream int) (int, error) _, err := vm.cp.Write(dt, ts, int32(stream)) // #nosec G115 if err != nil { - return 0, errors.Wrap(err, "write log line") + return 0, fmt.Errorf("write log line: %w", err) } return len(dt), nil diff --git a/logbus/solvermon/vertexmon_test.go b/logbus/solvermon/vertexmon_test.go index f033e0acfc..6a5d286045 100644 --- a/logbus/solvermon/vertexmon_test.go +++ b/logbus/solvermon/vertexmon_test.go @@ -1,10 +1,11 @@ package solvermon import ( + "errors" "testing" "github.com/EarthBuild/earthbuild/logstream" - "github.com/pkg/errors" + "github.com/stretchr/testify/assert" ) diff --git a/logbus/writersub/raw.go b/logbus/writersub/raw.go index d35cedfec3..8c2cd6555d 100644 --- a/logbus/writersub/raw.go +++ b/logbus/writersub/raw.go @@ -1,6 +1,7 @@ package writersub import ( + "errors" "io" "sync" @@ -11,10 +12,10 @@ import ( // RawWriterSub is a bus subscriber that can print formatted logs to a writer. type RawWriterSub struct { - w io.Writer - errors []error - mu sync.Mutex - json bool + w io.Writer + err error + mu sync.Mutex + json bool } // NewRaw creates a new WriterSub. @@ -43,21 +44,21 @@ func (rws *RawWriterSub) Write(delta *logstream.Delta) { } if err != nil { - rws.errors = append(rws.errors, err) + rws.err = errors.Join(rws.err, err) return } _, err = rws.w.Write(dt) if err != nil { - rws.errors = append(rws.errors, err) + rws.err = errors.Join(rws.err, err) return } } -// Errors returns any errors that occurred while writing to the writer. -func (rws *RawWriterSub) Errors() []error { +// Err returns any error that occurred while writing to the writer. +func (rws *RawWriterSub) Err() error { rws.mu.Lock() defer rws.mu.Unlock() - return rws.errors + return rws.err } diff --git a/logbus/writersub/writersub.go b/logbus/writersub/writersub.go index d5727af545..7f274ae3f2 100644 --- a/logbus/writersub/writersub.go +++ b/logbus/writersub/writersub.go @@ -2,6 +2,7 @@ package writersub import ( + "errors" "io" "sync" @@ -11,8 +12,8 @@ import ( // WriterSub is a bus subscriber that can print formatted logs to a writer. type WriterSub struct { w io.Writer + err error targetIDFilter string - errors []error mu sync.Mutex } @@ -37,17 +38,17 @@ func (ws *WriterSub) Write(delta *logstream.Delta) { _, err := ws.w.Write(d.DeltaFormattedLog.GetData()) if err != nil { - ws.errors = append(ws.errors, err) + ws.err = errors.Join(ws.err, err) return } default: } } -// Errors returns any errors that occurred while writing to the writer. -func (ws *WriterSub) Errors() []error { +// Err returns any error that occurred while writing to the writer. +func (ws *WriterSub) Err() error { ws.mu.Lock() defer ws.mu.Unlock() - return ws.errors + return ws.err } diff --git a/logstream/delta.pb.go b/logstream/delta.pb.go index 20bcd789dd..ace523568b 100644 --- a/logstream/delta.pb.go +++ b/logstream/delta.pb.go @@ -7,10 +7,11 @@ package logstream import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" + "reflect" + "sync" + + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/runtime/protoimpl" ) const ( @@ -1154,24 +1155,27 @@ func file_delta_proto_rawDescGZIP() []byte { return file_delta_proto_rawDescData } -var file_delta_proto_msgTypes = make([]protoimpl.MessageInfo, 10) -var file_delta_proto_goTypes = []interface{}{ - (*Delta)(nil), // 0: api.public.logstream.Delta - (*DeltaLog)(nil), // 1: api.public.logstream.DeltaLog - (*DeltaFormattedLog)(nil), // 2: api.public.logstream.DeltaFormattedLog - (*DeltaManifest)(nil), // 3: api.public.logstream.DeltaManifest - (*DeltaTargetManifest)(nil), // 4: api.public.logstream.DeltaTargetManifest - (*DeltaCommandManifest)(nil), // 5: api.public.logstream.DeltaCommandManifest - (*DeltaManifest_ResumeBuild)(nil), // 6: api.public.logstream.DeltaManifest.ResumeBuild - (*DeltaManifest_FieldsDelta)(nil), // 7: api.public.logstream.DeltaManifest.FieldsDelta - nil, // 8: api.public.logstream.DeltaManifest.FieldsDelta.TargetsEntry - nil, // 9: api.public.logstream.DeltaManifest.FieldsDelta.CommandsEntry - (*RunManifest)(nil), // 10: api.public.logstream.RunManifest - (RunStatus)(0), // 11: api.public.logstream.RunStatus - (*SourceLocation)(nil), // 12: api.public.logstream.SourceLocation - (*CommandTarget)(nil), // 13: api.public.logstream.CommandTarget - (*Failure)(nil), // 14: api.public.logstream.Failure -} +var ( + file_delta_proto_msgTypes = make([]protoimpl.MessageInfo, 10) + file_delta_proto_goTypes = []interface{}{ + (*Delta)(nil), // 0: api.public.logstream.Delta + (*DeltaLog)(nil), // 1: api.public.logstream.DeltaLog + (*DeltaFormattedLog)(nil), // 2: api.public.logstream.DeltaFormattedLog + (*DeltaManifest)(nil), // 3: api.public.logstream.DeltaManifest + (*DeltaTargetManifest)(nil), // 4: api.public.logstream.DeltaTargetManifest + (*DeltaCommandManifest)(nil), // 5: api.public.logstream.DeltaCommandManifest + (*DeltaManifest_ResumeBuild)(nil), // 6: api.public.logstream.DeltaManifest.ResumeBuild + (*DeltaManifest_FieldsDelta)(nil), // 7: api.public.logstream.DeltaManifest.FieldsDelta + nil, // 8: api.public.logstream.DeltaManifest.FieldsDelta.TargetsEntry + nil, // 9: api.public.logstream.DeltaManifest.FieldsDelta.CommandsEntry + (*RunManifest)(nil), // 10: api.public.logstream.RunManifest + RunStatus(0), // 11: api.public.logstream.RunStatus + (*SourceLocation)(nil), // 12: api.public.logstream.SourceLocation + (*CommandTarget)(nil), // 13: api.public.logstream.CommandTarget + (*Failure)(nil), // 14: api.public.logstream.Failure + } +) + var file_delta_proto_depIdxs = []int32{ 3, // 0: api.public.logstream.Delta.delta_manifest:type_name -> api.public.logstream.DeltaManifest 1, // 1: api.public.logstream.Delta.delta_log:type_name -> api.public.logstream.DeltaLog diff --git a/regproxy/controller.go b/regproxy/controller.go index 7c48c23d94..3df1488832 100644 --- a/regproxy/controller.go +++ b/regproxy/controller.go @@ -2,6 +2,7 @@ package regproxy import ( "context" + "errors" "fmt" "net" "net/http" @@ -12,7 +13,6 @@ import ( "github.com/EarthBuild/earthbuild/util/containerutil" "github.com/EarthBuild/earthbuild/util/stringutil" registry "github.com/moby/buildkit/api/services/registry" - "github.com/pkg/errors" ) const ( @@ -56,7 +56,7 @@ func (c *Controller) Start(ctx context.Context) (string, func(), error) { ln, err := (&net.ListenConfig{}).Listen(ctx, "tcp", addr) if err != nil { - return "", nil, errors.Wrap(err, "failed to create proxy listener") + return "", nil, fmt.Errorf("failed to create proxy listener: %w", err) } p := newRegistryProxy(ln, c.registryClient) @@ -107,7 +107,7 @@ func (c *Controller) Start(ctx context.Context) (string, func(), error) { port, err := c.startDarwinProxy(ctx, containerName, registry.Port) if err != nil { stopFn(ctx) - return "", nil, errors.Wrap(err, "failed to start Darwin support container") + return "", nil, fmt.Errorf("failed to start Darwin support container: %w", err) } addr = fmt.Sprintf("127.0.0.1:%d", port) @@ -138,7 +138,7 @@ func (c *Controller) startDarwinProxy(ctx context.Context, containerName string, containerPort, err := acquireFreePort(ctx) if err != nil { - return 0, errors.Wrap(err, "failed to acquire free port") + return 0, fmt.Errorf("failed to acquire free port: %w", err) } runCfg := containerutil.ContainerRun{ @@ -160,7 +160,7 @@ func (c *Controller) startDarwinProxy(ctx context.Context, containerName string, err = c.containerFrontend.ContainerRun(ctx, runCfg) if err != nil { - return 0, errors.Wrap(err, "failed to start support container") + return 0, fmt.Errorf("failed to start support container: %w", err) } childCtx, cancel := context.WithTimeout(ctx, c.darwinProxyWait) @@ -233,7 +233,7 @@ func (c *Controller) stopDarwinProxy(containerName string, checkExists bool) err err := c.containerFrontend.ContainerRemove(detachedCtx, true, containerName) if err != nil { - return errors.Wrap(err, "failed to stop support container") + return fmt.Errorf("failed to stop support container: %w", err) } return nil @@ -244,7 +244,7 @@ func acquireFreePort(ctx context.Context) (int, error) { ln, err := (&net.ListenConfig{}).Listen(ctx, "tcp", addr) if err != nil { - return 0, errors.Wrap(err, "listen on open port") + return 0, fmt.Errorf("listen on open port: %w", err) } defer ln.Close() // Immediately close the listener diff --git a/regproxy/proxy.go b/regproxy/proxy.go index 0216c8e84e..f962c36d6e 100644 --- a/regproxy/proxy.go +++ b/regproxy/proxy.go @@ -2,13 +2,13 @@ package regproxy import ( "context" + "fmt" "io" "net" "sync" "sync/atomic" registry "github.com/moby/buildkit/api/services/registry" - "github.com/pkg/errors" "golang.org/x/sync/errgroup" ) @@ -48,7 +48,7 @@ func (r *registryProxy) serve(ctx context.Context) { conn, err := r.ln.Accept() if err != nil { if !r.done.Load() { - r.errCh <- errors.Wrap(err, "failed to accept") + r.errCh <- fmt.Errorf("failed to accept: %w", err) } return @@ -75,7 +75,7 @@ func (r *registryProxy) handle(ctx context.Context, conn net.Conn) error { stream, err := r.cl.Proxy(ctx) if err != nil { - return errors.Wrap(err, "failed to create proxy stream") + return fmt.Errorf("failed to create proxy stream: %w", err) } rw := registry.NewStreamRW(stream) @@ -84,12 +84,12 @@ func (r *registryProxy) handle(ctx context.Context, conn net.Conn) error { eg.Go(func() error { _, err = registry.CopyWithDeadline(conn, rw) if err != nil { - return errors.Wrap(err, "failed to write to stream") + return fmt.Errorf("failed to write to stream: %w", err) } err = stream.CloseSend() if err != nil { - return errors.Wrap(err, "failed to close stream") + return fmt.Errorf("failed to close stream: %w", err) } return nil @@ -98,7 +98,7 @@ func (r *registryProxy) handle(ctx context.Context, conn net.Conn) error { eg.Go(func() error { _, err = io.Copy(conn, rw) if err != nil { - return errors.Wrap(err, "failed to read from stream") + return fmt.Errorf("failed to read from stream: %w", err) } return nil @@ -106,7 +106,7 @@ func (r *registryProxy) handle(ctx context.Context, conn net.Conn) error { err = eg.Wait() if err != nil { - return errors.Wrap(err, "failed to wait") + return fmt.Errorf("failed to wait: %w", err) } return nil diff --git a/states/dedup/targetinput.go b/states/dedup/targetinput.go index 2eb53757e3..f28d16abec 100644 --- a/states/dedup/targetinput.go +++ b/states/dedup/targetinput.go @@ -4,11 +4,10 @@ import ( "crypto/sha256" "encoding/hex" "encoding/json" + "fmt" "github.com/EarthBuild/earthbuild/domain" "github.com/EarthBuild/earthbuild/variables/reserved" - - "github.com/pkg/errors" ) // TargetInput represents the conditions in which a target is invoked. @@ -99,7 +98,7 @@ func (ti TargetInput) cloneNoTag() (TargetInput, error) { func (ti TargetInput) Hash() (string, error) { tiBytes, err := json.Marshal(&ti) if err != nil { - return "", errors.Wrap(err, "serialize TargetInput when creating hash") + return "", fmt.Errorf("serialize TargetInput when creating hash: %w", err) } digest := sha256.Sum256(tiBytes) @@ -116,7 +115,7 @@ func (ti TargetInput) HashNoTag() (string, error) { tiBytes, err := json.Marshal(&tiNoTag) if err != nil { - return "", errors.Wrap(err, "serialize TargetInput when creating hash no tag") + return "", fmt.Errorf("serialize TargetInput when creating hash no tag: %w", err) } digest := sha256.Sum256(tiBytes) diff --git a/states/solvecache.go b/states/solvecache.go index 838f43836f..a03b37b571 100644 --- a/states/solvecache.go +++ b/states/solvecache.go @@ -6,7 +6,6 @@ import ( "github.com/EarthBuild/earthbuild/util/llbutil/pllb" "github.com/EarthBuild/earthbuild/util/syncutil/synccache" - "github.com/pkg/errors" ) // SolveCacheConstructor is func taking a StateKey and returning a state. @@ -55,7 +54,7 @@ func (sc *SolveCache) Do(ctx context.Context, sk StateKey, constructor SolveCach func KeyFromHashAndTag(target *SingleTarget, dockerTag string) (StateKey, error) { hash, err := target.TargetInput().Hash() if err != nil { - return StateKey(""), errors.Wrap(err, "target input hash") + return StateKey(""), fmt.Errorf("target input hash: %w", err) } key := fmt.Sprintf("%s-%s", dockerTag, hash) @@ -67,7 +66,7 @@ func KeyFromHashAndTag(target *SingleTarget, dockerTag string) (StateKey, error) func KeyFromState(target *SingleTarget) (StateKey, error) { hash, err := target.TargetInput().Hash() if err != nil { - return StateKey(""), errors.Wrap(err, "target input hash") + return StateKey(""), fmt.Errorf("target input hash: %w", err) } return StateKey(hash), nil diff --git a/states/states.go b/states/states.go index c7f6bd1486..3b4efd3f28 100644 --- a/states/states.go +++ b/states/states.go @@ -332,7 +332,8 @@ func (sts *SingleTarget) addOverridingVarsAsBuildArgInputs(overridingVars *varia for _, key := range overridingVars.Sorted() { ovVar, _ := overridingVars.Get(key) sts.targetInput = sts.targetInput.WithBuildArgInput( - dedup.BuildArgInput{ConstantValue: ovVar, Name: key}) + dedup.BuildArgInput{ConstantValue: ovVar, Name: key}, + ) } } diff --git a/states/visited-legacy.go b/states/visited-legacy.go index c8b1a7b6b1..a42e4cad27 100644 --- a/states/visited-legacy.go +++ b/states/visited-legacy.go @@ -2,13 +2,13 @@ package states import ( "context" + "fmt" "sync" "github.com/EarthBuild/earthbuild/domain" "github.com/EarthBuild/earthbuild/states/dedup" "github.com/EarthBuild/earthbuild/util/platutil" "github.com/EarthBuild/earthbuild/variables" - "github.com/pkg/errors" ) // legacyVisitedCollection is a collection of visited targets. @@ -67,8 +67,9 @@ func (vc *legacyVisitedCollection) Add( // Existing sts. if dependents[sts.ID] { // Infinite recursion. The previously visited sts is a dependent of us. - return nil, false, errors.Errorf( - "infinite recursion detected for target %s", target.String()) + return nil, false, fmt.Errorf( + "infinite recursion detected for target %s", target.String(), + ) } // If it's not a dependent, then it *has* to be done at this point. // Sanity check. diff --git a/tests/cli/cli_test.go b/tests/cli/cli_test.go index 33d97f62e1..57708d258c 100644 --- a/tests/cli/cli_test.go +++ b/tests/cli/cli_test.go @@ -57,7 +57,8 @@ func TestBuiltinArgCannotBePassedOnCommandLine(t *testing.T) { projectDir := copyFixtureDir(t, "builtin-args") replaceVersionLine(t, filepath.Join(projectDir, "Earthfile"), versionLine) - out, err := runEarth(t, projectDir, + out, err := runEarth( + t, projectDir, "--no-output", "--build-arg", "EARTHLY_VERSION=123", "+builtin-args-test", diff --git a/util/cliutil/earthlydir.go b/util/cliutil/earthlydir.go index 5e863d2375..5987d0c396 100644 --- a/util/cliutil/earthlydir.go +++ b/util/cliutil/earthlydir.go @@ -1,13 +1,13 @@ package cliutil import ( + "fmt" "os" "os/user" "path/filepath" "sync" "github.com/EarthBuild/earthbuild/util/fileutil" - "github.com/pkg/errors" ) var ( @@ -51,21 +51,21 @@ func GetOrCreateEarthDir(installName string) (string, error) { earthDirCreateOnce.Do(func() { earthDirExists, err := fileutil.DirExists(earthDir) if err != nil { - errEarthDirCreate = errors.Wrapf(err, "unable to create dir %s", earthDir) + errEarthDirCreate = fmt.Errorf("unable to create dir %s: %w", earthDir, err) return } if !earthDirExists { err := os.MkdirAll(earthDir, 0o755) // #nosec G301 if err != nil { - errEarthDirCreate = errors.Wrapf(err, "unable to create dir %s", earthDir) + errEarthDirCreate = fmt.Errorf("unable to create dir %s: %w", earthDir, err) return } if earthDirSudoUser != nil { err := fileutil.EnsureUserOwned(earthDir, earthDirSudoUser) if err != nil { - errEarthDirCreate = errors.Wrapf(err, "failed to ensure %s is owned by %s", earthDir, earthDirSudoUser) + errEarthDirCreate = fmt.Errorf("failed to ensure %s is owned by %s: %w", earthDir, earthDirSudoUser, err) } } } @@ -86,7 +86,7 @@ func EnsurePermissions(installName string) error { if sudoUser != nil { err := fileutil.EnsureUserOwned(earthDir, sudoUser) if err != nil { - return errors.Wrapf(err, "failed to ensure %s is owned by %s", earthDir, sudoUser) + return fmt.Errorf("failed to ensure %s is owned by %s: %w", earthDir, sudoUser, err) } } diff --git a/util/containerutil/docker.go b/util/containerutil/docker.go index 20942468c1..1cf651423b 100644 --- a/util/containerutil/docker.go +++ b/util/containerutil/docker.go @@ -3,6 +3,7 @@ package containerutil import ( "context" "encoding/json" + "errors" "fmt" "io" "os" @@ -11,9 +12,7 @@ import ( "al.essio.dev/pkg/shellescape" "github.com/dustin/go-humanize" - "github.com/hashicorp/go-multierror" _ "github.com/moby/buildkit/client/connhelper/dockercontainer" // Load "docker-container://" helper. - "github.com/pkg/errors" ) type dockerShellFrontend struct { @@ -58,7 +57,7 @@ func NewDockerShellFrontend(ctx context.Context, cfg *FrontendConfig) (Container fe.urls, err = fe.setupAndValidateAddresses(FrontendDockerShell, cfg) if err != nil { - return nil, errors.Wrap(err, "failed to calculate buildkit URLs") + return nil, fmt.Errorf("failed to calculate buildkit URLs: %w", err) } output, err = fe.commandContextOutput(ctx, "info", "--format={{.DockerRootDir}}") @@ -69,7 +68,7 @@ func NewDockerShellFrontend(ctx context.Context, cfg *FrontendConfig) (Container output, err2 = fe.commandContextOutput(ctx, "info", "--format={{.Store.GraphRoot}}") if err2 != nil { - return nil, errors.Wrap(err, "failed to get docker root dir") + return nil, fmt.Errorf("failed to get docker root dir: %w", err) } } @@ -119,7 +118,7 @@ func (dsf *dockerShellFrontend) Information(ctx context.Context) (*FrontendInfo, err = json.Unmarshal([]byte(output.string()), &allInfo) if err != nil { - return nil, errors.Wrap(err, "failed to parse docker version output") + return nil, fmt.Errorf("failed to parse docker version output: %w", err) } host, exists := os.LookupEnv("DOCKER_HOST") @@ -163,7 +162,7 @@ func (dsf *dockerShellFrontend) ImagePull(ctx context.Context, refs ...string) e for _, ref := range refs { _, cmdErr := dsf.commandContextOutput(ctx, "pull", ref) if cmdErr != nil { - err = multierror.Append(err, cmdErr) + err = errors.Join(err, cmdErr) } } @@ -189,7 +188,7 @@ func (dsf *dockerShellFrontend) ImageLoad(ctx context.Context, images ...io.Read output, cmdErr := cmd.CombinedOutput() if cmdErr != nil { - err = multierror.Append(err, errors.Wrapf(cmdErr, "image load failed: %s", string(output))) + err = errors.Join(err, fmt.Errorf("image load failed: %s: %w", string(output), cmdErr)) } } @@ -218,7 +217,7 @@ func (dsf *dockerShellFrontend) VolumeInfo(ctx context.Context, volumeNames ...s err := json.Unmarshal([]byte(output.stdout.String()), &volumeInfos) if err != nil { - return nil, errors.Wrapf(err, "failed to decode docker volume info for %v", volumeNames) + return nil, fmt.Errorf("failed to decode docker volume info for %v: %w", volumeNames, err) } for _, name := range volumeNames { @@ -226,7 +225,7 @@ func (dsf *dockerShellFrontend) VolumeInfo(ctx context.Context, volumeNames ...s if name == volumeInfo.Name { bytes, parseErr := humanize.ParseBytes(volumeInfo.Size) if parseErr != nil { - err = multierror.Append(err, parseErr) + err = errors.Join(err, parseErr) } else { results[name] = &VolumeInfo{ Name: volumeInfo.Name, diff --git a/util/containerutil/frontend.go b/util/containerutil/frontend.go index ea24f44555..a1c75ee461 100644 --- a/util/containerutil/frontend.go +++ b/util/containerutil/frontend.go @@ -2,12 +2,10 @@ package containerutil import ( "context" + "errors" "fmt" "io" - "github.com/hashicorp/go-multierror" - "github.com/pkg/errors" - "github.com/EarthBuild/earthbuild/conslogging" ) @@ -65,7 +63,7 @@ func autodetectFrontend(ctx context.Context, cfg *FrontendConfig) (ContainerFron } { fe, err := frontendIfAvailable(ctx, feType, cfg) if err != nil { - errs = multierror.Append(errs, err) + errs = errors.Join(errs, err) continue } @@ -77,7 +75,7 @@ func autodetectFrontend(ctx context.Context, cfg *FrontendConfig) (ContainerFron return fe, nil } - return nil, errors.Wrapf(errs, "failed to autodetect a supported frontend") + return nil, fmt.Errorf("failed to autodetect a supported frontend: %w", errs) } func frontendIfAvailable(ctx context.Context, feType string, cfg *FrontendConfig) (ContainerFrontend, error) { @@ -94,7 +92,7 @@ func frontendIfAvailable(ctx context.Context, feType string, cfg *FrontendConfig fe, err := newFe(ctx, cfg) if err != nil { - return nil, errors.Wrapf(err, "%s frontend failed to initialize", feType) + return nil, fmt.Errorf("%s frontend failed to initialize: %w", feType, err) } if !fe.IsAvailable(ctx) { diff --git a/util/containerutil/frontend_integration_test.go b/util/containerutil/frontend_integration_test.go index 2c47a6410e..f7550cb66d 100644 --- a/util/containerutil/frontend_integration_test.go +++ b/util/containerutil/frontend_integration_test.go @@ -6,6 +6,7 @@ import ( "bufio" "bytes" "context" + "errors" "fmt" "os" "os/exec" @@ -16,9 +17,6 @@ import ( "github.com/EarthBuild/earthbuild/conslogging" "github.com/EarthBuild/earthbuild/util/containerutil" - - "github.com/hashicorp/go-multierror" - "github.com/pkg/errors" ) func TestFrontendNew(t *testing.T) { @@ -717,7 +715,7 @@ func startTestContainers(ctx context.Context, feBinary string, names ...string) if createErr != nil { // the frontend exists but is non-functional. This is... not likely to work at all. - err = multierror.Append(err, errors.Wrap(createErr, string(output))) + err = errors.Join(err, fmt.Errorf("%s: %w", string(output), createErr)) } }(name) } @@ -767,7 +765,7 @@ func removeContainers(ctx context.Context, feBinary string, names ...string) err defer m.Unlock() if removeErr != nil { - err = multierror.Append(err, fmt.Errorf("failed to remove container %s", name)) + err = errors.Join(err, fmt.Errorf("failed to remove container %s", name)) } }(name) } @@ -801,7 +799,7 @@ func waitForContainers(ctx context.Context, feBinary string, names ...string) er if inspectErr != nil { m.Lock() - err = multierror.Append(err, inspectErr) + err = errors.Join(err, inspectErr) m.Unlock() @@ -818,7 +816,7 @@ func waitForContainers(ctx context.Context, feBinary string, names ...string) er m.Lock() defer m.Unlock() - err = multierror.Append(err, fmt.Errorf("failed to wait for container %s to start", name)) + err = errors.Join(err, fmt.Errorf("failed to wait for container %s to start", name)) }(name) } @@ -836,7 +834,7 @@ func spawnTestImages(ctx context.Context, feBinary string, refs ...string) (func output, createErr := cmd.CombinedOutput() if createErr != nil { // the frontend exists but is non-functional. This is... not likely to work at all. - err = multierror.Append(err, errors.Wrap(createErr, string(output))) + err = errors.Join(err, fmt.Errorf("%s: %w", string(output), createErr)) break } @@ -845,7 +843,7 @@ func spawnTestImages(ctx context.Context, feBinary string, refs ...string) (func output, tagErr := cmd.CombinedOutput() if tagErr != nil { // the frontend exists but is non-functional. This is... not likely to work at all. - err = multierror.Append(err, errors.Wrap(tagErr, string(output))) + err = errors.Join(err, fmt.Errorf("%s: %w", string(output), tagErr)) break } } @@ -867,7 +865,7 @@ func spawnTestVolumes(ctx context.Context, feBinary string, names ...string) (fu output, createErr := cmd.CombinedOutput() if createErr != nil { // the frontend exists but is non-functional. This is... not likely to work at all. - err = multierror.Append(err, errors.Wrapf(createErr, "%s: %s", string(output), name)) + err = errors.Join(err, fmt.Errorf("%s: %s: %w", string(output), name, createErr)) } } diff --git a/util/containerutil/podman.go b/util/containerutil/podman.go index c3d7b364a3..c7a48e454a 100644 --- a/util/containerutil/podman.go +++ b/util/containerutil/podman.go @@ -3,15 +3,15 @@ package containerutil import ( "context" "encoding/json" + "errors" + "fmt" "io" "os" "strconv" "strings" "github.com/dustin/go-humanize" - "github.com/hashicorp/go-multierror" _ "github.com/moby/buildkit/client/connhelper/podmancontainer" // Load "podman-container://" helper. - "github.com/pkg/errors" ) type podmanShellFrontend struct { @@ -50,14 +50,14 @@ func NewPodmanShellFrontend(ctx context.Context, cfg *FrontendConfig) (Container isRootless, err := strconv.ParseBool(trimmedStdOut) if err != nil { - return nil, errors.Wrapf(err, "info returned invalid value %s", output.string()) + return nil, fmt.Errorf("info returned invalid value %s: %w", output.string(), err) } fe.rootless = isRootless fe.urls, err = fe.setupAndValidateAddresses(FrontendPodmanShell, cfg) if err != nil { - return nil, errors.Wrap(err, "failed to calculate buildkit URLs") + return nil, fmt.Errorf("failed to calculate buildkit URLs: %w", err) } return fe, nil @@ -84,7 +84,7 @@ func (psf *podmanShellFrontend) Information(ctx context.Context) (*FrontendInfo, hasRemote, err := strconv.ParseBool(output.string()) if err != nil { - return nil, errors.Wrapf(err, "info returned invalid value %s", output.string()) + return nil, fmt.Errorf("info returned invalid value %s: %w", output.string(), err) } args := []string{"version", "--format=json"} @@ -124,7 +124,7 @@ func (psf *podmanShellFrontend) Information(ctx context.Context) (*FrontendInfo, err = json.Unmarshal([]byte(output.string()), &allInfo) if err != nil { - return nil, errors.Wrapf(err, "failed to parse version output %s", output.string()) + return nil, fmt.Errorf("failed to parse version output %s: %w", output.string(), err) } host := "daemonless" @@ -164,7 +164,7 @@ func (psf *podmanShellFrontend) ImagePull(ctx context.Context, refs ...string) e _, cmdErr := psf.commandContextOutput(ctx, args...) if cmdErr != nil { - err = multierror.Append(err, cmdErr) + err = errors.Join(err, cmdErr) } } @@ -190,13 +190,13 @@ func (psf *podmanShellFrontend) ImageLoad(ctx context.Context, images ...io.Read // here: https://github.com/earthly/earthly/issues/1285 file, tmpErr := os.CreateTemp("", "earthly-podman-load-*") if tmpErr != nil { - err = multierror.Append(err, errors.Wrap(tmpErr, "failed to create temp tarball")) + err = errors.Join(err, fmt.Errorf("failed to create temp tarball: %w", tmpErr)) continue } _, copyErr := io.Copy(file, image) if copyErr != nil { - err = multierror.Append(err, errors.Wrapf(tmpErr, "failed to write to %s", file.Name())) + err = errors.Join(err, fmt.Errorf("failed to write to %s: %w", file.Name(), copyErr)) continue } defer file.Close() @@ -204,7 +204,7 @@ func (psf *podmanShellFrontend) ImageLoad(ctx context.Context, images ...io.Read output, cmdErr := psf.commandContextOutput(ctx, "pull", "docker-archive:"+file.Name()) if cmdErr != nil { - err = multierror.Append(err, errors.Wrapf(cmdErr, "image load failed: %s", output.string())) + err = errors.Join(err, fmt.Errorf("image load failed: %s: %w", output.string(), cmdErr)) } } @@ -235,8 +235,8 @@ func (psf *podmanShellFrontend) VolumeInfo(ctx context.Context, volumeNames ...s var bytes uint64 bytes, parseErr := humanize.ParseBytes(lineParts[2]) - if err != nil { - err = multierror.Append(err, parseErr) + if parseErr != nil { + err = errors.Join(err, parseErr) break } @@ -244,7 +244,7 @@ func (psf *podmanShellFrontend) VolumeInfo(ctx context.Context, volumeNames ...s mountpoint, mountpointErr := psf. commandContextOutput(ctx, "volume", "inspect", volumeName, "--format={{.Mountpoint}}") if mountpointErr != nil { - err = multierror.Append(err, mountpointErr) + err = errors.Join(err, mountpointErr) break } diff --git a/util/containerutil/shell_shared.go b/util/containerutil/shell_shared.go index dc18f76fc9..d1c7a36dbd 100644 --- a/util/containerutil/shell_shared.go +++ b/util/containerutil/shell_shared.go @@ -3,6 +3,7 @@ package containerutil import ( "context" "encoding/json" + "errors" "fmt" "net" "net/url" @@ -13,9 +14,7 @@ import ( "time" "github.com/EarthBuild/earthbuild/conslogging" - "github.com/hashicorp/go-multierror" _ "github.com/moby/buildkit/client/connhelper/dockercontainer" // Load "docker-container://" helper. - "github.com/pkg/errors" ) type containerInfo struct { @@ -85,7 +84,7 @@ func parseContainerList(output string) ([]*ContainerInfo, error) { createdAt, err := time.Parse(containerDateFormat, parts[4]) if err != nil { - return nil, errors.Wrap(err, "failed to parse container date") + return nil, fmt.Errorf("failed to parse container date: %w", err) } ret = append(ret, &ContainerInfo{ @@ -120,7 +119,7 @@ func (sf *shellFrontend) ContainerInfo(ctx context.Context, namesOrIDs ...string err := json.Unmarshal([]byte(output.stdout.String()), &containers) if err != nil { - return nil, errors.Wrapf(err, "failed to unmarshal container inspect output %s", output.stdout.String()) + return nil, fmt.Errorf("failed to unmarshal container inspect output %s: %w", output.stdout.String(), err) } for i, container := range containers { @@ -196,7 +195,7 @@ func (sf *shellFrontend) ContainerLogs(ctx context.Context, namesOrIDs ...string cmdErr := cmd.Run() if cmdErr != nil { - err = multierror.Append(err, cmdErr) + err = errors.Join(err, cmdErr) continue } @@ -268,7 +267,7 @@ func (sf *shellFrontend) ContainerRun(ctx context.Context, containers ...Contain _, cmdErr := sf.commandContextOutput(ctx, args...) if cmdErr != nil { - err = multierror.Append(err, cmdErr) + err = errors.Join(err, cmdErr) } } @@ -298,7 +297,7 @@ func (sf *shellFrontend) ImageInfo(ctx context.Context, refs ...string) (map[str err := json.Unmarshal([]byte(output.stdout.String()), &images) if err != nil { - return nil, errors.Wrap(err, "failed to parse image info") + return nil, fmt.Errorf("failed to parse image info: %w", err) } for i, image := range images { @@ -332,7 +331,7 @@ func (sf *shellFrontend) ImageTag(ctx context.Context, tags ...ImageTag) error { for _, tag := range tags { _, cmdErr := sf.commandContextOutput(ctx, "tag", tag.SourceRef, tag.TargetRef) if cmdErr != nil { - err = multierror.Append(err, cmdErr) + err = errors.Join(err, cmdErr) } } @@ -368,7 +367,7 @@ func (sf *shellFrontend) commandContextOutput(ctx context.Context, args ...strin err := cmd.Run() if err != nil { format := "command failed: %s %s: %s: %s" - return output, errors.Wrapf(err, format, sf.binaryName, strings.Join(args, " "), err.Error(), output.string()) + return output, fmt.Errorf(format+": %w", sf.binaryName, strings.Join(args, " "), err.Error(), output.string(), err) } return output, nil @@ -384,7 +383,7 @@ func (sf *shellFrontend) setupAndValidateAddresses(feType string, cfg *FrontendC calculatedBuildkitHost, err = DefaultAddressForSetting(feType, cfg.LocalContainerName, cfg.DefaultPort) if err != nil { - return nil, errors.Wrap(err, "could not validate default address") + return nil, fmt.Errorf("could not validate default address: %w", err) } } } diff --git a/util/containerutil/stub.go b/util/containerutil/stub.go index 51762c422a..4d0e7de48f 100644 --- a/util/containerutil/stub.go +++ b/util/containerutil/stub.go @@ -2,9 +2,9 @@ package containerutil import ( "context" + "errors" + "fmt" "io" - - "github.com/pkg/errors" ) // This is a stub for use when a proper frontend is not available. @@ -27,7 +27,7 @@ func NewStubFrontend(cfg *FrontendConfig) (ContainerFrontend, error) { fe.urls, err = fe.setupAndValidateAddresses(FrontendStub, cfg) if err != nil { - return nil, errors.Wrap(err, "failed to calculate buildkit URLs") + return nil, fmt.Errorf("failed to calculate buildkit URLs: %w", err) } return fe, nil diff --git a/util/containerutil/types.go b/util/containerutil/types.go index 91b21963be..0fc84a9c33 100644 --- a/util/containerutil/types.go +++ b/util/containerutil/types.go @@ -1,10 +1,9 @@ package containerutil import ( + "errors" "net/url" "time" - - "github.com/pkg/errors" ) // ContainerInfo contains things we may care about from inspect output for a given container. @@ -205,7 +204,7 @@ const ( ) var ( - errURLParseFailure = errors.New("Invalid URL") + errURLParseFailure = errors.New("invalid URL") errURLValidationFailure = errors.New("URL did not pass validation") ) diff --git a/util/dockerutil/docker.go b/util/dockerutil/docker.go index 45171d88c5..c7d71c15e9 100644 --- a/util/dockerutil/docker.go +++ b/util/dockerutil/docker.go @@ -11,8 +11,6 @@ import ( "github.com/EarthBuild/earthbuild/util/containerutil" "github.com/EarthBuild/earthbuild/util/platutil" "golang.org/x/sync/errgroup" - - "github.com/pkg/errors" ) // Manifest contains docker manifest data. @@ -31,7 +29,7 @@ func LoadDockerManifest( platr *platutil.Resolver, ) error { if len(children) == 0 { - return errors.Errorf("no images in manifest list for %s", parentImageName) + return fmt.Errorf("no images in manifest list for %s", parentImageName) } // Check if any child has the platform as the default platform defaultChild := 0 @@ -50,7 +48,8 @@ func LoadDockerManifest( // fall back to using first defined platform (and display a warning) console.Warnf( "Failed to find default platform (%s) of multi-platform image %s; defaulting to the first platform type: %s\n", - platr.Materialize(platutil.DefaultPlatform).String(), parentImageName, children[defaultChild].Platform) + platr.Materialize(platutil.DefaultPlatform).String(), parentImageName, children[defaultChild].Platform, + ) } var childImgs []string @@ -68,14 +67,15 @@ func LoadDockerManifest( "Separate per-platform image tags are only available locally." console.Printf( "Image %s is a multi-platform image. The following per-platform images have been produced:\n\t%s\n%s\n", - parentImageName, strings.Join(childImgs, "\n\t"), noteDetail) + parentImageName, strings.Join(childImgs, "\n\t"), noteDetail, + ) err := fe.ImageTag(ctx, containerutil.ImageTag{ SourceRef: children[defaultChild].ImageName, TargetRef: parentImageName, }) if err != nil { - return errors.Wrap(err, "docker tag default platform image") + return fmt.Errorf("docker tag default platform image: %w", err) } return nil @@ -85,7 +85,7 @@ func LoadDockerManifest( func LoadDockerTar(ctx context.Context, fe containerutil.ContainerFrontend, r io.ReadCloser) error { err := fe.ImageLoad(ctx, r) if err != nil { - return errors.Wrapf(err, "load tar") + return fmt.Errorf("load tar: %w", err) } return nil @@ -119,7 +119,7 @@ func dockerPullLocalImage( err := fe.ImagePull(ctx, fullPullName) if err != nil { - return errors.Wrap(err, "image pull") + return fmt.Errorf("image pull: %w", err) } // Fix for #2471 where Podman pulls seem exit before the image is available @@ -134,14 +134,14 @@ func dockerPullLocalImage( TargetRef: finalName, }) if err != nil { - return errors.Wrap(err, "image tag after pull") + return fmt.Errorf("image tag after pull: %w", err) } force := true // Sometimes Docker GCs images automatically (force prevents an error). err = fe.ImageRemove(ctx, force, fullPullName) if err != nil { - return errors.Wrap(err, "image rmi after pull and retag") + return fmt.Errorf("image rmi after pull and retag: %w", err) } return nil diff --git a/util/fileutil/fileutil.go b/util/fileutil/fileutil.go index 82392ad735..21f9b81822 100644 --- a/util/fileutil/fileutil.go +++ b/util/fileutil/fileutil.go @@ -3,13 +3,12 @@ package fileutil import ( + "fmt" "io/fs" "os" "os/user" "path/filepath" "strconv" - - "github.com/pkg/errors" ) // FileExists returns true if the file exists. @@ -20,7 +19,7 @@ func FileExists(filename string) (bool, error) { return false, nil } - return false, errors.Wrapf(err, "unable to stat %s", filename) + return false, fmt.Errorf("unable to stat %s: %w", filename, err) } return !info.IsDir(), nil @@ -40,7 +39,7 @@ func DirExists(filename string) (bool, error) { return false, nil } - return false, errors.Wrapf(err, "unable to stat %s", filename) + return false, fmt.Errorf("unable to stat %s: %w", filename, err) } return info.IsDir(), nil @@ -57,7 +56,7 @@ func DirExistsBestEffort(filename string) bool { func EnsureUserOwned(dir string, owner *user.User) error { uid, err := strconv.Atoi(owner.Uid) if err != nil { - return errors.Wrapf(err, "convert uid %s to int", owner.Uid) + return fmt.Errorf("convert uid %s to int: %w", owner.Uid, err) } gid := 0 @@ -68,7 +67,7 @@ func EnsureUserOwned(dir string, owner *user.User) error { root, err := os.OpenRoot(dir) if err != nil { - return errors.Wrapf(err, "open root %s", dir) + return fmt.Errorf("open root %s: %w", dir, err) } defer root.Close() @@ -79,7 +78,7 @@ func EnsureUserOwned(dir string, owner *user.User) error { rel, err := filepath.Rel(dir, path) if err != nil { - return errors.Wrapf(err, "get relative path for %s to %s", path, dir) + return fmt.Errorf("get relative path for %s to %s: %w", path, dir, err) } return root.Chown(rel, uid, gid) @@ -91,14 +90,14 @@ func EnsureUserOwned(dir string, owner *user.User) error { func GlobDirs(pattern string) ([]string, error) { matches, err := filepath.Glob(pattern) if err != nil { - return nil, errors.Wrapf(err, "failed to expand glob path %q", pattern) + return nil, fmt.Errorf("failed to expand glob path %q: %w", pattern, err) } ret := make([]string, 0, len(matches)) for _, match := range matches { st, err := os.Stat(match) if err != nil { - return nil, errors.Wrapf(err, "failed to stat expanded path %q", match) + return nil, fmt.Errorf("failed to stat expanded path %q: %w", match, err) } if !st.IsDir() { diff --git a/util/fileutil/homedirs.go b/util/fileutil/homedirs.go index f2c3851161..9c1c975be6 100644 --- a/util/fileutil/homedirs.go +++ b/util/fileutil/homedirs.go @@ -2,6 +2,7 @@ package fileutil import ( "bufio" + "fmt" "io" "os" "os/user" @@ -9,8 +10,6 @@ import ( "path/filepath" "runtime" "strings" - - "github.com/pkg/errors" ) // GetUserHomeDirs returns a map of all users and their homedirs. @@ -20,14 +19,14 @@ func GetUserHomeDirs() (map[string]string, error) { if runtime.GOOS == "darwin" { currentUser, err := user.Current() if err != nil { - return nil, errors.Wrap(err, "failed to get current user") + return nil, fmt.Errorf("failed to get current user: %w", err) } home := filepath.Dir(currentUser.HomeDir) directoryList, err := os.ReadDir(home) if err != nil { - return nil, errors.Wrap(err, "failed to read dir") + return nil, fmt.Errorf("failed to read dir: %w", err) } for _, s := range directoryList { @@ -48,7 +47,7 @@ func GetUserHomeDirs() (map[string]string, error) { fp, err := os.Open("/etc/passwd") if err != nil { - return nil, errors.Wrap(err, "failed to open /etc/passwd") + return nil, fmt.Errorf("failed to open /etc/passwd: %w", err) } reader := bufio.NewReader(fp) @@ -59,7 +58,7 @@ func GetUserHomeDirs() (map[string]string, error) { break } - return nil, errors.Wrap(err, "failed to read line") + return nil, fmt.Errorf("failed to read line: %w", err) } line = strings.TrimSpace(line) diff --git a/util/fileutil/iswritable_other.go b/util/fileutil/iswritable_other.go index 954643db82..cf1c523fe4 100644 --- a/util/fileutil/iswritable_other.go +++ b/util/fileutil/iswritable_other.go @@ -3,12 +3,11 @@ package fileutil import ( + "fmt" "os" "os/user" "strconv" "syscall" - - "github.com/pkg/errors" ) // IsDirWritable returns if the path is a directory that the user can write to. @@ -41,7 +40,7 @@ func IsDirWritable(path string) (bool, error) { uid, err := strconv.Atoi(u.Uid) if err != nil { - return false, errors.Wrapf(err, "failed to convert uid %s to int", u.Uid) + return false, fmt.Errorf("failed to convert uid %s to int: %w", u.Uid, err) } if int(stat.Uid) != uid && uid != 0 { diff --git a/util/flagutil/matrix.go b/util/flagutil/matrix.go index 3bf8ef3185..67e87e5bf0 100644 --- a/util/flagutil/matrix.go +++ b/util/flagutil/matrix.go @@ -3,8 +3,6 @@ package flagutil import ( "fmt" "strings" - - "github.com/pkg/errors" ) type argGroup struct { @@ -75,7 +73,7 @@ func parseKeyValue(arg string) (string, *string, error) { splitArg := strings.SplitN(arg, "=", 2) if len(splitArg) < 1 { - return "", nil, errors.Errorf("invalid build arg %s", splitArg) + return "", nil, fmt.Errorf("invalid build arg %s", splitArg) } name = splitArg[0] diff --git a/util/flagutil/parse.go b/util/flagutil/parse.go index c92703364e..bff3d98354 100644 --- a/util/flagutil/parse.go +++ b/util/flagutil/parse.go @@ -1,6 +1,8 @@ package flagutil import ( + "errors" + "fmt" "os" "reflect" "strings" @@ -9,7 +11,6 @@ import ( "github.com/EarthBuild/earthbuild/internal/earthfile" "github.com/EarthBuild/earthbuild/util/stringutil" "github.com/jessevdk/go-flags" - "github.com/pkg/errors" ) // ArgumentModFunc accepts a flagName which corresponds to the long flag name, and a pointer @@ -76,7 +77,7 @@ func ParseArgsWithValueModifierAndOptions( _, err := p.AddGroup(command+" [options] args", "", data) if err != nil { - return nil, errors.Wrapf(err, "failed to initiate parser.AddGroup for %s", command) + return nil, fmt.Errorf("failed to initiate parser.AddGroup for %s: %w", command, err) } res, err := p.ParseArgs(args) diff --git a/util/flagutil/remote_cache.go b/util/flagutil/remote_cache.go index c42aeb154f..a7f8ff2161 100644 --- a/util/flagutil/remote_cache.go +++ b/util/flagutil/remote_cache.go @@ -1,9 +1,8 @@ package flagutil import ( + "fmt" "strings" - - "github.com/pkg/errors" ) // ParseImageNameAndAttrs parses the image name and returns its registry attributes. @@ -17,8 +16,9 @@ func ParseImageNameAndAttrs(s string) (string, map[string]string, error) { for _, entry := range entries[1:] { pair := strings.Split(strings.TrimSpace(entry), "=") if len(pair) != 2 { - return "", attrs, errors.Errorf( - "failed to parse remote cache attribute: expected a key=value pair while parsing %q", entry) + return "", attrs, fmt.Errorf( + "failed to parse remote cache attribute: expected a key=value pair while parsing %q", entry, + ) } attrs[strings.TrimSpace(pair[0])] = strings.TrimSpace(pair[1]) diff --git a/util/gatewaycrafter/gatewaycrafter.go b/util/gatewaycrafter/gatewaycrafter.go index d5604df4c8..32229f1892 100644 --- a/util/gatewaycrafter/gatewaycrafter.go +++ b/util/gatewaycrafter/gatewaycrafter.go @@ -4,6 +4,7 @@ package gatewaycrafter import ( "encoding/json" + "fmt" "strconv" "github.com/EarthBuild/earthbuild/states/image" @@ -11,7 +12,6 @@ import ( "github.com/moby/buildkit/exporter/containerimage/exptypes" gwclient "github.com/moby/buildkit/frontend/gateway/client" - "github.com/pkg/errors" ) // NewGatewayCrafter creates a new GatewayCrafter designed to be used to populate ref @@ -42,7 +42,7 @@ func (gc *GatewayCrafter) AddPushImageEntry( ) (string, error) { config, err := json.Marshal(imageConfig) if err != nil { - return "", errors.Wrapf(err, "marshal save image config") + return "", fmt.Errorf("marshal save image config: %w", err) } refKey := "image-" + strconv.Itoa(refID) diff --git a/util/gitutil/detectgit.go b/util/gitutil/detectgit.go index 832396756d..ff552187fb 100644 --- a/util/gitutil/detectgit.go +++ b/util/gitutil/detectgit.go @@ -2,6 +2,8 @@ package gitutil import ( "context" + "errors" + "fmt" "os" "os/exec" "path" @@ -10,28 +12,27 @@ import ( "strings" "github.com/EarthBuild/earthbuild/domain" - "github.com/pkg/errors" ) var ( // ErrNoGitBinary is an error returned when no git binary is found. - ErrNoGitBinary = errors.New("No git binary found") + ErrNoGitBinary = errors.New("no git binary found") // ErrNotAGitDir is an error returned when a given directory is not a git dir. - ErrNotAGitDir = errors.New("Not a git directory") + ErrNotAGitDir = errors.New("not a git directory") // ErrCouldNotDetectRemote is an error returned when git remote could not be detected or parsed. - ErrCouldNotDetectRemote = errors.New("Could not auto-detect or parse Git remote URL") + ErrCouldNotDetectRemote = errors.New("could not auto-detect or parse Git remote URL") // ErrCouldNotDetectGitHash is an error returned when git hash could not be detected. - ErrCouldNotDetectGitHash = errors.New("Could not auto-detect or parse Git hash") + ErrCouldNotDetectGitHash = errors.New("could not auto-detect or parse Git hash") // ErrCouldNotDetectGitShortHash is an error returned when git short hash could not be detected. - ErrCouldNotDetectGitShortHash = errors.New("Could not auto-detect or parse Git short hash") + ErrCouldNotDetectGitShortHash = errors.New("could not auto-detect or parse Git short hash") // ErrCouldNotDetectGitContentHash is an error returned when git tree hash could not be detected. - ErrCouldNotDetectGitContentHash = errors.New("Could not auto-detect or parse Git content hash") + ErrCouldNotDetectGitContentHash = errors.New("could not auto-detect or parse Git content hash") // ErrCouldNotDetectGitBranch is an error returned when git branch could not be detected. - ErrCouldNotDetectGitBranch = errors.New("Could not auto-detect or parse Git branch") + ErrCouldNotDetectGitBranch = errors.New("could not auto-detect or parse Git branch") // ErrCouldNotDetectGitTags is an error returned when git tags could not be detected. - ErrCouldNotDetectGitTags = errors.New("Could not auto-detect or parse Git tags") + ErrCouldNotDetectGitTags = errors.New("could not auto-detect or parse Git tags") // ErrCouldNotDetectGitRefs is an error returned when git refs could not be detected. - ErrCouldNotDetectGitRefs = errors.New("Could not auto-detect or parse Git refs") + ErrCouldNotDetectGitRefs = errors.New("could not auto-detect or parse Git refs") ) // GitMetadata is a collection of git information about a certain directory. @@ -155,7 +156,7 @@ func Metadata(ctx context.Context, dir, gitBranchOverride string) (*GitMetadata, relDir, isRel, err := gitRelDir(baseDir, dir) if err != nil { - return nil, errors.Wrapf(err, "get rel dir for %s when base git path is %s", dir, baseDir) + return nil, fmt.Errorf("get rel dir for %s when base git path is %s: %w", dir, baseDir, err) } if !isRel { @@ -245,13 +246,12 @@ func detectGitRemoteURL(ctx context.Context, dir string) (string, error) { out, err := cmd.Output() if err != nil { - return "", errors.Wrapf( - ErrCouldNotDetectRemote, "returned error %s: %s", err.Error(), string(out)) + return "", fmt.Errorf("returned error %s: %s: %w", err.Error(), string(out), ErrCouldNotDetectRemote) } outStr := string(out) if outStr == "" { - return "", errors.Wrapf(ErrCouldNotDetectRemote, "no remote origin url output") + return "", fmt.Errorf("no remote origin url output: %w", ErrCouldNotDetectRemote) } return strings.SplitN(outStr, "\n", 2)[0], nil @@ -263,7 +263,7 @@ func detectGitBaseDir(ctx context.Context, dir string) (string, error) { out, err := cmd.Output() if err != nil { - return "", errors.Wrap(err, "detect git directory") + return "", fmt.Errorf("detect git directory: %w", err) } outStr := string(out) @@ -271,7 +271,7 @@ func detectGitBaseDir(ctx context.Context, dir string) (string, error) { // E.g. This would convert `C:/my/path` to `C:\my\path`, but only when the platform is Windows. outStr = strings.Join(strings.Split(outStr, "/"), string(filepath.Separator)) if outStr == "" { - return "", errors.New("No output returned for git base dir") + return "", errors.New("no output returned for git base dir") } return strings.SplitN(outStr, "\n", 2)[0], nil @@ -284,12 +284,12 @@ func gitRevParse(ctx context.Context, dir string, sentinel error, args ...string out, err := cmd.Output() if err != nil { - return "", errors.Wrapf(sentinel, "returned error %s: %s", err.Error(), string(out)) + return "", fmt.Errorf("returned error %s: %s: %w", err.Error(), string(out), sentinel) } outStr := string(out) if outStr == "" { - return "", errors.Wrapf(sentinel, "no output") + return "", fmt.Errorf("no output: %w", sentinel) } return strings.SplitN(outStr, "\n", 2)[0], nil @@ -317,7 +317,7 @@ func detectGitBranch(ctx context.Context, dir, gitBranchOverride string) ([]stri out, err := cmd.Output() if err != nil { - return nil, errors.Wrapf(ErrCouldNotDetectGitBranch, "returned error %s: %s", err.Error(), string(out)) + return nil, fmt.Errorf("returned error %s: %s: %w", err.Error(), string(out), ErrCouldNotDetectGitBranch) } outStr := string(out) @@ -334,7 +334,7 @@ func detectGitTags(ctx context.Context, dir string) ([]string, error) { out, err := cmd.Output() if err != nil { - return nil, errors.Wrapf(ErrCouldNotDetectGitTags, "returned error %s: %s", err.Error(), string(out)) + return nil, fmt.Errorf("returned error %s: %s: %w", err.Error(), string(out), ErrCouldNotDetectGitTags) } outStr := string(out) @@ -351,7 +351,7 @@ func detectGitRefs(ctx context.Context, dir string) ([]string, error) { out, err := cmd.Output() if err != nil { - return nil, errors.Wrapf(ErrCouldNotDetectGitRefs, "returned error %s: %s", err.Error(), string(out)) + return nil, fmt.Errorf("returned error %s: %s: %w", err.Error(), string(out), ErrCouldNotDetectGitRefs) } outStr := string(out) @@ -399,7 +399,7 @@ func detectGitTimestamp(ctx context.Context, dir string, tsType gitTimestampType return "", nil } - return "", errors.Wrap(err, "detect git timestamp") + return "", fmt.Errorf("detect git timestamp: %w", err) } outStr := string(out) @@ -422,7 +422,7 @@ func detectGitAuthor(ctx context.Context, dir string, format string) (string, er return "", nil } - return "", errors.Wrap(err, "detect git author") + return "", fmt.Errorf("detect git author: %w", err) } outStr := string(out) @@ -440,7 +440,7 @@ func ConfigEmail(ctx context.Context) (string, error) { out, err := cmd.Output() if err != nil { - return "", errors.Wrap(err, "detect git global email") + return "", fmt.Errorf("detect git global email: %w", err) } return strings.TrimSpace(string(out)), nil @@ -462,7 +462,7 @@ func detectGitCoAuthors(ctx context.Context, dir string) ([]string, error) { return nil, nil } - return nil, errors.Wrap(err, "detect git co-authors") + return nil, fmt.Errorf("detect git co-authors: %w", err) } return ParseCoAuthorsFromBody(string(out)), nil @@ -505,17 +505,17 @@ func ParseCoAuthorsFromBody(body string) []string { // This function validates the input data (basePath, path) as well. func gitRelDir(basePath string, path string) (string, bool, error) { if !filepath.IsAbs(basePath) { - return "", false, errors.Errorf("git base path %s is not absolute", basePath) + return "", false, fmt.Errorf("git base path %s is not absolute", basePath) } absPath, err := filepath.Abs(path) if err != nil { - return "", false, errors.Wrapf(err, "get abs path for %s", path) + return "", false, fmt.Errorf("get abs path for %s: %w", path, err) } absPath2, err := filepath.EvalSymlinks(absPath) if err != nil { - return "", false, errors.Wrapf(err, "eval symlinks for %s", absPath) + return "", false, fmt.Errorf("eval symlinks for %s: %w", absPath, err) } basePathParts := strings.Split(basePath, string(filepath.Separator)) @@ -529,7 +529,7 @@ func gitRelDir(basePath string, path string) (string, bool, error) { a, err := os.Stat(basePath) if err != nil { - return "", false, errors.Wrapf(err, "stat for %s", basePath) + return "", false, fmt.Errorf("stat for %s: %w", basePath, err) } // Checking VolumeName determines if we have a fully-qualified Windows path like `C:\my\dir`. @@ -545,7 +545,7 @@ func gitRelDir(basePath string, path string) (string, bool, error) { b, err := os.Stat(filepath.Join(pathParts[:len(basePathParts)]...)) if err != nil { - return "", false, errors.Wrapf(err, "stat for %v", pathParts) + return "", false, fmt.Errorf("stat for %v: %w", pathParts, err) } // Here checks if `path` is included in `basePath` in filesystem agnostic way. // Case-sensitivity difference (like HFS+ in OSX) is also covered by os.SameFile. diff --git a/util/llbutil/authprovider/helheim_mocks_test.go b/util/llbutil/authprovider/helheim_mocks_test.go index bab2baa502..7a72b56f58 100644 --- a/util/llbutil/authprovider/helheim_mocks_test.go +++ b/util/llbutil/authprovider/helheim_mocks_test.go @@ -9,11 +9,12 @@ package authprovider_test import ( "context" + "io" + "time" + "git.sr.ht/~nelsam/hel/pkg/pers" "git.sr.ht/~nelsam/hel/vegr" "github.com/moby/buildkit/session/auth" - "io" - "time" ) var ( diff --git a/util/llbutil/authprovider/podman.go b/util/llbutil/authprovider/podman.go index 634a9da1b6..c68efb1de0 100644 --- a/util/llbutil/authprovider/podman.go +++ b/util/llbutil/authprovider/podman.go @@ -2,6 +2,7 @@ package authprovider import ( "context" + "errors" "fmt" "io" "io/fs" @@ -14,7 +15,6 @@ import ( "github.com/docker/cli/cli/config/configfile" "github.com/moby/buildkit/session" "github.com/moby/buildkit/session/auth/authprovider" - "github.com/pkg/errors" ) const ( @@ -129,14 +129,14 @@ func podmanAuth(o OS, path string) (*configfile.ConfigFile, error) { cfg := configfile.New(path) if err != nil { - return cfg, errors.Wrap(err, path) + return cfg, fmt.Errorf("%s: %w", path, err) } defer f.Close() err = cfg.LoadFromReader(f) if err != nil { - return cfg, errors.Wrap(err, path) + return cfg, fmt.Errorf("%s: %w", path, err) } return cfg, nil diff --git a/util/llbutil/copyop.go b/util/llbutil/copyop.go index f436d16089..9d8ceb710e 100644 --- a/util/llbutil/copyop.go +++ b/util/llbutil/copyop.go @@ -12,7 +12,6 @@ import ( "github.com/EarthBuild/earthbuild/util/llbutil/pllb" "github.com/EarthBuild/earthbuild/util/platutil" "github.com/moby/buildkit/client/llb" - "github.com/pkg/errors" ) // CopyOp is a simplified llb copy operation. @@ -127,7 +126,7 @@ func Abs(ctx context.Context, s pllb.State, p string) (string, error) { dir, err := s.GetDir(ctx) if err != nil { - return "", errors.Wrap(err, "get dir") + return "", fmt.Errorf("get dir: %w", err) } return path.Join(dir, p), nil diff --git a/util/llbutil/platform_name.go b/util/llbutil/platform_name.go index 9842b5924a..3fdab12ead 100644 --- a/util/llbutil/platform_name.go +++ b/util/llbutil/platform_name.go @@ -5,7 +5,6 @@ import ( "github.com/EarthBuild/earthbuild/util/platutil" "github.com/distribution/reference" - "github.com/pkg/errors" ) // PlatformSpecificImageName returns the PlatformSpecificImageName. @@ -17,19 +16,19 @@ func PlatformSpecificImageName(imgName string, platform platutil.Platform) (stri r, err := reference.ParseNormalizedNamed(imgName) if err != nil { - return "", errors.Wrapf(err, "parse %s", imgName) + return "", fmt.Errorf("parse %s: %w", imgName, err) } taggedR, ok := reference.TagNameOnly(r).(reference.Tagged) if !ok { - return "", errors.Wrapf(err, "not tagged %s", reference.TagNameOnly(r).String()) + return "", fmt.Errorf("not tagged %s: %w", reference.TagNameOnly(r).String(), err) } platformTag := DockerTagSafe(fmt.Sprintf("%s_%s", taggedR.Tag(), platformStr)) r2, err := reference.WithTag(r, platformTag) if err != nil { - return "", errors.Wrapf(err, "with tag %s - %s", r.String(), platformTag) + return "", fmt.Errorf("with tag %s - %s: %w", r.String(), platformTag, err) } return reference.FamiliarString(r2), nil diff --git a/util/llbutil/secretprovider/aws_creds.go b/util/llbutil/secretprovider/aws_creds.go index 82eee1729c..9a64231212 100644 --- a/util/llbutil/secretprovider/aws_creds.go +++ b/util/llbutil/secretprovider/aws_creds.go @@ -2,6 +2,7 @@ package secretprovider import ( "context" + "fmt" "net/url" "strings" @@ -9,7 +10,7 @@ import ( "github.com/aws/aws-sdk-go-v2/config" "github.com/moby/buildkit/session/secrets" "github.com/moby/buildkit/util/grpcerrors" - "github.com/pkg/errors" + "google.golang.org/grpc/codes" "github.com/EarthBuild/earthbuild/util/hint" @@ -66,7 +67,7 @@ func NewAWSCredentialProvider() *AWSCredentialProvider { func (c *AWSCredentialProvider) GetSecret(ctx context.Context, name string) ([]byte, error) { q, err := url.ParseQuery(name) if err != nil { - return nil, errors.Wrap(err, "failed to parse secret info") + return nil, fmt.Errorf("failed to parse secret info: %w", err) } secretName := q.Get("name") @@ -100,13 +101,13 @@ func (c *AWSCredentialProvider) GetSecret(ctx context.Context, name string) ([]b case awsRegion: val = cfg.Region default: - return nil, errors.Errorf("unexpected secret: %s", secretName) + return nil, fmt.Errorf("unexpected secret: %s", secretName) } if val == "" && secretName != awsRegion { // the region may be provided by a separate arg/env if it's not provided in the local env or oidc configuration // Use a custom error here as not to fall back on other secret providers. - return nil, errors.Errorf("AWS setting %s not found in environment", secretName) + return nil, fmt.Errorf("AWS setting %s not found in environment", secretName) } return []byte(val), nil @@ -119,7 +120,7 @@ func getCFG(ctx context.Context) (aws.Config, error) { // Note: results of this call are cached. cfg, err := config.LoadDefaultConfig(ctx, config.WithDefaultsMode(aws.DefaultsModeStandard)) if err != nil { - return aws.Config{}, errors.Wrap(err, "failed to load AWS config") + return aws.Config{}, fmt.Errorf("failed to load AWS config: %w", err) } return cfg, nil @@ -150,5 +151,5 @@ func handleError(err error, region string) error { } } - return errors.Wrap(err, "failed to load AWS credentials") + return fmt.Errorf("failed to load AWS credentials: %w", err) } diff --git a/util/llbutil/secretprovider/secrets.go b/util/llbutil/secretprovider/secrets.go index f65c20f8d4..9357a34a4d 100644 --- a/util/llbutil/secretprovider/secrets.go +++ b/util/llbutil/secretprovider/secrets.go @@ -2,12 +2,14 @@ package secretprovider import ( "context" + "errors" + "fmt" "net/url" "github.com/EarthBuild/earthbuild/util/hint" "github.com/moby/buildkit/session" "github.com/moby/buildkit/session/secrets" - "github.com/pkg/errors" + "google.golang.org/grpc" ) @@ -47,7 +49,7 @@ func (sp *secretProvider) GetSecret( }, nil } - return nil, hint.Wrap(errors.WithStack(errors.Wrapf(secrets.ErrNotFound, "unable to lookup secret %q", v.Get("name"))), + return nil, hint.Wrap(fmt.Errorf("unable to lookup secret %q: %w", v.Get("name"), secrets.ErrNotFound), "Make sure to set the project at the top of the Earthfile by using the PROJECT command.", "Note, if this secret was called from a FUNCTION, "+ "the project needs to be set in the Earthfile that calls the FUNCTION.") diff --git a/util/llbutil/statetoref.go b/util/llbutil/statetoref.go index 7b556a5f78..782bbde6e3 100644 --- a/util/llbutil/statetoref.go +++ b/util/llbutil/statetoref.go @@ -2,12 +2,12 @@ package llbutil import ( "context" + "fmt" "github.com/EarthBuild/earthbuild/util/llbutil/pllb" "github.com/EarthBuild/earthbuild/util/platutil" "github.com/moby/buildkit/client/llb" gwclient "github.com/moby/buildkit/frontend/gateway/client" - "github.com/pkg/errors" ) // StateToRef takes an LLB state, solves it using gateway and returns the ref. @@ -36,7 +36,7 @@ func StateToRef( def, err := state.Marshal(ctx, llb.Platform(platr.ToLLBPlatform(platform))) if err != nil { - return nil, errors.Wrap(err, "marshal state") + return nil, fmt.Errorf("marshal state: %w", err) } r, err := gwClient.Solve(ctx, gwclient.SolveRequest{ @@ -44,12 +44,12 @@ func StateToRef( CacheImports: coes, }) if err != nil { - return nil, errors.Wrap(err, "solve state") + return nil, fmt.Errorf("solve state: %w", err) } ref, err := r.SingleRef() if err != nil { - return nil, errors.Wrap(err, "single ref") + return nil, fmt.Errorf("single ref: %w", err) } return ref, nil diff --git a/util/params/paramerror.go b/util/params/paramerror.go index c3c51bdebe..2fbd093f85 100644 --- a/util/params/paramerror.go +++ b/util/params/paramerror.go @@ -2,8 +2,6 @@ package params import ( "fmt" - - "github.com/pkg/errors" ) // Error represents an error with an associated parent error and cause. @@ -36,9 +34,9 @@ func (e *Error) Error() string { return e.msg } -// Cause returns the underlying error. -func (e *Error) Cause() error { - return errors.Cause(e.cause) +// Unwrap returns the underlying error. +func (e *Error) Unwrap() error { + return e.cause } // Is checks if the err is an Error. diff --git a/util/params/paramerror_test.go b/util/params/paramerror_test.go index 07ed4b8db9..9a8fad2576 100644 --- a/util/params/paramerror_test.go +++ b/util/params/paramerror_test.go @@ -1,10 +1,11 @@ package params import ( + "errors" "testing" - "github.com/pkg/errors" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) var errInternal = errors.New("internal") @@ -23,9 +24,9 @@ func TestErrorf(t *testing.T) { t.Run("with args", func(t *testing.T) { t.Parallel() - res := Errorf("some error %s", "myarg") + res := Errorf("some error %d", 1) assert.Equal(t, &Error{ - msg: "some error myarg", + msg: "some error 1", }, res) }) } @@ -45,9 +46,9 @@ func TestWrapf(t *testing.T) { t.Run("with args", func(t *testing.T) { t.Parallel() - res := Wrapf(errInternal, "some error %s", "myarg") + res := Wrapf(errInternal, "some error %d", 1) assert.Equal(t, &Error{ - msg: "some error myarg", + msg: "some error 1", cause: errInternal, }, res) }) @@ -70,16 +71,6 @@ func TestError(t *testing.T) { }) } -func TestCause(t *testing.T) { - t.Parallel() - - var err *Error - - assert.True(t, errors.As(Wrapf(errInternal, "some error"), &err)) - res := err.Cause() - assert.Equal(t, errors.Cause(errInternal), res) -} - func TestIs(t *testing.T) { t.Parallel() @@ -88,7 +79,7 @@ func TestIs(t *testing.T) { var err *Error - assert.True(t, errors.As(Errorf("some error"), &err)) + require.ErrorAs(t, Errorf("some error"), &err) res := err.Is(errInternal) assert.False(t, res) }) @@ -98,7 +89,7 @@ func TestIs(t *testing.T) { var err *Error - assert.True(t, errors.As(Errorf("some error"), &err)) + require.ErrorAs(t, Errorf("some error"), &err) res := err.Is(err) assert.True(t, res) }) @@ -109,7 +100,7 @@ func TestParentError(t *testing.T) { var err *Error - assert.True(t, errors.As(Wrapf(errInternal, "some error"), &err)) + require.ErrorAs(t, Wrapf(errInternal, "some error"), &err) res := err.ParentError() assert.Equal(t, "some error", res) } diff --git a/util/platutil/native.go b/util/platutil/native.go index 3acceead57..fae20fc405 100644 --- a/util/platutil/native.go +++ b/util/platutil/native.go @@ -2,12 +2,13 @@ package platutil import ( "context" + "errors" + "fmt" "github.com/containerd/platforms" "github.com/moby/buildkit/client" gwclient "github.com/moby/buildkit/frontend/gateway/client" specs "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" ) // GetNativePlatform returns the native platform for a given gwClient. @@ -29,7 +30,7 @@ func GetNativePlatform(gwClient gwclient.Client) (specs.Platform, error) { func GetNativePlatformViaBkClient(ctx context.Context, bkClient *client.Client) (specs.Platform, error) { ws, err := bkClient.ListWorkers(ctx) if err != nil { - return specs.Platform{}, errors.Wrap(err, "failed to list workers") + return specs.Platform{}, fmt.Errorf("failed to list workers: %w", err) } if len(ws) == 0 { diff --git a/util/proj/golang.go b/util/proj/golang.go index ddf563d4d6..e4f354b7b0 100644 --- a/util/proj/golang.go +++ b/util/proj/golang.go @@ -2,6 +2,8 @@ package proj import ( "context" + "errors" + "fmt" "io" "io/fs" "path/filepath" @@ -9,7 +11,6 @@ import ( "text/template" "github.com/EarthBuild/earthbuild/util/hint" - "github.com/pkg/errors" ) const ( @@ -152,29 +153,29 @@ func (g *Golang) Type(context.Context) string { func (g *Golang) ForDir(ctx context.Context, dir string) (Project, error) { _, err := fs.Stat(g.fs, filepath.Join(dir, goMod)) if errors.Is(err, fs.ErrNotExist) { - return nil, errors.Wrap(ErrSkip, "no go.mod found") + return nil, fmt.Errorf("no go.mod found: %w", ErrSkip) } if err != nil { - return nil, errors.Wrap(err, "error reading go.mod") + return nil, fmt.Errorf("error reading go.mod: %w", err) } out, _, err := g.execer.Command("go", "list", "-f", "{{.Dir}}").Run(ctx) if errors.Is(err, fs.ErrNotExist) { return nil, hint.Wrap( - errors.Wrap(err, "go.mod and go.sum exist, but go is not installed"), + fmt.Errorf("go.mod and go.sum exist, but go is not installed: %w", err), "go must be installed for 'go list' so that earth can read information about your go project", ) } rootBytes, err := io.ReadAll(out) if err != nil { - return nil, errors.Wrap(err, "could not read go project root directory") + return nil, fmt.Errorf("could not read go project root directory: %w", err) } root, err := filepath.Abs(strings.TrimSpace(string(rootBytes))) if err != nil { - return nil, errors.Wrapf(err, "could not get absolute path for directory %q", string(rootBytes)) + return nil, fmt.Errorf("could not get absolute path for directory %q: %w", string(rootBytes), err) } return &Golang{ @@ -227,7 +228,7 @@ func (f *targetFormatter) Format(w io.Writer, indent string) error { tmpl, err := template.New("").Parse(t) if err != nil { - return errors.Wrap(err, "golang: failed to parse target template") + return fmt.Errorf("golang: failed to parse target template: %w", err) } type tmplCtx struct { @@ -237,7 +238,7 @@ func (f *targetFormatter) Format(w io.Writer, indent string) error { err = tmpl.Execute(w, tmplCtx{Prefix: f.prefix, Indent: indent}) if err != nil { - return errors.Wrap(err, "golang: failed to execute target template") + return fmt.Errorf("golang: failed to execute target template: %w", err) } return nil diff --git a/util/proj/golang_test.go b/util/proj/golang_test.go index 0baca8f695..a908b06400 100644 --- a/util/proj/golang_test.go +++ b/util/proj/golang_test.go @@ -3,13 +3,14 @@ package proj_test import ( "bytes" "context" + "errors" "io/fs" "testing" "time" "git.sr.ht/~nelsam/hel/pkg/pers" "github.com/EarthBuild/earthbuild/util/proj" - "github.com/pkg/errors" + "github.com/stretchr/testify/require" ) diff --git a/util/proj/helheim_mocks_test.go b/util/proj/helheim_mocks_test.go index b72bfe1d4c..abe211c9f9 100644 --- a/util/proj/helheim_mocks_test.go +++ b/util/proj/helheim_mocks_test.go @@ -9,12 +9,13 @@ package proj_test import ( "context" - "git.sr.ht/~nelsam/hel/pkg/pers" - "git.sr.ht/~nelsam/hel/vegr" - "github.com/EarthBuild/earthbuild/util/proj" "io" "io/fs" "time" + + "git.sr.ht/~nelsam/hel/pkg/pers" + "git.sr.ht/~nelsam/hel/vegr" + "github.com/EarthBuild/earthbuild/util/proj" ) var ( diff --git a/util/proj/proj.go b/util/proj/proj.go index 662ef9ab39..69f6023655 100644 --- a/util/proj/proj.go +++ b/util/proj/proj.go @@ -7,12 +7,12 @@ package proj import ( "bytes" "context" + "errors" + "fmt" "io" "io/fs" "os" "os/exec" - - "github.com/pkg/errors" ) // FS represents the type that proj types need to inspect files in the @@ -133,7 +133,7 @@ func All(ctx context.Context, dir string) ([]Project, error) { } if err != nil { - return nil, errors.Wrapf(err, "checking for project type %T failed", proj) + return nil, fmt.Errorf("checking for project type %T failed: %w", proj, err) } active = append(active, forDir) diff --git a/util/saveartifactlocally/saveartifactlocally.go b/util/saveartifactlocally/saveartifactlocally.go index 2f1e8fcc34..25b8a082eb 100644 --- a/util/saveartifactlocally/saveartifactlocally.go +++ b/util/saveartifactlocally/saveartifactlocally.go @@ -3,6 +3,8 @@ package saveartifactlocally import ( + "errors" + "fmt" "os" "path" "path/filepath" @@ -11,9 +13,7 @@ import ( "github.com/EarthBuild/earthbuild/conslogging" "github.com/EarthBuild/earthbuild/domain" "github.com/EarthBuild/earthbuild/util/gatewaycrafter" - reccopy "github.com/otiai10/copy" - "github.com/pkg/errors" ) // SaveArtifactLocally handles saving artifacts to the local host, and is called from both builder and waitblock. @@ -30,13 +30,13 @@ func SaveArtifactLocally( // while the pattern is also guest-platform dependent. fromGlobMatches, err := filepath.Glob(fromPattern) if err != nil { - return errors.Wrapf(err, "glob") + return fmt.Errorf("glob: %w", err) } else if !artifact.Target.IsRemote() && len(fromGlobMatches) == 0 { if ifExists { return nil } - return errors.Errorf("cannot save artifact %s, since it does not exist", artifact.StringCanonical()) + return fmt.Errorf("cannot save artifact %s, since it does not exist", artifact.StringCanonical()) } isWildcard := strings.ContainsAny(fromPattern, `*?[`) @@ -44,7 +44,7 @@ func SaveArtifactLocally( for _, from := range fromGlobMatches { fiSrc, err := os.Stat(from) if err != nil { - return errors.Wrapf(err, "os stat %s", from) + return fmt.Errorf("os stat %s: %w", from, err) } srcIsDir := fiSrc.IsDir() @@ -68,7 +68,8 @@ func SaveArtifactLocally( // Ignore err. Likely dest path does not exist. if isWildcard && !destIsDir { return errors.New( - "artifact is a wildcard, but AS LOCAL destination does not end with /") + "artifact is a wildcard, but AS LOCAL destination does not end with /", + ) } destIsDir = fiSrc.IsDir() @@ -80,18 +81,19 @@ func SaveArtifactLocally( switch { case !destIsDir && srcIsDir: return errors.New( - "artifact is a directory, but existing AS LOCAL destination is a file") + "artifact is a directory, but existing AS LOCAL destination is a file", + ) case destExists && srcIsDir: // Remove preexisting dest dir. err = os.RemoveAll(to) if err != nil { - return errors.Wrapf(err, "rm -rf %s", to) + return fmt.Errorf("rm -rf %s: %w", to, err) } case destExists && !srcIsDir: // Remove preexisting dest file. err = os.Remove(to) if err != nil { - return errors.Wrapf(err, "rm %s", to) + return fmt.Errorf("rm %s: %w", to, err) } } @@ -99,7 +101,7 @@ func SaveArtifactLocally( err = os.MkdirAll(toDir, 0o755) // #nosec G301 if err != nil { - return errors.Wrapf(err, "mkdir all for artifact %s", toDir) + return fmt.Errorf("mkdir all for artifact %s: %w", toDir, err) } err = os.Link(from, to) @@ -107,7 +109,7 @@ func SaveArtifactLocally( // Hard linking did not work. Try recursive copy. errCopy := reccopy.Copy(from, to) if errCopy != nil { - return errors.Wrapf(errCopy, "copy artifact %s", from) + return fmt.Errorf("copy artifact %s: %w", from, errCopy) } } diff --git a/util/semverutil/semverutil.go b/util/semverutil/semverutil.go index 16691d907f..d202cac08b 100644 --- a/util/semverutil/semverutil.go +++ b/util/semverutil/semverutil.go @@ -3,11 +3,10 @@ package semverutil import ( + "errors" "fmt" "io" "strings" - - "github.com/pkg/errors" ) // Version is a semantic version number. @@ -30,7 +29,7 @@ func Parse(s string) (Version, error) { } if err != nil { - return Version{}, errors.Wrap(err, "parsing semantic version") + return Version{}, fmt.Errorf("parsing semantic version: %w", err) } return v, nil diff --git a/util/shell/lex.go b/util/shell/lex.go index 1f1a66a10d..acfb702ff0 100644 --- a/util/shell/lex.go +++ b/util/shell/lex.go @@ -5,12 +5,11 @@ package shell import ( "bytes" + "errors" "fmt" "strings" "text/scanner" "unicode" - - "github.com/pkg/errors" ) // Lex performs shell word splitting and variable expansion. @@ -106,7 +105,7 @@ type shellWord struct { func (sw *shellWord) process(source string) (string, []string, error) { word, words, err := sw.processStopOn(scanner.EOF) if err != nil { - err = errors.Wrapf(err, "failed to process %q", source) + err = fmt.Errorf("failed to process %q: %w", source, err) } return word, words, err @@ -225,7 +224,7 @@ func (sw *shellWord) processStopOn(stopChar rune) (string, []string, error) { } if stopChar != scanner.EOF { - return "", []string{}, errors.Errorf("unexpected end of statement while looking for matching %s", string(stopChar)) + return "", []string{}, fmt.Errorf("unexpected end of statement while looking for matching %s", string(stopChar)) } return result.String(), words.getWords(), nil @@ -541,7 +540,7 @@ func (sw *shellWord) processDollarCurlyBracket() (string, error) { message = word } - return "", errors.Errorf("%s: %s", name, message) + return "", fmt.Errorf("%s: %s", name, message) } return newValue, nil @@ -677,7 +676,7 @@ func (sw *shellWord) processDollarCurlyBracket() (string, error) { message = word } - return "", errors.Errorf("%s: %s", name, message) + return "", fmt.Errorf("%s: %s", name, message) } if newValue == "" { @@ -686,17 +685,17 @@ func (sw *shellWord) processDollarCurlyBracket() (string, error) { message = word } - return "", errors.Errorf("%s: %s", name, message) + return "", fmt.Errorf("%s: %s", name, message) } return newValue, nil default: - return "", errors.Errorf("unsupported modifier (%c) in substitution", modifier) + return "", fmt.Errorf("unsupported modifier (%c) in substitution", modifier) } } - return "", errors.Errorf("missing ':' in substitution") + return "", errors.New("missing ':' in substitution") } func (sw *shellWord) processName() string { diff --git a/util/syncutil/synccache/synccache.go b/util/syncutil/synccache/synccache.go index 7d4a97fd5e..1ab0b3410c 100644 --- a/util/syncutil/synccache/synccache.go +++ b/util/syncutil/synccache/synccache.go @@ -4,10 +4,10 @@ package synccache import ( "context" + "errors" "sync" "github.com/EarthBuild/earthbuild/util/syncutil/metacontext" - "github.com/pkg/errors" ) // Constructor is a func that is used to construct a cache value, given a key. diff --git a/variables/collection.go b/variables/collection.go index b14ff23f1e..e207750b2d 100644 --- a/variables/collection.go +++ b/variables/collection.go @@ -1,6 +1,7 @@ package variables import ( + "errors" "fmt" "slices" "strings" @@ -12,8 +13,6 @@ import ( "github.com/EarthBuild/earthbuild/util/hint" "github.com/EarthBuild/earthbuild/util/platutil" "github.com/EarthBuild/earthbuild/util/shell" - "github.com/pkg/errors" - dfShell "github.com/moby/buildkit/frontend/dockerfile/shell" specs "github.com/opencontainers/image-spec/specs-go/v1" ) @@ -372,7 +371,7 @@ func (c *Collection) DeclareVar(name string, opts ...DeclareOpt) (string, string if prefs.global { if _, ok := c.args().Get(name); ok { - baseErr := errors.Wrap(ErrRedeclared, "could not override non-global ARG with global ARG") + baseErr := fmt.Errorf("could not override non-global ARG with global ARG: %w", ErrRedeclared) return "", "", hint.Wrapf(baseErr, "'%[1]v' was already declared as a non-global ARG in this scope - "+ "did you mean to add '--global' to the original declaration?", name) @@ -437,7 +436,7 @@ func (c *Collection) UpdateVar(name, value string, pncvf ProcessNonConstantVaria v, err := parseArgValue(name, value, pncvf) if err != nil { - return errors.Wrap(err, "failed to parse SET value") + return fmt.Errorf("failed to parse SET value: %w", err) } c.vars().Add(name, v, WithActive()) diff --git a/variables/parse.go b/variables/parse.go index e8ef28d367..c17adf48dc 100644 --- a/variables/parse.go +++ b/variables/parse.go @@ -1,12 +1,11 @@ package variables import ( + "fmt" "os" "strings" "github.com/EarthBuild/earthbuild/variables/reserved" - - "github.com/pkg/errors" ) // ProcessNonConstantVariableFunc is a function which takes in an expression and @@ -21,7 +20,7 @@ func ParseCommandLineArgs(args []string) (*Scope, error) { for _, arg := range args { splitArg := strings.SplitN(arg, "=", 2) if len(splitArg) < 1 { - return nil, errors.Errorf("invalid build arg %s", splitArg) + return nil, fmt.Errorf("invalid build arg %s", splitArg) } key := splitArg[0] @@ -34,7 +33,7 @@ func ParseCommandLineArgs(args []string) (*Scope, error) { } if reserved.IsBuiltIn(key) { - return nil, errors.Errorf("built-in arg %s cannot be passed on the command line", key) + return nil, fmt.Errorf("built-in arg %s cannot be passed on the command line", key) } if !hasValue { @@ -42,7 +41,7 @@ func ParseCommandLineArgs(args []string) (*Scope, error) { value, found = os.LookupEnv(key) if !found { - return nil, errors.Errorf("env var %s not set", key) + return nil, fmt.Errorf("env var %s not set", key) } } @@ -59,7 +58,7 @@ func ParseArgs(args []string, pncvf ProcessNonConstantVariableFunc, current *Col for _, arg := range args { name, variable, err := parseArg(arg, pncvf, current) if err != nil { - return nil, errors.Wrapf(err, "parse build arg %s", arg) + return nil, fmt.Errorf("parse build arg %s: %w", arg, err) } ret.Add(name, variable) @@ -73,7 +72,7 @@ func parseArg(arg string, pncvf ProcessNonConstantVariableFunc, current *Collect splitArg := strings.SplitN(arg, "=", 2) if len(splitArg) < 1 { - return "", "", errors.Errorf("invalid build arg %s", splitArg) + return "", "", fmt.Errorf("invalid build arg %s", splitArg) } name = splitArg[0] @@ -87,7 +86,7 @@ func parseArg(arg string, pncvf ProcessNonConstantVariableFunc, current *Collect if hasValue { if reserved.IsBuiltIn(name) { - return "", "", errors.Errorf("value cannot be specified for built-in build arg %s", name) + return "", "", fmt.Errorf("value cannot be specified for built-in build arg %s", name) } v, err := parseArgValue(name, value, pncvf) @@ -100,7 +99,7 @@ func parseArg(arg string, pncvf ProcessNonConstantVariableFunc, current *Collect v, ok := current.Get(name, WithActive()) if !ok { - return "", "", errors.Errorf("value not specified for build arg %s and no value can be inferred", name) + return "", "", fmt.Errorf("value not specified for build arg %s and no value can be inferred", name) } return name, v, nil diff --git a/variables/parsenew.go b/variables/parsenew.go index c9f885ee9e..a84a77424a 100644 --- a/variables/parsenew.go +++ b/variables/parsenew.go @@ -3,8 +3,6 @@ package variables import ( "fmt" "strings" - - "github.com/pkg/errors" ) // ParseFlagArgs parses flag-form args. @@ -17,7 +15,7 @@ func ParseFlagArgs(args []string) ([]string, error) { } if len(nonFlags) != 0 { - return nil, errors.Errorf("invalid argument %s", nonFlags[0]) + return nil, fmt.Errorf("invalid argument %s", nonFlags[0]) } return flags, nil @@ -60,7 +58,7 @@ func ParseFlagArgsWithNonFlags(args []string) (flags, nonFlags []string, err err } if keyFromPrev != "" { - return nil, nil, errors.Errorf("no value provided for --%s", keyFromPrev) + return nil, nil, fmt.Errorf("no value provided for --%s", keyFromPrev) } return flags, nonFlags, nil From 7760b78fec700a21add19252ae2f0cab39edaaf1 Mon Sep 17 00:00:00 2001 From: Janis Horsts Date: Thu, 25 Jun 2026 16:53:44 +0100 Subject: [PATCH 2/3] chore: tidy --- buildcontext/provider/provider.go | 2 -- builder/builder.go | 1 - buildkitd/buildkitd.go | 4 +-- cmd/debugger/main.go | 8 ++--- cmd/earthly/app/run.go | 3 +- cmd/earthly/helper/autocomplete.go | 6 ++-- cmd/earthly/main.go | 1 - earthfile2llb/converter.go | 7 ++-- earthfile2llb/interpretererror.go | 12 +------ examples/readme/proto/pb/api.pb.go | 3 +- inputgraph/error.go | 5 ++- logbus/command.go | 1 - logbus/solvermon/vertexmon_test.go | 1 - logstream/delta.pb.go | 48 ++++++++++++------------- util/containerutil/shell_shared.go | 4 +-- util/gatewaycrafter/gatewaycrafter.go | 1 - util/gitutil/detectgit.go | 22 ++++++------ util/gitutil/detectgitbinary_others.go | 3 +- util/gitutil/detectgitbinary_windows.go | 3 +- util/llbutil/secretprovider/cmd.go | 4 +-- util/proj/golang_test.go | 1 - 21 files changed, 52 insertions(+), 88 deletions(-) diff --git a/buildcontext/provider/provider.go b/buildcontext/provider/provider.go index 9701505020..644f01b05e 100644 --- a/buildcontext/provider/provider.go +++ b/buildcontext/provider/provider.go @@ -12,10 +12,8 @@ import ( "github.com/EarthBuild/earthbuild/conslogging" "github.com/EarthBuild/earthbuild/util/fsutilprogress" - "github.com/moby/buildkit/session" "github.com/moby/buildkit/session/filesync" - "github.com/sirupsen/logrus" "github.com/tonistiigi/fsutil" fstypes "github.com/tonistiigi/fsutil/types" diff --git a/builder/builder.go b/builder/builder.go index 10c168e4d4..b022b05802 100644 --- a/builder/builder.go +++ b/builder/builder.go @@ -43,7 +43,6 @@ import ( "github.com/moby/buildkit/util/apicaps" "github.com/moby/buildkit/util/entitlements" buildkitgitutil "github.com/moby/buildkit/util/gitutil" - "golang.org/x/sync/errgroup" ) diff --git a/buildkitd/buildkitd.go b/buildkitd/buildkitd.go index eb03bdb56d..9ab44fc83d 100644 --- a/buildkitd/buildkitd.go +++ b/buildkitd/buildkitd.go @@ -855,8 +855,8 @@ func waitForConnection( info, workerInfo, err := checkConnection(ctx, address, attemptTimeout, opts...) if err != nil { // We give up. - return nil, nil, fmt.Errorf("timeout %s: could not connect to buildkit: %s: %w", - opTimeout, err.Error(), ErrBuildkitConnectionFailure) + return nil, nil, fmt.Errorf("timeout %s: could not connect to buildkit: %w: %w", + opTimeout, err, ErrBuildkitConnectionFailure) } return info, workerInfo, nil diff --git a/cmd/debugger/main.go b/cmd/debugger/main.go index c7475f6ba9..819ff6a3d3 100644 --- a/cmd/debugger/main.go +++ b/cmd/debugger/main.go @@ -385,9 +385,7 @@ func main() { exitCode = 127 - var exitErr *exec.ExitError - - if errors.As(err, &exitErr) { + if exitErr, ok := errors.AsType[*exec.ExitError](err); ok { exitCode = exitErr.ExitCode() } } @@ -431,9 +429,7 @@ func handleError( exitCode := 1 - var exitErr *exec.ExitError - - if errors.As(err, &exitErr) { + if exitErr, ok := errors.AsType[*exec.ExitError](err); ok { exitCode = exitErr.ExitCode() if debuggerSettings.Enabled { conslogger.Warnf("Command %s failed with exit code %d\n", quotedCmd, exitCode) diff --git a/cmd/earthly/app/run.go b/cmd/earthly/app/run.go index 571e32103d..75f6fa2fe5 100644 --- a/cmd/earthly/app/run.go +++ b/cmd/earthly/app/run.go @@ -453,8 +453,7 @@ func errorWithPrefix(err string) string { } func getHintErr(err error, grpcError *status.Status) *hint.Error { - res := new(hint.Error) - if errors.As(err, &res) { + if res, ok := errors.AsType[*hint.Error](err); ok { return res } diff --git a/cmd/earthly/helper/autocomplete.go b/cmd/earthly/helper/autocomplete.go index 26cc6877fb..ac4ba47ddf 100644 --- a/cmd/earthly/helper/autocomplete.go +++ b/cmd/earthly/helper/autocomplete.go @@ -10,14 +10,12 @@ import ( "runtime/debug" "strconv" - gwclient "github.com/moby/buildkit/frontend/gateway/client" - - "github.com/EarthBuild/earthbuild/cmd/earthly/base" - "github.com/EarthBuild/earthbuild/autocomplete" "github.com/EarthBuild/earthbuild/buildcontext" + "github.com/EarthBuild/earthbuild/cmd/earthly/base" "github.com/EarthBuild/earthbuild/conslogging" "github.com/EarthBuild/earthbuild/util/cliutil" + gwclient "github.com/moby/buildkit/frontend/gateway/client" ) // AutoComplete handles shell autocomplete requests. diff --git a/cmd/earthly/main.go b/cmd/earthly/main.go index 6f07eb5b0f..62e8f226d9 100644 --- a/cmd/earthly/main.go +++ b/cmd/earthly/main.go @@ -27,7 +27,6 @@ import ( "github.com/fatih/color" "github.com/joho/godotenv" _ "github.com/moby/buildkit/client/connhelper/dockercontainer" // Load "docker-container://" helper. - "github.com/sirupsen/logrus" urfavecli "github.com/urfave/cli/v3" semconv "go.opentelemetry.io/otel/semconv/v1.39.0" diff --git a/earthfile2llb/converter.go b/earthfile2llb/converter.go index 96857f5e8d..82b1e39039 100644 --- a/earthfile2llb/converter.go +++ b/earthfile2llb/converter.go @@ -2708,9 +2708,7 @@ func (c *Converter) internalRun(ctx context.Context, opts ConvertRunOpts) (pllb. // Debugger. err = c.opt.LLBCaps.Supports(solverpb.CapExecMountSock) if err != nil { - var capErr *apicaps.CapError - - if errors.As(err, &capErr) { + if _, ok := errors.AsType[*apicaps.CapError](err); ok { if c.opt.InteractiveDebuggerEnabled || isInteractive { return pllb.State{}, fmt.Errorf("interactive debugger requires a newer version of buildkit: %w", err) } @@ -3508,8 +3506,7 @@ func (c *Converter) expandWildcardTargets(ctx context.Context, fullTargetName st data, _, _, err := c.ResolveReference(ctx, childTarget) if err != nil { - notExist := buildcontext.EarthfileNotExistError{} - if errors.As(err, ¬Exist) { + if _, ok := errors.AsType[buildcontext.EarthfileNotExistError](err); ok { continue } diff --git a/earthfile2llb/interpretererror.go b/earthfile2llb/interpretererror.go index c88c02bd54..bcea52947f 100644 --- a/earthfile2llb/interpretererror.go +++ b/earthfile2llb/interpretererror.go @@ -90,17 +90,7 @@ func GetInterpreterError(err error) (*InterpreterError, bool) { return nil, false } - var ie *InterpreterError - if errors.As(err, &ie) { - return ie, true - } - - unwrapped := errors.Unwrap(err) - if unwrapped != nil { - return GetInterpreterError(unwrapped) - } - - return nil, false + return errors.AsType[*InterpreterError](err) } // FromError attempts to parse the given error's string to an *InterpreterError. diff --git a/examples/readme/proto/pb/api.pb.go b/examples/readme/proto/pb/api.pb.go index a9ad7fa643..ac6c73ee10 100644 --- a/examples/readme/proto/pb/api.pb.go +++ b/examples/readme/proto/pb/api.pb.go @@ -5,9 +5,8 @@ package pb import ( fmt "fmt" - math "math" - proto "github.com/golang/protobuf/proto" + math "math" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/inputgraph/error.go b/inputgraph/error.go index d8c962a6ac..cda7dcea55 100644 --- a/inputgraph/error.go +++ b/inputgraph/error.go @@ -34,12 +34,11 @@ func (e *Error) Error() string { // is found, it will prefix the error message with source file information // associated with the error. func FormatError(err error) string { - e := &Error{} - if errors.As(err, &e) { + if e, ok := errors.AsType[*Error](err); ok { return fmt.Sprintf("%s:%d:%d %s", e.srcLoc.File, e.srcLoc.StartLine, e.srcLoc.StartColumn, err) } - return e.Error() + return err.Error() } func newError(srcLoc *earthfile.SourceLocation, format string, args ...any) error { diff --git a/logbus/command.go b/logbus/command.go index fa37351e67..705679773c 100644 --- a/logbus/command.go +++ b/logbus/command.go @@ -10,7 +10,6 @@ import ( "github.com/EarthBuild/earthbuild/logstream" "github.com/EarthBuild/earthbuild/util/circbuf" - "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/logbus/solvermon/vertexmon_test.go b/logbus/solvermon/vertexmon_test.go index 6a5d286045..ac40ae2f26 100644 --- a/logbus/solvermon/vertexmon_test.go +++ b/logbus/solvermon/vertexmon_test.go @@ -5,7 +5,6 @@ import ( "testing" "github.com/EarthBuild/earthbuild/logstream" - "github.com/stretchr/testify/assert" ) diff --git a/logstream/delta.pb.go b/logstream/delta.pb.go index ace523568b..20bcd789dd 100644 --- a/logstream/delta.pb.go +++ b/logstream/delta.pb.go @@ -7,11 +7,10 @@ package logstream import ( - "reflect" - "sync" - - "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/runtime/protoimpl" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" ) const ( @@ -1155,27 +1154,24 @@ func file_delta_proto_rawDescGZIP() []byte { return file_delta_proto_rawDescData } -var ( - file_delta_proto_msgTypes = make([]protoimpl.MessageInfo, 10) - file_delta_proto_goTypes = []interface{}{ - (*Delta)(nil), // 0: api.public.logstream.Delta - (*DeltaLog)(nil), // 1: api.public.logstream.DeltaLog - (*DeltaFormattedLog)(nil), // 2: api.public.logstream.DeltaFormattedLog - (*DeltaManifest)(nil), // 3: api.public.logstream.DeltaManifest - (*DeltaTargetManifest)(nil), // 4: api.public.logstream.DeltaTargetManifest - (*DeltaCommandManifest)(nil), // 5: api.public.logstream.DeltaCommandManifest - (*DeltaManifest_ResumeBuild)(nil), // 6: api.public.logstream.DeltaManifest.ResumeBuild - (*DeltaManifest_FieldsDelta)(nil), // 7: api.public.logstream.DeltaManifest.FieldsDelta - nil, // 8: api.public.logstream.DeltaManifest.FieldsDelta.TargetsEntry - nil, // 9: api.public.logstream.DeltaManifest.FieldsDelta.CommandsEntry - (*RunManifest)(nil), // 10: api.public.logstream.RunManifest - RunStatus(0), // 11: api.public.logstream.RunStatus - (*SourceLocation)(nil), // 12: api.public.logstream.SourceLocation - (*CommandTarget)(nil), // 13: api.public.logstream.CommandTarget - (*Failure)(nil), // 14: api.public.logstream.Failure - } -) - +var file_delta_proto_msgTypes = make([]protoimpl.MessageInfo, 10) +var file_delta_proto_goTypes = []interface{}{ + (*Delta)(nil), // 0: api.public.logstream.Delta + (*DeltaLog)(nil), // 1: api.public.logstream.DeltaLog + (*DeltaFormattedLog)(nil), // 2: api.public.logstream.DeltaFormattedLog + (*DeltaManifest)(nil), // 3: api.public.logstream.DeltaManifest + (*DeltaTargetManifest)(nil), // 4: api.public.logstream.DeltaTargetManifest + (*DeltaCommandManifest)(nil), // 5: api.public.logstream.DeltaCommandManifest + (*DeltaManifest_ResumeBuild)(nil), // 6: api.public.logstream.DeltaManifest.ResumeBuild + (*DeltaManifest_FieldsDelta)(nil), // 7: api.public.logstream.DeltaManifest.FieldsDelta + nil, // 8: api.public.logstream.DeltaManifest.FieldsDelta.TargetsEntry + nil, // 9: api.public.logstream.DeltaManifest.FieldsDelta.CommandsEntry + (*RunManifest)(nil), // 10: api.public.logstream.RunManifest + (RunStatus)(0), // 11: api.public.logstream.RunStatus + (*SourceLocation)(nil), // 12: api.public.logstream.SourceLocation + (*CommandTarget)(nil), // 13: api.public.logstream.CommandTarget + (*Failure)(nil), // 14: api.public.logstream.Failure +} var file_delta_proto_depIdxs = []int32{ 3, // 0: api.public.logstream.Delta.delta_manifest:type_name -> api.public.logstream.DeltaManifest 1, // 1: api.public.logstream.Delta.delta_log:type_name -> api.public.logstream.DeltaLog diff --git a/util/containerutil/shell_shared.go b/util/containerutil/shell_shared.go index d1c7a36dbd..bb29c7388b 100644 --- a/util/containerutil/shell_shared.go +++ b/util/containerutil/shell_shared.go @@ -366,8 +366,8 @@ func (sf *shellFrontend) commandContextOutput(ctx context.Context, args ...strin err := cmd.Run() if err != nil { - format := "command failed: %s %s: %s: %s" - return output, fmt.Errorf(format+": %w", sf.binaryName, strings.Join(args, " "), err.Error(), output.string(), err) + return output, fmt.Errorf("command failed: %s %s: %w: %s: %w", + sf.binaryName, strings.Join(args, " "), err, output.string(), err) } return output, nil diff --git a/util/gatewaycrafter/gatewaycrafter.go b/util/gatewaycrafter/gatewaycrafter.go index 32229f1892..6460654bbc 100644 --- a/util/gatewaycrafter/gatewaycrafter.go +++ b/util/gatewaycrafter/gatewaycrafter.go @@ -9,7 +9,6 @@ import ( "github.com/EarthBuild/earthbuild/states/image" "github.com/EarthBuild/earthbuild/util/stringutil" - "github.com/moby/buildkit/exporter/containerimage/exptypes" gwclient "github.com/moby/buildkit/frontend/gateway/client" ) diff --git a/util/gitutil/detectgit.go b/util/gitutil/detectgit.go index ff552187fb..53cf8376da 100644 --- a/util/gitutil/detectgit.go +++ b/util/gitutil/detectgit.go @@ -246,7 +246,7 @@ func detectGitRemoteURL(ctx context.Context, dir string) (string, error) { out, err := cmd.Output() if err != nil { - return "", fmt.Errorf("returned error %s: %s: %w", err.Error(), string(out), ErrCouldNotDetectRemote) + return "", fmt.Errorf("returned error %w: %s: %w", err, string(out), ErrCouldNotDetectRemote) } outStr := string(out) @@ -284,7 +284,7 @@ func gitRevParse(ctx context.Context, dir string, sentinel error, args ...string out, err := cmd.Output() if err != nil { - return "", fmt.Errorf("returned error %s: %s: %w", err.Error(), string(out), sentinel) + return "", fmt.Errorf("returned error %w: %s: %w", err, string(out), sentinel) } outStr := string(out) @@ -317,7 +317,7 @@ func detectGitBranch(ctx context.Context, dir, gitBranchOverride string) ([]stri out, err := cmd.Output() if err != nil { - return nil, fmt.Errorf("returned error %s: %s: %w", err.Error(), string(out), ErrCouldNotDetectGitBranch) + return nil, fmt.Errorf("returned error %w: %s: %w", err, string(out), ErrCouldNotDetectGitBranch) } outStr := string(out) @@ -334,7 +334,7 @@ func detectGitTags(ctx context.Context, dir string) ([]string, error) { out, err := cmd.Output() if err != nil { - return nil, fmt.Errorf("returned error %s: %s: %w", err.Error(), string(out), ErrCouldNotDetectGitTags) + return nil, fmt.Errorf("returned error %w: %s: %w", err, string(out), ErrCouldNotDetectGitTags) } outStr := string(out) @@ -351,7 +351,7 @@ func detectGitRefs(ctx context.Context, dir string) ([]string, error) { out, err := cmd.Output() if err != nil { - return nil, fmt.Errorf("returned error %s: %s: %w", err.Error(), string(out), ErrCouldNotDetectGitRefs) + return nil, fmt.Errorf("returned error %w: %s: %w", err, string(out), ErrCouldNotDetectGitRefs) } outStr := string(out) @@ -394,8 +394,8 @@ func detectGitTimestamp(ctx context.Context, dir string, tsType gitTimestampType out, err := cmd.Output() if err != nil { - var exitError *exec.ExitError - if errors.As(err, &exitError) && strings.Contains(string(exitError.Stderr), "does not have any commits yet") { + exitError, ok := errors.AsType[*exec.ExitError](err) + if ok && strings.Contains(string(exitError.Stderr), "does not have any commits yet") { return "", nil } @@ -417,8 +417,8 @@ func detectGitAuthor(ctx context.Context, dir string, format string) (string, er out, err := cmd.Output() if err != nil { - var exitError *exec.ExitError - if errors.As(err, &exitError) && strings.Contains(string(exitError.Stderr), "does not have any commits yet") { + exitError, ok := errors.AsType[*exec.ExitError](err) + if ok && strings.Contains(string(exitError.Stderr), "does not have any commits yet") { return "", nil } @@ -453,8 +453,8 @@ func detectGitCoAuthors(ctx context.Context, dir string) ([]string, error) { out, err := cmd.Output() if err != nil { - var exitError *exec.ExitError - if errors.As(err, &exitError) && strings.Contains(string(exitError.Stderr), "does not have any commits yet") { + exitError, ok := errors.AsType[*exec.ExitError](err) + if ok && strings.Contains(string(exitError.Stderr), "does not have any commits yet") { return nil, nil } diff --git a/util/gitutil/detectgitbinary_others.go b/util/gitutil/detectgitbinary_others.go index 6f7b98b37b..78b141234c 100644 --- a/util/gitutil/detectgitbinary_others.go +++ b/util/gitutil/detectgitbinary_others.go @@ -13,8 +13,7 @@ func detectGitBinary(ctx context.Context) error { _, err := cmd.Output() - var exitErr *exec.ExitError - if errors.As(err, &exitErr) { + if _, ok := errors.AsType[*exec.ExitError](err); ok { return ErrNoGitBinary } diff --git a/util/gitutil/detectgitbinary_windows.go b/util/gitutil/detectgitbinary_windows.go index 7a1ceda552..b55db59779 100644 --- a/util/gitutil/detectgitbinary_windows.go +++ b/util/gitutil/detectgitbinary_windows.go @@ -12,8 +12,7 @@ func detectGitBinary(ctx context.Context) error { cmd := exec.CommandContext(ctx, "cmd", "/C", "where git") _, err := cmd.Output() if err != nil { - var exitErr *exec.ExitError - if errors.As(err, &exitErr) { + if _, ok := errors.AsType[*exec.ExitError](err); ok { return ErrNoGitBinary } return err diff --git a/util/llbutil/secretprovider/cmd.go b/util/llbutil/secretprovider/cmd.go index b6a8996349..2b67f916fe 100644 --- a/util/llbutil/secretprovider/cmd.go +++ b/util/llbutil/secretprovider/cmd.go @@ -62,8 +62,8 @@ func (c *cmdStore) GetSecret(ctx context.Context, id string) ([]byte, error) { } func (c *cmdStore) secretNotFound(err error) error { - var exitErr *exec.ExitError - if !errors.As(err, &exitErr) { + exitErr, ok := errors.AsType[*exec.ExitError](err) + if !ok { return err } diff --git a/util/proj/golang_test.go b/util/proj/golang_test.go index a908b06400..fe4567140e 100644 --- a/util/proj/golang_test.go +++ b/util/proj/golang_test.go @@ -10,7 +10,6 @@ import ( "git.sr.ht/~nelsam/hel/pkg/pers" "github.com/EarthBuild/earthbuild/util/proj" - "github.com/stretchr/testify/require" ) From 6d1422337831d01ad5007b4d651172a0fcfbcf55 Mon Sep 17 00:00:00 2001 From: Janis Horsts Date: Thu, 25 Jun 2026 16:55:39 +0100 Subject: [PATCH 3/3] chore: tidy --- cmd/earthly/subcmd/bootstrap_cmds.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/earthly/subcmd/bootstrap_cmds.go b/cmd/earthly/subcmd/bootstrap_cmds.go index ccce1db1ed..c60c2dda7e 100644 --- a/cmd/earthly/subcmd/bootstrap_cmds.go +++ b/cmd/earthly/subcmd/bootstrap_cmds.go @@ -430,7 +430,7 @@ function _earthly { func renderEntryTemplate(template string) (string, error) { earthPath, err := os.Executable() if err != nil { - return "", fmt.Errorf("failed to determine earth path: %w: %w", err, err) + return "", fmt.Errorf("failed to determine earth path: %w", err) } return strings.ReplaceAll(template, "__earthly__", earthPath), nil