diff --git a/.golangci.yml b/.golangci.yml index b5f4d0be05a3..ca150ade525b 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -87,6 +87,9 @@ linters: - linters: - revive text: stutters + - linters: + - revive + text: var-naming - linters: - revive text: empty-block diff --git a/bake/hclparser/gohcl/schema.go b/bake/hclparser/gohcl/schema.go index 03ced5419ab6..0f6f03b3b1d9 100644 --- a/bake/hclparser/gohcl/schema.go +++ b/bake/hclparser/gohcl/schema.go @@ -140,11 +140,11 @@ func getFieldTags(ty reflect.Type) *fieldTags { continue } - comma := strings.Index(tag, ",") + before, after, ok := strings.Cut(tag, ",") var name, kind string - if comma != -1 { - name = tag[:comma] - kind = tag[comma+1:] + if ok { + name = before + kind = after } else { name = tag kind = "attr" diff --git a/bake/hclparser/gohcl/types.go b/bake/hclparser/gohcl/types.go index b12e3b61c043..c2e3fd4d4a7d 100644 --- a/bake/hclparser/gohcl/types.go +++ b/bake/hclparser/gohcl/types.go @@ -9,11 +9,8 @@ import ( "github.com/hashicorp/hcl/v2" ) -var victimExpr hcl.Expression -var victimBody hcl.Body - -var exprType = reflect.TypeOf(&victimExpr).Elem() -var bodyType = reflect.TypeOf(&victimBody).Elem() -var blockType = reflect.TypeOf((*hcl.Block)(nil)) //nolint:unused -var attrType = reflect.TypeOf((*hcl.Attribute)(nil)) -var attrsType = reflect.TypeOf(hcl.Attributes(nil)) +var exprType = reflect.TypeFor[hcl.Expression]() +var bodyType = reflect.TypeFor[hcl.Body]() +var blockType = reflect.TypeFor[*hcl.Block]() //nolint:unused +var attrType = reflect.TypeFor[*hcl.Attribute]() +var attrsType = reflect.TypeFor[hcl.Attributes]() diff --git a/bake/hclparser/stdlib_test.go b/bake/hclparser/stdlib_test.go index cf05210bd610..1f3038ca80c9 100644 --- a/bake/hclparser/stdlib_test.go +++ b/bake/hclparser/stdlib_test.go @@ -34,7 +34,6 @@ func TestIndexOf(t *testing.T) { } for name, test := range tests { - name, test := name, test t.Run(name, func(t *testing.T) { got, err := indexOfFunc().Call([]cty.Value{test.input, test.key}) if test.wantErr { @@ -85,7 +84,6 @@ func TestBasename(t *testing.T) { } for name, test := range tests { - name, test := name, test t.Run(name, func(t *testing.T) { got, err := basenameFunc().Call([]cty.Value{test.input}) if test.wantErr { @@ -136,7 +134,6 @@ func TestDirname(t *testing.T) { } for name, test := range tests { - name, test := name, test t.Run(name, func(t *testing.T) { got, err := dirnameFunc().Call([]cty.Value{test.input}) if test.wantErr { @@ -190,7 +187,6 @@ func TestSanitize(t *testing.T) { } for name, test := range tests { - name, test := name, test t.Run(name, func(t *testing.T) { got, err := sanitizeFunc().Call([]cty.Value{test.input}) require.NoError(t, err) @@ -251,7 +247,6 @@ func TestSemverCmp(t *testing.T) { }, } for name, test := range tests { - name, test := name, test t.Run(name, func(t *testing.T) { got, err := semvercmpFunc().Call([]cty.Value{test.version, test.constraint}) if test.wantErr { diff --git a/bake/hclparser/type_implied.go b/bake/hclparser/type_implied.go index 3468f20e2d19..6ed6d9ad77fd 100644 --- a/bake/hclparser/type_implied.go +++ b/bake/hclparser/type_implied.go @@ -133,8 +133,8 @@ func impliedStructType(rt reflect.Type, path cty.Path) (cty.Type, error) { } var ( - valueType = reflect.TypeOf(cty.Value{}) - stringType = reflect.TypeOf("") + valueType = reflect.TypeFor[cty.Value]() + stringType = reflect.TypeFor[string]() ) // structTagIndices interrogates the fields of the given type (which must diff --git a/build/build.go b/build/build.go index f0952971902a..e5a9ecf78013 100644 --- a/build/build.go +++ b/build/build.go @@ -395,7 +395,6 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opts map[ var insecurePush bool for i, dp := range dps { - i, dp := i, dp node := dp.Node() so := reqForNodes[k][i].so if multiDriver { diff --git a/build/resolver/driver.go b/build/resolver/driver.go index 24d4eda34d9a..f68cd3350cb2 100644 --- a/build/resolver/driver.go +++ b/build/resolver/driver.go @@ -131,7 +131,6 @@ func (r *nodeResolver) Resolve(ctx context.Context, optPlatforms map[string][]oc eg, egCtx := errgroup.WithContext(ctx) workers := make([][]ocispecs.Platform, len(clients)) for i, c := range clients { - i, c := i, c if c == nil { continue } @@ -269,7 +268,6 @@ func (r *nodeResolver) boot(ctx context.Context, idxs []int, pw progress.Writer) eg, ctx := errgroup.WithContext(ctx) for i, idx := range idxs { - i, idx := i, idx eg.Go(func() error { c, err := r.clients.g.Do(ctx, fmt.Sprint(idx), func(ctx context.Context) (*client.Client, error) { if r.nodes[idx].Driver == nil { diff --git a/commands/dap.go b/commands/dap.go index 09111e022db2..08ccde34d381 100644 --- a/commands/dap.go +++ b/commands/dap.go @@ -102,7 +102,8 @@ func dapAttachCmd() *cobra.Command { return err } - conn, err := net.Dial("unix", args[0]) + dialer := net.Dialer{} + conn, err := dialer.DialContext(cmd.Context(), "unix", args[0]) if err != nil { return err } diff --git a/commands/history/trace.go b/commands/history/trace.go index 095c0c2a3363..1b2145dd8b71 100644 --- a/commands/history/trace.go +++ b/commands/history/trace.go @@ -156,7 +156,8 @@ func runTrace(ctx context.Context, dockerCli command.Cli, opts traceOptions) err return nil } - ln, err := net.Listen("tcp", opts.addr) + lc := net.ListenConfig{} + ln, err := lc.Listen(ctx, "tcp", opts.addr) if err != nil { return err } diff --git a/commands/history/utils.go b/commands/history/utils.go index 963cf1c308f5..90c892f11733 100644 --- a/commands/history/utils.go +++ b/commands/history/utils.go @@ -425,8 +425,8 @@ func timeBasedFilter(key, value, sep string) (matchFunc, error) { func cutAny(s string, seps ...string) (before, after, sep string, found bool) { for _, sep := range seps { - if idx := strings.Index(s, sep); idx != -1 { - return s[:idx], s[idx+len(sep):], sep, true + if before0, after0, ok := strings.Cut(s, sep); ok { + return before0, after0, sep, true } } return s, "", "", false diff --git a/dap/debug_shell.go b/dap/debug_shell.go index 63a7be76a633..5ebb1c930bc5 100644 --- a/dap/debug_shell.go +++ b/dap/debug_shell.go @@ -77,7 +77,8 @@ func (s *shell) listen() error { }() s.SocketPath = filepath.Join(dir, "s.sock") - s.l, s.err = net.Listen("unix", s.SocketPath) + lc := net.ListenConfig{} + s.l, s.err = lc.Listen(context.Background(), "unix", s.SocketPath) if s.err != nil { return } diff --git a/dap/eval.go b/dap/eval.go index 0072535b1341..10d13b3bd13c 100644 --- a/dap/eval.go +++ b/dap/eval.go @@ -120,7 +120,8 @@ func (t *thread) Exec(ctx Context, args []string) (message string, retErr error) }() socketPath := filepath.Join(dir, "s.sock") - l, err := net.Listen("unix", socketPath) + lc := net.ListenConfig{} + l, err := lc.Listen(ctx, "unix", socketPath) if err != nil { return "", err } diff --git a/dap/thread.go b/dap/thread.go index 2995fee305c8..febd4677e8fa 100644 --- a/dap/thread.go +++ b/dap/thread.go @@ -355,11 +355,9 @@ func (t *thread) prepareResultHandle(c Context, ref gateway.Reference, err error // Start the attach. Use the context we created and perform it in // a goroutine. We aren't necessarily assuming this will actually work. - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { t.sh.Attach(ctx, t) - }() + }) } func (t *thread) Continue() { diff --git a/docs/generate.go b/docs/generate.go index 160ce13a4706..9d5f7a92c5e5 100644 --- a/docs/generate.go +++ b/docs/generate.go @@ -135,9 +135,9 @@ func generateBakeStdlibDocs(filename string) error { } currentContent := string(dt) - start := strings.Index(currentContent, "") + before, _, ok := strings.Cut(currentContent, "") end := strings.Index(currentContent, "") - if start == -1 { + if !ok { return errors.Errorf("no start marker in %s", filename) } if end == -1 { @@ -164,7 +164,7 @@ func generateBakeStdlibDocs(filename string) error { table.AddRow(fname, fdesc) } - newContent := currentContent[:start] + "\n\n" + table.String() + "\n" + currentContent[end:] + newContent := before + "\n\n" + table.String() + "\n" + currentContent[end:] return os.WriteFile(filename, []byte(newContent), 0644) } diff --git a/driver/remote/util/dialer_unix.go b/driver/remote/util/dialer_unix.go index 307663179f9c..aa0aa5efdc8c 100644 --- a/driver/remote/util/dialer_unix.go +++ b/driver/remote/util/dialer_unix.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows package remoteutil diff --git a/go.mod b/go.mod index 5712a1c88526..92bd3b106cb2 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/docker/buildx -go 1.24.3 +go 1.25.0 require ( github.com/Masterminds/semver/v3 v3.4.0 diff --git a/hack/dockerfiles/lint.Dockerfile b/hack/dockerfiles/lint.Dockerfile index 405babf41682..f33d8db623b3 100644 --- a/hack/dockerfiles/lint.Dockerfile +++ b/hack/dockerfiles/lint.Dockerfile @@ -4,9 +4,9 @@ ARG GO_VERSION=1.25 ARG ALPINE_VERSION=3.22 ARG XX_VERSION=1.7.0 -ARG GOLANGCI_LINT_VERSION=v2.1.5 +ARG GOLANGCI_LINT_VERSION=v2.8.0 ARG GOLANGCI_FROM_SOURCE=false -ARG GOPLS_VERSION=v0.33.0 +ARG GOPLS_VERSION=v0.40.0 # GOPLS_ANALYZERS defines gopls analyzers to be run. disabled by default: deprecated simplifyrange unusedfunc unusedvariable ARG GOPLS_ANALYZERS="embeddirective fillreturns infertypeargs maprange modernize nonewvars noresultvalues simplifycompositelit simplifyslice unusedparams yield" @@ -60,16 +60,30 @@ RUN <<'EOF' mkdir -p /out for analyzer in ${GOPLS_ANALYZERS}; do mkdir -p internal/cmd/$analyzer - cat < internal/cmd/$analyzer/main.go + if [ "$analyzer" = "modernize" ]; then + cat <<'eot' > internal/cmd/$analyzer/main.go +package main + +import ( + "golang.org/x/tools/go/analysis/multichecker" + "golang.org/x/tools/go/analysis/passes/modernize" +) + +func main() { multichecker.Main(modernize.Suite...) } +eot + else + pkg="golang.org/x/tools/gopls/internal/analysis/$analyzer" + cat < internal/cmd/$analyzer/main.go package main import ( "golang.org/x/tools/go/analysis/singlechecker" - analyzer "golang.org/x/tools/gopls/internal/analysis/$analyzer" + analyzer "${pkg}" ) func main() { singlechecker.Main(analyzer.Analyzer) } eot + fi echo "Analyzing with ${analyzer}..." go build -o /out/$analyzer ./internal/cmd/$analyzer done diff --git a/tests/integration.go b/tests/integration.go index 8790d296d406..7035ff001bcf 100644 --- a/tests/integration.go +++ b/tests/integration.go @@ -1,6 +1,7 @@ package tests import ( + "context" "os" "os/exec" "path/filepath" @@ -49,7 +50,7 @@ func withDir(dir string) cmdOpt { } func buildxCmd(sb integration.Sandbox, opts ...cmdOpt) *exec.Cmd { - cmd := exec.Command("buildx") + cmd := exec.CommandContext(context.TODO(), "buildx") cmd.Env = os.Environ() for _, opt := range opts { opt(cmd) @@ -76,7 +77,7 @@ func buildxCmd(sb integration.Sandbox, opts ...cmdOpt) *exec.Cmd { } func composeCmd(sb integration.Sandbox, opts ...cmdOpt) *exec.Cmd { - cmd := exec.Command("compose") + cmd := exec.CommandContext(context.TODO(), "compose") cmd.Env = os.Environ() for _, opt := range opts { opt(cmd) @@ -100,7 +101,7 @@ func composeCmd(sb integration.Sandbox, opts ...cmdOpt) *exec.Cmd { } func dockerCmd(sb integration.Sandbox, opts ...cmdOpt) *exec.Cmd { - cmd := exec.Command("docker") + cmd := exec.CommandContext(context.TODO(), "docker") cmd.Env = os.Environ() for _, opt := range opts { opt(cmd) @@ -200,10 +201,10 @@ func buildkitVersion(t *testing.T, sb integration.Sandbox) string { os.RemoveAll(destDir) }) - cmd := exec.Command(undockBin, "--cachedir", "/root/.cache/undock", "--include", "/usr/bin/buildkitd", "--rm-dist", buildkitImage, destDir) + cmd := exec.CommandContext(context.TODO(), undockBin, "--cachedir", "/root/.cache/undock", "--include", "/usr/bin/buildkitd", "--rm-dist", buildkitImage, destDir) require.NoErrorf(t, cmd.Run(), "failed to extract buildkitd binary from %q", buildkitImage) - cmd = exec.Command(filepath.Join(destDir, "usr", "bin", "buildkitd"), "--version") + cmd = exec.CommandContext(context.TODO(), filepath.Join(destDir, "usr", "bin", "buildkitd"), "--version") out, err := cmd.CombinedOutput() require.NoErrorf(t, err, "failed to get BuildKit version from %q: %s", buildkitImage, string(out)) diff --git a/tests/workers/docker-container.go b/tests/workers/docker-container.go index 9e55ea9b835b..8126e3d0112d 100644 --- a/tests/workers/docker-container.go +++ b/tests/workers/docker-container.go @@ -58,7 +58,7 @@ func (w *containerWorker) New(ctx context.Context, cfg *integration.BackendConfi } defer os.RemoveAll(filepath.Dir(cfgfile)) name := "integration-container-" + identity.NewID() - cmd := exec.Command("buildx", "create", + cmd := exec.CommandContext(ctx, "buildx", "create", "--bootstrap", "--name="+name, "--buildkitd-config="+cfgfile, @@ -75,7 +75,7 @@ func (w *containerWorker) New(ctx context.Context, cfg *integration.BackendConfi } cl := func() error { - cmd := exec.Command("buildx", "rm", "-f", name) + cmd := exec.CommandContext(context.Background(), "buildx", "rm", "-f", name) cmd.Env = append( os.Environ(), "BUILDX_CONFIG=/tmp/buildx-"+name, diff --git a/tests/workers/docker.go b/tests/workers/docker.go index 285223882a42..32e86b10c5be 100644 --- a/tests/workers/docker.go +++ b/tests/workers/docker.go @@ -98,7 +98,7 @@ func (c dockerWorker) New(ctx context.Context, cfg *integration.BackendConfig) ( } name := "integration-" + identity.NewID() - cmd := exec.Command("docker", "context", "create", + cmd := exec.CommandContext(ctx, "docker", "context", "create", name, "--docker", "host="+bk.DockerAddress(), ) @@ -109,7 +109,7 @@ func (c dockerWorker) New(ctx context.Context, cfg *integration.BackendConfig) ( cl = func() error { err := bkclose() - cmd := exec.Command("docker", "context", "rm", "-f", name) + cmd := exec.CommandContext(context.Background(), "docker", "context", "rm", "-f", name) if err1 := cmd.Run(); err == nil { err = errors.Wrapf(err1, "failed to remove buildx instance %s", name) } diff --git a/tests/workers/remote.go b/tests/workers/remote.go index 14c09cacc47b..c13b2b97cdc6 100644 --- a/tests/workers/remote.go +++ b/tests/workers/remote.go @@ -42,7 +42,7 @@ func (w remoteWorker) New(ctx context.Context, cfg *integration.BackendConfig) ( } name := "integration-remote-" + identity.NewID() - cmd := exec.Command("buildx", "create", + cmd := exec.CommandContext(ctx, "buildx", "create", "--bootstrap", "--name="+name, "--driver=remote", @@ -55,7 +55,7 @@ func (w remoteWorker) New(ctx context.Context, cfg *integration.BackendConfig) ( cl = func() error { err := bkclose() - cmd := exec.Command("buildx", "rm", "-f", name) + cmd := exec.CommandContext(context.Background(), "buildx", "rm", "-f", name) cmd.Env = append(os.Environ(), "BUILDX_CONFIG=/tmp/buildx-"+name) if err1 := cmd.Run(); err == nil { err = err1 diff --git a/util/confutil/config_unix.go b/util/confutil/config_unix.go index 00a59137fe0e..899c68c4207d 100644 --- a/util/confutil/config_unix.go +++ b/util/confutil/config_unix.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows package confutil diff --git a/util/confutil/config_unix_test.go b/util/confutil/config_unix_test.go index 32bf36499b5e..e2e1d2171d7c 100644 --- a/util/confutil/config_unix_test.go +++ b/util/confutil/config_unix_test.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows package confutil diff --git a/util/dockerutil/dockerconfig/configprovider.go b/util/dockerutil/dockerconfig/configprovider.go index 60908155545e..2d03e4185e70 100644 --- a/util/dockerutil/dockerconfig/configprovider.go +++ b/util/dockerutil/dockerconfig/configprovider.go @@ -133,9 +133,9 @@ func parseConfigKey(key string) alternativeConfig { var out alternativeConfig var mainPart, scopePart string - if i := strings.IndexByte(key, '@'); i >= 0 { - mainPart = key[:i] - scopePart = key[i+1:] + if before, after, ok := strings.Cut(key, "@"); ok { + mainPart = before + scopePart = after } else { mainPart = key } @@ -153,14 +153,14 @@ func parseConfigKey(key string) alternativeConfig { return out } - slash := strings.IndexByte(mainPart, '/') - if slash < 0 { + before, after, ok := strings.Cut(mainPart, "/") + if !ok { out.host = mainPart return out } - out.host = mainPart[:slash] - out.repo = mainPart[slash+1:] + out.host = before + out.repo = after return out } diff --git a/util/gitutil/gittestutil/testutilserve.go b/util/gitutil/gittestutil/testutilserve.go index 87c15179f251..0a6076ec43b7 100644 --- a/util/gitutil/gittestutil/testutilserve.go +++ b/util/gitutil/gittestutil/testutilserve.go @@ -66,7 +66,8 @@ func GitServeHTTP(c *gitutil.Git, t testing.TB, opts ...GitServeOpt) (url string } mux.Handle(prefix, handler(http.StripPrefix(prefix, http.FileServer(http.Dir(dir))))) - l, err := net.Listen("tcp", "localhost:0") + lc := net.ListenConfig{} + l, err := lc.Listen(ctx, "tcp", "localhost:0") if err != nil { panic(err) } diff --git a/util/gitutil/path.go b/util/gitutil/path.go index 898cb654dd0d..86cdcbdc114a 100644 --- a/util/gitutil/path.go +++ b/util/gitutil/path.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows package gitutil diff --git a/util/gitutil/path_unix_test.go b/util/gitutil/path_unix_test.go index 76c305345f30..f1af507bf8f9 100644 --- a/util/gitutil/path_unix_test.go +++ b/util/gitutil/path_unix_test.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows package gitutil diff --git a/util/ioset/mux.go b/util/ioset/mux.go index 143ce853a862..261b6e7ee256 100644 --- a/util/ioset/mux.go +++ b/util/ioset/mux.go @@ -36,10 +36,7 @@ func NewMuxIO(in In, outs []MuxOut, initIdx int, toggleMessage func(prev int, re var wg sync.WaitGroup var mu sync.Mutex for i, o := range outs { - i, o := i, o - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { if err := copyToFunc(o.Stdout, func() (io.Writer, error) { if m.cur == i { return in.Stdout, nil @@ -51,10 +48,8 @@ func NewMuxIO(in In, outs []MuxOut, initIdx int, toggleMessage func(prev int, re if err := o.Stdout.Close(); err != nil { logrus.WithField("output index", i).WithError(err).Warnf("failed to close stdout") } - }() - wg.Add(1) - go func() { - defer wg.Done() + }) + wg.Go(func() { if err := copyToFunc(o.Stderr, func() (io.Writer, error) { if m.cur == i { return in.Stderr, nil @@ -66,7 +61,7 @@ func NewMuxIO(in In, outs []MuxOut, initIdx int, toggleMessage func(prev int, re if err := o.Stderr.Close(); err != nil { logrus.WithField("output index", i).WithError(err).Warnf("failed to close stderr") } - }() + }) } go func() { errToggle := errors.Errorf("toggle IO") diff --git a/util/ioset/mux_test.go b/util/ioset/mux_test.go index 039998aed404..8819e1650ee6 100644 --- a/util/ioset/mux_test.go +++ b/util/ioset/mux_test.go @@ -303,11 +303,11 @@ func writeMasked(w io.Writer, s string) io.Writer { pr.CloseWithError(readErr) return } - var masked string + var masked strings.Builder for range n { - masked += s + masked.WriteString(s) } - if _, err := w.Write([]byte(masked)); err != nil { + if _, err := w.Write([]byte(masked.String())); err != nil { pr.CloseWithError(err) return } diff --git a/util/osutil/path_unix.go b/util/osutil/path_unix.go index 2faa703062a9..4fe6936e5ee3 100644 --- a/util/osutil/path_unix.go +++ b/util/osutil/path_unix.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows package osutil