diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000000..c3add27d17 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,83 @@ +linters: + enable: + - bodyclose + - deadcode + - dogsled + - gocyclo + - goimports + - golint + - gosec + - gosimple + - govet + - ineffassign + - interfacer + - lll + - megacheck + - misspell + - nakedret + - staticcheck + - structcheck + - typecheck + - unconvert + - unparam + - unused + - varcheck + + disable: + - errcheck + +run: + timeout: 5m + skip-dirs: + - cli/command/stack/kubernetes/api/openapi + - cli/command/stack/kubernetes/api/client + skip-files: + - cli/compose/schema/bindata.go + - .*generated.* + +linters-settings: + gocyclo: + min-complexity: 16 + govet: + check-shadowing: false + lll: + line-length: 200 + nakedret: + command: nakedret + pattern: ^(?P.*?\\.go):(?P\\d+)\\s*(?P.*)$ + +issues: + # The default exclusion rules are a bit too permissive, so copying the relevant ones below + exclude-use-default: false + + exclude: + - parameter .* always receives + + exclude-rules: + # These are copied from the default exclude rules, except for "ineffective break statement" + # and GoDoc checks. + # https://github.com/golangci/golangci-lint/blob/0cc87df732aaf1d5ad9ce9ca538d38d916918b36/pkg/config/config.go#L36 + - text: "Error return value of .((os\\.)?std(out|err)\\..*|.*Close|.*Flush|os\\.Remove(All)?|.*printf?|os\\.(Un)?Setenv). is not checked" + linters: + - errcheck + - text: "func name will be used as test\\.Test.* by other packages, and that stutters; consider calling this" + linters: + - golint + - text: "G103: Use of unsafe calls should be audited" + linters: + - gosec + - text: "G104: Errors unhandled" + linters: + - gosec + - text: "G204: Subprocess launch(ed with (variable|function call)|ing should be audited)" + linters: + - gosec + - text: "(G301|G302): (Expect directory permissions to be 0750 or less|Expect file permissions to be 0600 or less)" + linters: + - gosec + - text: "G304: Potential file inclusion via variable" + linters: + - gosec + - text: "(G201|G202): SQL string (formatting|concatenation)" + linters: + - gosec diff --git a/cli/command/cli_test.go b/cli/command/cli_test.go index 34d0c219ca..dcff1bb569 100644 --- a/cli/command/cli_test.go +++ b/cli/command/cli_test.go @@ -152,6 +152,7 @@ func TestInitializeFromClient(t *testing.T) { } for _, testcase := range testcases { + testcase := testcase t.Run(testcase.doc, func(t *testing.T) { apiclient := &fakeClient{ pingFunc: testcase.pingFunc, @@ -189,6 +190,7 @@ func TestExperimentalCLI(t *testing.T) { } for _, testcase := range testcases { + testcase := testcase t.Run(testcase.doc, func(t *testing.T) { dir := fs.NewDir(t, testcase.doc, fs.WithFile("config.json", testcase.configfile)) defer dir.Remove() @@ -242,6 +244,7 @@ func TestGetClientWithPassword(t *testing.T) { } for _, testcase := range testcases { + testcase := testcase t.Run(testcase.doc, func(t *testing.T) { passRetriever := func(_, _ string, _ bool, attempts int) (passphrase string, giveup bool, err error) { // Always return an invalid pass first to test iteration @@ -294,11 +297,12 @@ func TestNewDockerCliAndOperators(t *testing.T) { inbuf := bytes.NewBuffer([]byte("input")) outbuf := bytes.NewBuffer(nil) errbuf := bytes.NewBuffer(nil) - cli.Apply( + err = cli.Apply( WithInputStream(ioutil.NopCloser(inbuf)), WithOutputStream(outbuf), WithErrorStream(errbuf), ) + assert.NilError(t, err) // Check input stream inputStream, err := ioutil.ReadAll(cli.In()) assert.NilError(t, err) diff --git a/cli/command/config/inspect_test.go b/cli/command/config/inspect_test.go index 1b4f275ccb..d174b0c502 100644 --- a/cli/command/config/inspect_test.go +++ b/cli/command/config/inspect_test.go @@ -7,10 +7,9 @@ import ( "time" "github.com/docker/cli/internal/test" + . "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function "github.com/docker/docker/api/types/swarm" "github.com/pkg/errors" - // Import builders to get the builder function as package function - . "github.com/docker/cli/internal/test/builders" "gotest.tools/assert" "gotest.tools/golden" ) diff --git a/cli/command/config/ls_test.go b/cli/command/config/ls_test.go index d3055b4aa1..4677b068e7 100644 --- a/cli/command/config/ls_test.go +++ b/cli/command/config/ls_test.go @@ -7,11 +7,10 @@ import ( "github.com/docker/cli/cli/config/configfile" "github.com/docker/cli/internal/test" + . "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/swarm" "github.com/pkg/errors" - // Import builders to get the builder function as package function - . "github.com/docker/cli/internal/test/builders" "gotest.tools/assert" is "gotest.tools/assert/cmp" "gotest.tools/golden" diff --git a/cli/command/container/attach.go b/cli/command/container/attach.go index de96a3b7d8..854aa73952 100644 --- a/cli/command/container/attach.go +++ b/cli/command/container/attach.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "io" - "net/http/httputil" "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" @@ -103,10 +102,7 @@ func runAttach(dockerCli command.Cli, opts *attachOptions) error { } resp, errAttach := client.ContainerAttach(ctx, opts.container, options) - if errAttach != nil && errAttach != httputil.ErrPersistEOF { - // ContainerAttach returns an ErrPersistEOF (connection closed) - // means server met an error and put it in Hijacked connection - // keep the error and read detailed error message from hijacked connection later + if errAttach != nil { return errAttach } defer resp.Close() @@ -142,10 +138,6 @@ func runAttach(dockerCli command.Cli, opts *attachOptions) error { return err } - if errAttach != nil { - return errAttach - } - return getExitStatus(errC, resultC) } diff --git a/cli/command/container/create_test.go b/cli/command/container/create_test.go index fe2651ca47..b0b8d4859e 100644 --- a/cli/command/container/create_test.go +++ b/cli/command/container/create_test.go @@ -108,6 +108,7 @@ func TestCreateContainerImagePullPolicy(t *testing.T) { }, } for _, c := range cases { + c := c pullCounter := 0 client := &fakeClient{ @@ -178,6 +179,7 @@ func TestNewCreateCommandWithContentTrustErrors(t *testing.T) { }, } for _, tc := range testCases { + tc := tc cli := test.NewFakeCli(&fakeClient{ createContainerFunc: func(config *container.Config, hostConfig *container.HostConfig, @@ -236,6 +238,7 @@ func TestNewCreateCommandWithWarnings(t *testing.T) { }, } for _, tc := range testCases { + tc := tc t.Run(tc.name, func(t *testing.T) { cli := test.NewFakeCli(&fakeClient{ createContainerFunc: func(config *container.Config, diff --git a/cli/command/container/list_test.go b/cli/command/container/list_test.go index 2bc1949a7f..310d78020a 100644 --- a/cli/command/container/list_test.go +++ b/cli/command/container/list_test.go @@ -7,9 +7,8 @@ import ( "github.com/docker/cli/cli/config/configfile" "github.com/docker/cli/internal/test" + . "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function "github.com/docker/docker/api/types" - // Import builders to get the builder function as package function - . "github.com/docker/cli/internal/test/builders" "gotest.tools/assert" "gotest.tools/golden" ) diff --git a/cli/command/container/opts_test.go b/cli/command/container/opts_test.go index a64b7c6a30..e8c71e2388 100644 --- a/cli/command/container/opts_test.go +++ b/cli/command/container/opts_test.go @@ -65,7 +65,7 @@ func setupRunFlags() (*pflag.FlagSet, *containerOptions) { } func parseMustError(t *testing.T, args string) { - _, _, _, err := parseRun(strings.Split(args+" ubuntu bash", " ")) + _, _, _, err := parseRun(strings.Split(args+" ubuntu bash", " ")) //nolint:dogsled assert.ErrorContains(t, err, "", args) } @@ -539,7 +539,7 @@ func TestParseModes(t *testing.T) { } // uts ko - _, _, _, err = parseRun([]string{"--uts=container:", "img", "cmd"}) + _, _, _, err = parseRun([]string{"--uts=container:", "img", "cmd"}) //nolint:dogsled assert.ErrorContains(t, err, "--uts: invalid UTS mode") // uts ok @@ -600,7 +600,7 @@ func TestParseRestartPolicy(t *testing.T) { func TestParseRestartPolicyAutoRemove(t *testing.T) { expected := "Conflicting options: --restart and --rm" - _, _, _, err := parseRun([]string{"--rm", "--restart=always", "img", "cmd"}) + _, _, _, err := parseRun([]string{"--rm", "--restart=always", "img", "cmd"}) //nolint:dogsled if err == nil || err.Error() != expected { t.Fatalf("Expected error %v, but got none", expected) } diff --git a/cli/command/container/run.go b/cli/command/container/run.go index c7f51f3dcc..1b0b76770c 100644 --- a/cli/command/container/run.go +++ b/cli/command/container/run.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "io" - "net/http/httputil" "os" "runtime" "strings" @@ -250,10 +249,7 @@ func attachContainer( } resp, errAttach := dockerCli.Client().ContainerAttach(ctx, containerID, options) - if errAttach != nil && errAttach != httputil.ErrPersistEOF { - // ContainerAttach returns an ErrPersistEOF (connection closed) - // means server met an error and put it in Hijacked connection - // keep the error and read detailed error message from hijacked connection later + if errAttach != nil { return nil, errAttach } diff --git a/cli/command/container/start.go b/cli/command/container/start.go index e388302841..2693987fc5 100644 --- a/cli/command/container/start.go +++ b/cli/command/container/start.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "io" - "net/http/httputil" "strings" "github.com/docker/cli/cli" @@ -98,10 +97,7 @@ func runStart(dockerCli command.Cli, opts *startOptions) error { } resp, errAttach := dockerCli.Client().ContainerAttach(ctx, c.ID, options) - if errAttach != nil && errAttach != httputil.ErrPersistEOF { - // ContainerAttach return an ErrPersistEOF (connection closed) - // means server met an error and already put it in Hijacked connection, - // we would keep the error and read the detailed error message from hijacked connection + if errAttach != nil { return errAttach } defer resp.Close() @@ -154,7 +150,7 @@ func runStart(dockerCli command.Cli, opts *startOptions) error { } } if attachErr := <-cErr; attachErr != nil { - if _, ok := err.(term.EscapeError); ok { + if _, ok := attachErr.(term.EscapeError); ok { // The user entered the detach escape sequence. return nil } diff --git a/cli/command/container/stats.go b/cli/command/container/stats.go index e8309e3324..95afccf5cb 100644 --- a/cli/command/container/stats.go +++ b/cli/command/container/stats.go @@ -208,7 +208,9 @@ func runStats(dockerCli command.Cli, opts *statsOptions) error { } var err error - for range time.Tick(500 * time.Millisecond) { + ticker := time.NewTicker(500 * time.Millisecond) + defer ticker.Stop() + for range ticker.C { cleanScreen() ccstats := []StatsEntry{} cStats.mu.Lock() diff --git a/cli/command/context/create_test.go b/cli/command/context/create_test.go index 013e82d05e..99af79e5e3 100644 --- a/cli/command/context/create_test.go +++ b/cli/command/context/create_test.go @@ -263,6 +263,7 @@ func TestCreateFromContext(t *testing.T) { cli.SetCurrentContext("dummy") for _, c := range cases { + c := c t.Run(c.name, func(t *testing.T) { cli.ResetOutputBuffers() err := RunCreate(cli, &CreateOptions{ @@ -339,6 +340,7 @@ func TestCreateFromCurrent(t *testing.T) { cli.SetCurrentContext("original") for _, c := range cases { + c := c t.Run(c.name, func(t *testing.T) { cli.ResetOutputBuffers() err := RunCreate(cli, &CreateOptions{ diff --git a/cli/command/formatter/container_test.go b/cli/command/formatter/container_test.go index 0b70fa3426..bb179586ff 100644 --- a/cli/command/formatter/container_test.go +++ b/cli/command/formatter/container_test.go @@ -312,7 +312,8 @@ func TestContainerContextWriteWithNoContainers(t *testing.T) { } for _, context := range contexts { - ContainerWrite(context.context, containers) + err := ContainerWrite(context.context, containers) + assert.NilError(t, err) assert.Check(t, is.Equal(context.expected, out.String())) // Clean buffer out.Reset() diff --git a/cli/command/formatter/image_test.go b/cli/command/formatter/image_test.go index 7efad0a758..6df395457f 100644 --- a/cli/command/formatter/image_test.go +++ b/cli/command/formatter/image_test.go @@ -348,7 +348,8 @@ func TestImageContextWriteWithNoImage(t *testing.T) { } for _, context := range contexts { - ImageWrite(context.context, images) + err := ImageWrite(context.context, images) + assert.NilError(t, err) assert.Check(t, is.Equal(context.expected, out.String())) // Clean buffer out.Reset() diff --git a/cli/command/idresolver/idresolver_test.go b/cli/command/idresolver/idresolver_test.go index f667b10641..4cb6355594 100644 --- a/cli/command/idresolver/idresolver_test.go +++ b/cli/command/idresolver/idresolver_test.go @@ -1,16 +1,14 @@ package idresolver import ( + "context" "testing" + . "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function "github.com/docker/docker/api/types/swarm" + "github.com/pkg/errors" "gotest.tools/assert" is "gotest.tools/assert/cmp" - // Import builders to get the builder function as package function - "context" - - . "github.com/docker/cli/internal/test/builders" - "github.com/pkg/errors" ) func TestResolveError(t *testing.T) { diff --git a/cli/command/image/build.go b/cli/command/image/build.go index 81cc8835f6..cbff43fde2 100644 --- a/cli/command/image/build.go +++ b/cli/command/image/build.go @@ -431,7 +431,7 @@ func runBuild(dockerCli command.Cli, options buildOptions) error { // should be just the image ID and we'll print that to stdout. if options.quiet { imageID = fmt.Sprintf("%s", buildBuff) - fmt.Fprintf(dockerCli.Out(), imageID) + _, _ = fmt.Fprint(dockerCli.Out(), imageID) } if options.imageIDFile != "" { diff --git a/cli/command/image/build/context.go b/cli/command/image/build/context.go index 5344626e05..24a9d525b5 100644 --- a/cli/command/image/build/context.go +++ b/cli/command/image/build/context.go @@ -232,6 +232,7 @@ func GetContextFromURL(out io.Writer, remoteURL, dockerfileName string) (io.Read // getWithStatusError does an http.Get() and returns an error if the // status code is 4xx or 5xx. func getWithStatusError(url string) (resp *http.Response, err error) { + // #nosec G107 if resp, err = http.Get(url); err != nil { return nil, err } @@ -344,7 +345,6 @@ func getDockerfileRelPath(absContextDir, givenDockerfile string) (string, error) absDockerfile, err = filepath.EvalSymlinks(absDockerfile) if err != nil { return "", errors.Errorf("unable to evaluate symlinks in Dockerfile path: %v", err) - } } diff --git a/cli/command/image/build/context_test.go b/cli/command/image/build/context_test.go index de4d38f75d..622f8edbd1 100644 --- a/cli/command/image/build/context_test.go +++ b/cli/command/image/build/context_test.go @@ -24,12 +24,12 @@ var prepareEmpty = func(t *testing.T) (string, func()) { } var prepareNoFiles = func(t *testing.T) (string, func()) { - return createTestTempDir(t, "", "builder-context-test") + return createTestTempDir(t, "builder-context-test") } var prepareOneFile = func(t *testing.T) (string, func()) { - contextDir, cleanup := createTestTempDir(t, "", "builder-context-test") - createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents, 0777) + contextDir, cleanup := createTestTempDir(t, "builder-context-test") + createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents) return contextDir, cleanup } @@ -42,7 +42,7 @@ func testValidateContextDirectory(t *testing.T, prepare func(t *testing.T) (stri } func TestGetContextFromLocalDirNoDockerfile(t *testing.T) { - contextDir, cleanup := createTestTempDir(t, "", "builder-context-test") + contextDir, cleanup := createTestTempDir(t, "builder-context-test") defer cleanup() _, _, err := GetContextFromLocalDir(contextDir, "") @@ -50,7 +50,7 @@ func TestGetContextFromLocalDirNoDockerfile(t *testing.T) { } func TestGetContextFromLocalDirNotExistingDir(t *testing.T) { - contextDir, cleanup := createTestTempDir(t, "", "builder-context-test") + contextDir, cleanup := createTestTempDir(t, "builder-context-test") defer cleanup() fakePath := filepath.Join(contextDir, "fake") @@ -60,7 +60,7 @@ func TestGetContextFromLocalDirNotExistingDir(t *testing.T) { } func TestGetContextFromLocalDirNotExistingDockerfile(t *testing.T) { - contextDir, cleanup := createTestTempDir(t, "", "builder-context-test") + contextDir, cleanup := createTestTempDir(t, "builder-context-test") defer cleanup() fakePath := filepath.Join(contextDir, "fake") @@ -70,10 +70,10 @@ func TestGetContextFromLocalDirNotExistingDockerfile(t *testing.T) { } func TestGetContextFromLocalDirWithNoDirectory(t *testing.T) { - contextDir, dirCleanup := createTestTempDir(t, "", "builder-context-test") + contextDir, dirCleanup := createTestTempDir(t, "builder-context-test") defer dirCleanup() - createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents, 0777) + createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents) chdirCleanup := chdir(t, contextDir) defer chdirCleanup() @@ -86,10 +86,10 @@ func TestGetContextFromLocalDirWithNoDirectory(t *testing.T) { } func TestGetContextFromLocalDirWithDockerfile(t *testing.T) { - contextDir, cleanup := createTestTempDir(t, "", "builder-context-test") + contextDir, cleanup := createTestTempDir(t, "builder-context-test") defer cleanup() - createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents, 0777) + createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents) absContextDir, relDockerfile, err := GetContextFromLocalDir(contextDir, "") assert.NilError(t, err) @@ -99,11 +99,11 @@ func TestGetContextFromLocalDirWithDockerfile(t *testing.T) { } func TestGetContextFromLocalDirLocalFile(t *testing.T) { - contextDir, cleanup := createTestTempDir(t, "", "builder-context-test") + contextDir, cleanup := createTestTempDir(t, "builder-context-test") defer cleanup() - createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents, 0777) - testFilename := createTestTempFile(t, contextDir, "tmpTest", "test", 0777) + createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents) + testFilename := createTestTempFile(t, contextDir, "tmpTest", "test") absContextDir, relDockerfile, err := GetContextFromLocalDir(testFilename, "") @@ -121,13 +121,13 @@ func TestGetContextFromLocalDirLocalFile(t *testing.T) { } func TestGetContextFromLocalDirWithCustomDockerfile(t *testing.T) { - contextDir, cleanup := createTestTempDir(t, "", "builder-context-test") + contextDir, cleanup := createTestTempDir(t, "builder-context-test") defer cleanup() chdirCleanup := chdir(t, contextDir) defer chdirCleanup() - createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents, 0777) + createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents) absContextDir, relDockerfile, err := GetContextFromLocalDir(contextDir, DefaultDockerfileName) assert.NilError(t, err) @@ -173,10 +173,10 @@ func TestGetContextFromReaderString(t *testing.T) { } func TestGetContextFromReaderTar(t *testing.T) { - contextDir, cleanup := createTestTempDir(t, "", "builder-context-test") + contextDir, cleanup := createTestTempDir(t, "builder-context-test") defer cleanup() - createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents, 0777) + createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents) tarStream, err := archive.Tar(contextDir, archive.Uncompressed) assert.NilError(t, err) @@ -241,17 +241,18 @@ func TestValidateContextDirectoryWithOneFileExcludes(t *testing.T) { // createTestTempDir creates a temporary directory for testing. // It returns the created path and a cleanup function which is meant to be used as deferred call. // When an error occurs, it terminates the test. -func createTestTempDir(t *testing.T, dir, prefix string) (string, func()) { - path, err := ioutil.TempDir(dir, prefix) +//nolint: unparam +func createTestTempDir(t *testing.T, prefix string) (string, func()) { + path, err := ioutil.TempDir("", prefix) assert.NilError(t, err) return path, func() { assert.NilError(t, os.RemoveAll(path)) } } // createTestTempFile creates a temporary file within dir with specific contents and permissions. // When an error occurs, it terminates the test -func createTestTempFile(t *testing.T, dir, filename, contents string, perm os.FileMode) string { +func createTestTempFile(t *testing.T, dir, filename, contents string) string { filePath := filepath.Join(dir, filename) - err := ioutil.WriteFile(filePath, []byte(contents), perm) + err := ioutil.WriteFile(filePath, []byte(contents), 0777) assert.NilError(t, err) return filePath } diff --git a/cli/command/image/build_buildkit.go b/cli/command/image/build_buildkit.go index b3b978c563..5c2de4630b 100644 --- a/cli/command/image/build_buildkit.go +++ b/cli/command/image/build_buildkit.go @@ -476,16 +476,13 @@ func parseSecret(value string) (*secretsprovider.FileSource, error) { func parseSSHSpecs(sl []string) (session.Attachable, error) { configs := make([]sshprovider.AgentConfig, 0, len(sl)) for _, v := range sl { - c, err := parseSSH(v) - if err != nil { - return nil, err - } + c := parseSSH(v) configs = append(configs, *c) } return sshprovider.NewSSHAgentProvider(configs) } -func parseSSH(value string) (*sshprovider.AgentConfig, error) { +func parseSSH(value string) *sshprovider.AgentConfig { parts := strings.SplitN(value, "=", 2) cfg := sshprovider.AgentConfig{ ID: parts[0], @@ -493,5 +490,5 @@ func parseSSH(value string) (*sshprovider.AgentConfig, error) { if len(parts) > 1 { cfg.Paths = strings.Split(parts[1], ",") } - return &cfg, nil + return &cfg } diff --git a/cli/command/image/build_session.go b/cli/command/image/build_session.go index 5b16b69c8e..0f15f51fb4 100644 --- a/cli/command/image/build_session.go +++ b/cli/command/image/build_session.go @@ -27,24 +27,21 @@ func isSessionSupported(dockerCli command.Cli, forStream bool) bool { } func trySession(dockerCli command.Cli, contextDir string, forStream bool) (*session.Session, error) { - var s *session.Session - if isSessionSupported(dockerCli, forStream) { - sharedKey, err := getBuildSharedKey(contextDir) - if err != nil { - return nil, errors.Wrap(err, "failed to get build shared key") - } - s, err = session.NewSession(context.Background(), filepath.Base(contextDir), sharedKey) - if err != nil { - return nil, errors.Wrap(err, "failed to create session") - } + if !isSessionSupported(dockerCli, forStream) { + return nil, nil + } + sharedKey := getBuildSharedKey(contextDir) + s, err := session.NewSession(context.Background(), filepath.Base(contextDir), sharedKey) + if err != nil { + return nil, errors.Wrap(err, "failed to create session") } return s, nil } -func getBuildSharedKey(dir string) (string, error) { +func getBuildSharedKey(dir string) string { // build session is hash of build dir with node based randomness s := sha256.Sum256([]byte(fmt.Sprintf("%s:%s", tryNodeIdentifier(), dir))) - return hex.EncodeToString(s[:]), nil + return hex.EncodeToString(s[:]) } func tryNodeIdentifier() string { diff --git a/cli/command/node/demote_test.go b/cli/command/node/demote_test.go index 3f18d63d41..849cbdc93d 100644 --- a/cli/command/node/demote_test.go +++ b/cli/command/node/demote_test.go @@ -5,11 +5,10 @@ import ( "testing" "github.com/docker/cli/internal/test" + . "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package functions "github.com/docker/docker/api/types/swarm" "github.com/pkg/errors" "gotest.tools/assert" - // Import builders to get the builder function as package function - . "github.com/docker/cli/internal/test/builders" ) func TestNodeDemoteErrors(t *testing.T) { diff --git a/cli/command/node/inspect_test.go b/cli/command/node/inspect_test.go index de343b0f49..22be4f475f 100644 --- a/cli/command/node/inspect_test.go +++ b/cli/command/node/inspect_test.go @@ -6,11 +6,10 @@ import ( "testing" "github.com/docker/cli/internal/test" + . "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package functions "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/swarm" "github.com/pkg/errors" - // Import builders to get the builder function as package function - . "github.com/docker/cli/internal/test/builders" "gotest.tools/assert" "gotest.tools/golden" ) diff --git a/cli/command/node/list_test.go b/cli/command/node/list_test.go index 5dc11c961a..11e5ff3f60 100644 --- a/cli/command/node/list_test.go +++ b/cli/command/node/list_test.go @@ -6,14 +6,13 @@ import ( "github.com/docker/cli/cli/config/configfile" "github.com/docker/cli/internal/test" + . "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/swarm" "github.com/pkg/errors" "gotest.tools/assert" is "gotest.tools/assert/cmp" "gotest.tools/golden" - // Import builders to get the builder function as package function - . "github.com/docker/cli/internal/test/builders" ) func TestNodeListErrorOnAPIFailure(t *testing.T) { diff --git a/cli/command/node/promote_test.go b/cli/command/node/promote_test.go index c6b5342320..528180ae00 100644 --- a/cli/command/node/promote_test.go +++ b/cli/command/node/promote_test.go @@ -5,11 +5,10 @@ import ( "testing" "github.com/docker/cli/internal/test" + . "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function "github.com/docker/docker/api/types/swarm" "github.com/pkg/errors" "gotest.tools/assert" - // Import builders to get the builder function as package function - . "github.com/docker/cli/internal/test/builders" ) func TestNodePromoteErrors(t *testing.T) { diff --git a/cli/command/node/ps_test.go b/cli/command/node/ps_test.go index 74a1779b1f..da4637da61 100644 --- a/cli/command/node/ps_test.go +++ b/cli/command/node/ps_test.go @@ -8,11 +8,10 @@ import ( "time" "github.com/docker/cli/internal/test" + . "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/swarm" "github.com/pkg/errors" - // Import builders to get the builder function as package function - . "github.com/docker/cli/internal/test/builders" "gotest.tools/assert" "gotest.tools/golden" ) diff --git a/cli/command/node/update_test.go b/cli/command/node/update_test.go index 8b6ae807da..00c447b6b2 100644 --- a/cli/command/node/update_test.go +++ b/cli/command/node/update_test.go @@ -5,11 +5,10 @@ import ( "testing" "github.com/docker/cli/internal/test" + . "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function "github.com/docker/docker/api/types/swarm" "github.com/pkg/errors" "gotest.tools/assert" - // Import builders to get the builder function as package function - . "github.com/docker/cli/internal/test/builders" ) func TestNodeUpdateErrors(t *testing.T) { diff --git a/cli/command/plugin/list_test.go b/cli/command/plugin/list_test.go index fbde655316..75d0c8139c 100644 --- a/cli/command/plugin/list_test.go +++ b/cli/command/plugin/list_test.go @@ -58,7 +58,7 @@ func TestListErrors(t *testing.T) { } func TestList(t *testing.T) { - singlePluginListFunc := func(filter filters.Args) (types.PluginsListResponse, error) { + singlePluginListFunc := func(_ filters.Args) (types.PluginsListResponse, error) { return types.PluginsListResponse{ { ID: "id-foo", @@ -113,7 +113,7 @@ func TestList(t *testing.T) { "format": "{{ .ID }}", }, golden: "plugin-list-with-no-trunc-option.golden", - listFunc: func(filter filters.Args) (types.PluginsListResponse, error) { + listFunc: func(_ filters.Args) (types.PluginsListResponse, error) { return types.PluginsListResponse{ { ID: "xyg4z2hiSLO5yTnBJfg4OYia9gKA6Qjd", @@ -142,7 +142,7 @@ func TestList(t *testing.T) { "format": "{{ .Name }}", }, golden: "plugin-list-sort.golden", - listFunc: func(filter filters.Args) (types.PluginsListResponse, error) { + listFunc: func(_ filters.Args) (types.PluginsListResponse, error) { return types.PluginsListResponse{ { ID: "id-1", diff --git a/cli/command/registry/login_test.go b/cli/command/registry/login_test.go index 0f1374ddbc..9372a50aec 100644 --- a/cli/command/registry/login_test.go +++ b/cli/command/registry/login_test.go @@ -69,7 +69,7 @@ func TestLoginWithCredStoreCreds(t *testing.T) { } ctx := context.Background() for _, tc := range testCases { - cli := (*test.FakeCli)(test.NewFakeCli(&fakeClient{})) + cli := test.NewFakeCli(&fakeClient{}) errBuf := new(bytes.Buffer) cli.SetErr(errBuf) loginWithCredStoreCreds(ctx, cli, &tc.inputAuthConfig) @@ -166,7 +166,7 @@ func TestRunLogin(t *testing.T) { if tc.inputStoredCred != nil { cred := *tc.inputStoredCred - configfile.GetCredentialsStore(cred.ServerAddress).Store(cred) + assert.NilError(t, configfile.GetCredentialsStore(cred.ServerAddress).Store(cred)) } loginErr := runLogin(cli, tc.inputLoginOption) if tc.expectedErr != "" { diff --git a/cli/command/secret/formatter.go b/cli/command/secret/formatter.go index 24a56bda62..9102f28856 100644 --- a/cli/command/secret/formatter.go +++ b/cli/command/secret/formatter.go @@ -13,7 +13,7 @@ import ( ) const ( - defaultSecretTableFormat = "table {{.ID}}\t{{.Name}}\t{{.Driver}}\t{{.CreatedAt}}\t{{.UpdatedAt}}" + defaultSecretTableFormat = "table {{.ID}}\t{{.Name}}\t{{.Driver}}\t{{.CreatedAt}}\t{{.UpdatedAt}}" // #nosec G101 secretIDHeader = "ID" secretCreatedHeader = "CREATED" secretUpdatedHeader = "UPDATED" diff --git a/cli/command/secret/inspect_test.go b/cli/command/secret/inspect_test.go index 67addaeadf..9224f9b796 100644 --- a/cli/command/secret/inspect_test.go +++ b/cli/command/secret/inspect_test.go @@ -7,10 +7,9 @@ import ( "time" "github.com/docker/cli/internal/test" + . "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function "github.com/docker/docker/api/types/swarm" "github.com/pkg/errors" - // Import builders to get the builder function as package function - . "github.com/docker/cli/internal/test/builders" "gotest.tools/assert" "gotest.tools/golden" ) diff --git a/cli/command/secret/ls_test.go b/cli/command/secret/ls_test.go index e1417115ce..1e6af25a0d 100644 --- a/cli/command/secret/ls_test.go +++ b/cli/command/secret/ls_test.go @@ -7,11 +7,10 @@ import ( "github.com/docker/cli/cli/config/configfile" "github.com/docker/cli/internal/test" + . "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/swarm" "github.com/pkg/errors" - // Import builders to get the builder function as package function - . "github.com/docker/cli/internal/test/builders" "gotest.tools/assert" is "gotest.tools/assert/cmp" "gotest.tools/golden" diff --git a/cli/command/service/client_test.go b/cli/command/service/client_test.go index b6b9f99058..d00afe2ca2 100644 --- a/cli/command/service/client_test.go +++ b/cli/command/service/client_test.go @@ -3,12 +3,10 @@ package service import ( "context" + . "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/client" - - // Import builders to get the builder function as package function - . "github.com/docker/cli/internal/test/builders" ) type fakeClient struct { @@ -74,6 +72,6 @@ func (f *fakeClient) NetworkInspect(ctx context.Context, networkID string, optio return types.NetworkResource{}, nil } -func newService(id string, name string, opts ...func(*swarm.Service)) swarm.Service { - return *Service(append(opts, ServiceID(id), ServiceName(name))...) +func newService(id string, name string) swarm.Service { + return *Service(ServiceID(id), ServiceName(name)) } diff --git a/cli/command/service/opts_test.go b/cli/command/service/opts_test.go index 6b9b83d186..8c27e9f026 100644 --- a/cli/command/service/opts_test.go +++ b/cli/command/service/opts_test.go @@ -202,9 +202,9 @@ func TestToServiceNetwork(t *testing.T) { } nwo := opts.NetworkOpt{} - nwo.Set("zzz-network") - nwo.Set("mmm-network") - nwo.Set("aaa-network") + assert.NilError(t, nwo.Set("zzz-network")) + assert.NilError(t, nwo.Set("mmm-network")) + assert.NilError(t, nwo.Set("aaa-network")) o := newServiceOptions() o.mode = "replicated" diff --git a/cli/command/service/update_test.go b/cli/command/service/update_test.go index 6eeea55a1f..fbabdf2bbf 100644 --- a/cli/command/service/update_test.go +++ b/cli/command/service/update_test.go @@ -28,7 +28,7 @@ func TestUpdateServiceArgs(t *testing.T) { cspec := spec.TaskTemplate.ContainerSpec cspec.Args = []string{"old", "args"} - updateService(nil, nil, flags, spec) + updateService(context.TODO(), nil, flags, spec) assert.Check(t, is.DeepEqual([]string{"the", "new args"}, cspec.Args)) } @@ -532,18 +532,18 @@ func TestUpdateReadOnly(t *testing.T) { // Update with --read-only=true, changed to true flags := newUpdateCommand(nil).Flags() flags.Set("read-only", "true") - updateService(nil, nil, flags, spec) + updateService(context.TODO(), nil, flags, spec) assert.Check(t, cspec.ReadOnly) // Update without --read-only, no change flags = newUpdateCommand(nil).Flags() - updateService(nil, nil, flags, spec) + updateService(context.TODO(), nil, flags, spec) assert.Check(t, cspec.ReadOnly) // Update with --read-only=false, changed to false flags = newUpdateCommand(nil).Flags() flags.Set("read-only", "false") - updateService(nil, nil, flags, spec) + updateService(context.TODO(), nil, flags, spec) assert.Check(t, !cspec.ReadOnly) } @@ -558,18 +558,18 @@ func TestUpdateInit(t *testing.T) { // Update with --init=true flags := newUpdateCommand(nil).Flags() flags.Set("init", "true") - updateService(nil, nil, flags, spec) + updateService(context.TODO(), nil, flags, spec) assert.Check(t, is.Equal(true, *cspec.Init)) // Update without --init, no change flags = newUpdateCommand(nil).Flags() - updateService(nil, nil, flags, spec) + updateService(context.TODO(), nil, flags, spec) assert.Check(t, is.Equal(true, *cspec.Init)) // Update with --init=false flags = newUpdateCommand(nil).Flags() flags.Set("init", "false") - updateService(nil, nil, flags, spec) + updateService(context.TODO(), nil, flags, spec) assert.Check(t, is.Equal(false, *cspec.Init)) } @@ -584,18 +584,18 @@ func TestUpdateStopSignal(t *testing.T) { // Update with --stop-signal=SIGUSR1 flags := newUpdateCommand(nil).Flags() flags.Set("stop-signal", "SIGUSR1") - updateService(nil, nil, flags, spec) + updateService(context.TODO(), nil, flags, spec) assert.Check(t, is.Equal("SIGUSR1", cspec.StopSignal)) // Update without --stop-signal, no change flags = newUpdateCommand(nil).Flags() - updateService(nil, nil, flags, spec) + updateService(context.TODO(), nil, flags, spec) assert.Check(t, is.Equal("SIGUSR1", cspec.StopSignal)) // Update with --stop-signal=SIGWINCH flags = newUpdateCommand(nil).Flags() flags.Set("stop-signal", "SIGWINCH") - updateService(nil, nil, flags, spec) + updateService(context.TODO(), nil, flags, spec) assert.Check(t, is.Equal("SIGWINCH", cspec.StopSignal)) } diff --git a/cli/command/stack/kubernetes/convert_test.go b/cli/command/stack/kubernetes/convert_test.go index 1cdf4f276b..05d1748e55 100644 --- a/cli/command/stack/kubernetes/convert_test.go +++ b/cli/command/stack/kubernetes/convert_test.go @@ -195,6 +195,7 @@ func TestHandlePullSecret(t *testing.T) { } for _, c := range cases { + c := c t.Run(c.version, func(t *testing.T) { conv, err := NewStackConverter(c.version) assert.NilError(t, err) @@ -222,6 +223,7 @@ func TestHandlePullPolicy(t *testing.T) { } for _, c := range cases { + c := c t.Run(c.version, func(t *testing.T) { conv, err := NewStackConverter(c.version) assert.NilError(t, err) @@ -271,6 +273,7 @@ func TestHandleInternalServiceType(t *testing.T) { }, } for _, c := range cases { + c := c t.Run(c.name, func(t *testing.T) { res, err := fromComposeServiceConfig(composetypes.ServiceConfig{ Name: "test", diff --git a/cli/command/stack/kubernetes/deploy_test.go b/cli/command/stack/kubernetes/deploy_test.go index 85d1a5ff7d..366ba45ebe 100644 --- a/cli/command/stack/kubernetes/deploy_test.go +++ b/cli/command/stack/kubernetes/deploy_test.go @@ -56,16 +56,16 @@ func TestCreateChildResourcesV1Beta1(t *testing.T) { secrets)) c, err := configs.Get("test", metav1.GetOptions{}) assert.NilError(t, err) - checkOwnerReferences(t, c.ObjectMeta, "test", v1beta1.SchemeGroupVersion.String()) + checkOwnerReferences(t, c.ObjectMeta, v1beta1.SchemeGroupVersion.String()) s, err := secrets.Get("test", metav1.GetOptions{}) assert.NilError(t, err) - checkOwnerReferences(t, s.ObjectMeta, "test", v1beta1.SchemeGroupVersion.String()) + checkOwnerReferences(t, s.ObjectMeta, v1beta1.SchemeGroupVersion.String()) } -func checkOwnerReferences(t *testing.T, objMeta metav1.ObjectMeta, stackName, stackVersion string) { +func checkOwnerReferences(t *testing.T, objMeta metav1.ObjectMeta, stackVersion string) { t.Helper() assert.Equal(t, len(objMeta.OwnerReferences), 1) - assert.Equal(t, objMeta.OwnerReferences[0].Name, stackName) + assert.Equal(t, objMeta.OwnerReferences[0].Name, "test") assert.Equal(t, objMeta.OwnerReferences[0].Kind, "Stack") assert.Equal(t, objMeta.OwnerReferences[0].APIVersion, stackVersion) } @@ -82,10 +82,10 @@ func TestCreateChildResourcesV1Beta2(t *testing.T) { secrets)) c, err := configs.Get("test", metav1.GetOptions{}) assert.NilError(t, err) - checkOwnerReferences(t, c.ObjectMeta, "test", v1beta2.SchemeGroupVersion.String()) + checkOwnerReferences(t, c.ObjectMeta, v1beta2.SchemeGroupVersion.String()) s, err := secrets.Get("test", metav1.GetOptions{}) assert.NilError(t, err) - checkOwnerReferences(t, s.ObjectMeta, "test", v1beta2.SchemeGroupVersion.String()) + checkOwnerReferences(t, s.ObjectMeta, v1beta2.SchemeGroupVersion.String()) } func TestCreateChildResourcesV1Alpha3(t *testing.T) { @@ -100,10 +100,10 @@ func TestCreateChildResourcesV1Alpha3(t *testing.T) { secrets)) c, err := configs.Get("test", metav1.GetOptions{}) assert.NilError(t, err) - checkOwnerReferences(t, c.ObjectMeta, "test", v1alpha3.SchemeGroupVersion.String()) + checkOwnerReferences(t, c.ObjectMeta, v1alpha3.SchemeGroupVersion.String()) s, err := secrets.Get("test", metav1.GetOptions{}) assert.NilError(t, err) - checkOwnerReferences(t, s.ObjectMeta, "test", v1alpha3.SchemeGroupVersion.String()) + checkOwnerReferences(t, s.ObjectMeta, v1alpha3.SchemeGroupVersion.String()) } func TestCreateChildResourcesWithStackCreationErrorV1Beta1(t *testing.T) { diff --git a/cli/command/stack/kubernetes/list.go b/cli/command/stack/kubernetes/list.go index 9706f4be56..facd401bb9 100644 --- a/cli/command/stack/kubernetes/list.go +++ b/cli/command/stack/kubernetes/list.go @@ -29,7 +29,7 @@ func GetStacks(kubeCli *KubeCli, opts options.List) ([]*formatter.Stack, error) } func isAllNamespacesDisabled(kubeCliConfig *configfile.KubernetesConfig) bool { - return kubeCliConfig == nil || kubeCliConfig != nil && kubeCliConfig.AllNamespaces != "disabled" + return kubeCliConfig == nil || kubeCliConfig.AllNamespaces != "disabled" } func getStacks(kubeCli *KubeCli, opts options.List) ([]*formatter.Stack, error) { diff --git a/cli/command/stack/kubernetes/watcher_test.go b/cli/command/stack/kubernetes/watcher_test.go index 0972a91461..c02655e8aa 100644 --- a/cli/command/stack/kubernetes/watcher_test.go +++ b/cli/command/stack/kubernetes/watcher_test.go @@ -41,11 +41,13 @@ func newTestPodAndStackRepository(initialPods []apiv1.Pod, initialStacks []apiv1 o := k8stesting.NewObjectTracker(scheme, codecs.UniversalDecoder()) for _, obj := range initialPods { + obj := obj if err := o.Add(&obj); err != nil { panic(err) } } for _, obj := range initialStacks { + obj := obj if err := o.Add(&obj); err != nil { panic(err) } diff --git a/cli/command/stack/list_test.go b/cli/command/stack/list_test.go index 5fdc04bed3..8d792172ac 100644 --- a/cli/command/stack/list_test.go +++ b/cli/command/stack/list_test.go @@ -6,8 +6,7 @@ import ( "github.com/docker/cli/cli/command" "github.com/docker/cli/internal/test" - // Import builders to get the builder function as package function - . "github.com/docker/cli/internal/test/builders" + . "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/swarm" "github.com/pkg/errors" diff --git a/cli/command/stack/ps_test.go b/cli/command/stack/ps_test.go index a3e68656fb..8e49d193bd 100644 --- a/cli/command/stack/ps_test.go +++ b/cli/command/stack/ps_test.go @@ -7,8 +7,7 @@ import ( "github.com/docker/cli/cli/config/configfile" "github.com/docker/cli/internal/test" - // Import builders to get the builder function as package function - . "github.com/docker/cli/internal/test/builders" + . "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/swarm" "github.com/pkg/errors" diff --git a/cli/command/stack/services_test.go b/cli/command/stack/services_test.go index a54e967983..52ba712780 100644 --- a/cli/command/stack/services_test.go +++ b/cli/command/stack/services_test.go @@ -6,9 +6,7 @@ import ( "github.com/docker/cli/cli/config/configfile" "github.com/docker/cli/internal/test" - - // Import builders to get the builder function as package function - . "github.com/docker/cli/internal/test/builders" + . "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/swarm" "github.com/pkg/errors" diff --git a/cli/command/swarm/join_token_test.go b/cli/command/swarm/join_token_test.go index 1bd7ba2508..e34e7da5f0 100644 --- a/cli/command/swarm/join_token_test.go +++ b/cli/command/swarm/join_token_test.go @@ -6,11 +6,10 @@ import ( "testing" "github.com/docker/cli/internal/test" + . "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/swarm" "github.com/pkg/errors" - // Import builders to get the builder function as package function - . "github.com/docker/cli/internal/test/builders" "gotest.tools/assert" "gotest.tools/golden" ) diff --git a/cli/command/swarm/unlock_key_test.go b/cli/command/swarm/unlock_key_test.go index d28921a141..d313c6319f 100644 --- a/cli/command/swarm/unlock_key_test.go +++ b/cli/command/swarm/unlock_key_test.go @@ -6,11 +6,10 @@ import ( "testing" "github.com/docker/cli/internal/test" + . "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/swarm" "github.com/pkg/errors" - // Import builders to get the builder function as package function - . "github.com/docker/cli/internal/test/builders" "gotest.tools/assert" "gotest.tools/golden" ) diff --git a/cli/command/swarm/update_test.go b/cli/command/swarm/update_test.go index 20a5624a89..ebddeeec0d 100644 --- a/cli/command/swarm/update_test.go +++ b/cli/command/swarm/update_test.go @@ -7,12 +7,10 @@ import ( "time" "github.com/docker/cli/internal/test" + . "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/swarm" "github.com/pkg/errors" - - // Import builders to get the builder function as package function - . "github.com/docker/cli/internal/test/builders" "gotest.tools/assert" "gotest.tools/golden" ) diff --git a/cli/command/system/info.go b/cli/command/system/info.go index 7adf92bd50..d837ca5231 100644 --- a/cli/command/system/info.go +++ b/cli/command/system/info.go @@ -88,9 +88,7 @@ func runInfo(cmd *cobra.Command, dockerCli command.Cli, opts *infoOptions) error func prettyPrintInfo(dockerCli command.Cli, info info) error { fmt.Fprintln(dockerCli.Out(), "Client:") if info.ClientInfo != nil { - if err := prettyPrintClientInfo(dockerCli, *info.ClientInfo); err != nil { - info.ClientErrors = append(info.ClientErrors, err.Error()) - } + prettyPrintClientInfo(dockerCli, *info.ClientInfo) } for _, err := range info.ClientErrors { fmt.Fprintln(dockerCli.Out(), "ERROR:", err) @@ -113,7 +111,7 @@ func prettyPrintInfo(dockerCli command.Cli, info info) error { return nil } -func prettyPrintClientInfo(dockerCli command.Cli, info clientInfo) error { +func prettyPrintClientInfo(dockerCli command.Cli, info clientInfo) { fmt.Fprintln(dockerCli.Out(), " Debug Mode:", info.Debug) if len(info.Plugins) > 0 { @@ -134,8 +132,6 @@ func prettyPrintClientInfo(dockerCli command.Cli, info clientInfo) error { if len(info.Warnings) > 0 { fmt.Fprintln(dockerCli.Err(), strings.Join(info.Warnings, "\n")) } - - return nil } // nolint: gocyclo diff --git a/cli/command/task/print_test.go b/cli/command/task/print_test.go index 6fa6e58653..5b5c0a81c3 100644 --- a/cli/command/task/print_test.go +++ b/cli/command/task/print_test.go @@ -8,8 +8,7 @@ import ( "github.com/docker/cli/cli/command/formatter" "github.com/docker/cli/cli/command/idresolver" "github.com/docker/cli/internal/test" - // Import builders to get the builder function as package function - . "github.com/docker/cli/internal/test/builders" + . "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/swarm" "gotest.tools/assert" diff --git a/cli/command/trust/inspect_pretty_test.go b/cli/command/trust/inspect_pretty_test.go index 13d436d168..d9ed38306a 100644 --- a/cli/command/trust/inspect_pretty_test.go +++ b/cli/command/trust/inspect_pretty_test.go @@ -393,11 +393,6 @@ func TestGetSignerRolesWithKeyIDs(t *testing.T) { "bob": {"key71", "key72"}, } - var roleWithSigs []client.RoleWithSignatures - for _, role := range roles { - roleWithSig := client.RoleWithSignatures{Role: role, Signatures: nil} - roleWithSigs = append(roleWithSigs, roleWithSig) - } signerRoleToKeyIDs := getDelegationRoleToKeyMap(roles) assert.Check(t, is.DeepEqual(expectedSignerRoleToKeyIDs, signerRoleToKeyIDs)) } diff --git a/cli/command/trust/key_generate.go b/cli/command/trust/key_generate.go index 47223c3d9d..bca6c45d7d 100644 --- a/cli/command/trust/key_generate.go +++ b/cli/command/trust/key_generate.go @@ -88,7 +88,7 @@ func validateAndGenerateKey(streams command.Streams, keyName string, workingDir pubPEM, err := generateKeyAndOutputPubPEM(keyName, privKeyFileStore) if err != nil { - fmt.Fprintf(streams.Out(), err.Error()) + fmt.Fprint(streams.Out(), err.Error()) return errors.Wrapf(err, "failed to generate key for %s", keyName) } @@ -108,8 +108,7 @@ func generateKeyAndOutputPubPEM(keyName string, privKeyStore trustmanager.KeySto return pem.Block{}, err } - privKeyStore.AddKey(trustmanager.KeyInfo{Role: data.RoleName(keyName)}, privKey) - if err != nil { + if err := privKeyStore.AddKey(trustmanager.KeyInfo{Role: data.RoleName(keyName)}, privKey); err != nil { return pem.Block{}, err } diff --git a/cli/command/trust/key_load_test.go b/cli/command/trust/key_load_test.go index e0e35aab9b..b8c89f1cd5 100644 --- a/cli/command/trust/key_load_test.go +++ b/cli/command/trust/key_load_test.go @@ -117,6 +117,7 @@ var testKeys = map[string][]byte{ func TestLoadKeyFromPath(t *testing.T) { skip.If(t, runtime.GOOS == "windows") for keyID, keyBytes := range testKeys { + keyID, keyBytes := keyID, keyBytes t.Run(fmt.Sprintf("load-key-id-%s-from-path", keyID), func(t *testing.T) { testLoadKeyFromPath(t, keyID, keyBytes) }) @@ -172,6 +173,7 @@ func testLoadKeyFromPath(t *testing.T, privKeyID string, privKeyFixture []byte) func TestLoadKeyTooPermissive(t *testing.T) { skip.If(t, runtime.GOOS == "windows") for keyID, keyBytes := range testKeys { + keyID, keyBytes := keyID, keyBytes t.Run(fmt.Sprintf("load-key-id-%s-too-permissive", keyID), func(t *testing.T) { testLoadKeyTooPermissive(t, keyBytes) }) diff --git a/cli/command/trust/sign_test.go b/cli/command/trust/sign_test.go index 31a56ea120..f197c7f599 100644 --- a/cli/command/trust/sign_test.go +++ b/cli/command/trust/sign_test.go @@ -116,7 +116,7 @@ func TestGetOrGenerateNotaryKey(t *testing.T) { assert.Check(t, is.DeepEqual(rootKeyA.Public(), rootKeyB.Public())) // Now also try with a delegation key - releasesKey, err := getOrGenerateNotaryKey(notaryRepo, data.RoleName(trust.ReleasesRole)) + releasesKey, err := getOrGenerateNotaryKey(notaryRepo, trust.ReleasesRole) assert.NilError(t, err) assert.Check(t, releasesKey != nil) diff --git a/cli/command/utils.go b/cli/command/utils.go index 21e702eb3f..72503f5d01 100644 --- a/cli/command/utils.go +++ b/cli/command/utils.go @@ -78,7 +78,7 @@ func PromptForConfirmation(ins io.Reader, outs io.Writer, message string) bool { } message += " [y/N] " - fmt.Fprintf(outs, message) + _, _ = fmt.Fprint(outs, message) // On Windows, force the use of the regular OS stdin stream. if runtime.GOOS == "windows" { diff --git a/cli/command/volume/inspect_test.go b/cli/command/volume/inspect_test.go index 759042a512..c5baa9c62e 100644 --- a/cli/command/volume/inspect_test.go +++ b/cli/command/volume/inspect_test.go @@ -6,10 +6,9 @@ import ( "testing" "github.com/docker/cli/internal/test" + . "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function "github.com/docker/docker/api/types" "github.com/pkg/errors" - // Import builders to get the builder function as package function - . "github.com/docker/cli/internal/test/builders" "gotest.tools/assert" "gotest.tools/golden" ) diff --git a/cli/command/volume/list_test.go b/cli/command/volume/list_test.go index 9159eb89ef..9f07006f16 100644 --- a/cli/command/volume/list_test.go +++ b/cli/command/volume/list_test.go @@ -6,12 +6,11 @@ import ( "github.com/docker/cli/cli/config/configfile" "github.com/docker/cli/internal/test" + . "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" volumetypes "github.com/docker/docker/api/types/volume" "github.com/pkg/errors" - // Import builders to get the builder function as package function - . "github.com/docker/cli/internal/test/builders" "gotest.tools/assert" "gotest.tools/golden" ) diff --git a/cli/compose/convert/compose.go b/cli/compose/convert/compose.go index 983e7b52ea..189a909622 100644 --- a/cli/compose/convert/compose.go +++ b/cli/compose/convert/compose.go @@ -109,7 +109,7 @@ func Secrets(namespace Namespace, secrets map[string]composetypes.SecretConfig) var obj swarmFileObject var err error if secret.Driver != "" { - obj, err = driverObjectConfig(namespace, name, composetypes.FileObjectConfig(secret)) + obj = driverObjectConfig(namespace, name, composetypes.FileObjectConfig(secret)) } else { obj, err = fileObjectConfig(namespace, name, composetypes.FileObjectConfig(secret)) } @@ -161,7 +161,7 @@ type swarmFileObject struct { Data []byte } -func driverObjectConfig(namespace Namespace, name string, obj composetypes.FileObjectConfig) (swarmFileObject, error) { +func driverObjectConfig(namespace Namespace, name string, obj composetypes.FileObjectConfig) swarmFileObject { if obj.Name != "" { name = obj.Name } else { @@ -174,7 +174,7 @@ func driverObjectConfig(namespace Namespace, name string, obj composetypes.FileO Labels: AddStackLabel(namespace, obj.Labels), }, Data: []byte{}, - }, nil + } } func fileObjectConfig(namespace Namespace, name string, obj composetypes.FileObjectConfig) (swarmFileObject, error) { diff --git a/cli/compose/convert/service.go b/cli/compose/convert/service.go index 2da8c6dc55..da182bbfe8 100644 --- a/cli/compose/convert/service.go +++ b/cli/compose/convert/service.go @@ -66,11 +66,7 @@ func Service( configs []*swarm.ConfigReference, ) (swarm.ServiceSpec, error) { name := namespace.Scope(service.Name) - - endpoint, err := convertEndpointSpec(service.Deploy.EndpointMode, service.Ports) - if err != nil { - return swarm.ServiceSpec{}, err - } + endpoint := convertEndpointSpec(service.Deploy.EndpointMode, service.Ports) mode, err := convertDeployMode(service.Deploy.Mode, service.Deploy.Replicas) if err != nil { @@ -103,10 +99,7 @@ func Service( return swarm.ServiceSpec{}, err } - dnsConfig, err := convertDNSConfig(service.DNS, service.DNSSearch) - if err != nil { - return swarm.ServiceSpec{}, err - } + dnsConfig := convertDNSConfig(service.DNS, service.DNSSearch) var privileges swarm.Privileges privileges.CredentialSpec, err = convertCredentialSpec( @@ -575,7 +568,7 @@ func convertResources(source composetypes.Resources) (*swarm.ResourceRequirement return resources, nil } -func convertEndpointSpec(endpointMode string, source []composetypes.ServicePortConfig) (*swarm.EndpointSpec, error) { +func convertEndpointSpec(endpointMode string, source []composetypes.ServicePortConfig) *swarm.EndpointSpec { portConfigs := []swarm.PortConfig{} for _, port := range source { portConfig := swarm.PortConfig{ @@ -594,7 +587,7 @@ func convertEndpointSpec(endpointMode string, source []composetypes.ServicePortC return &swarm.EndpointSpec{ Mode: swarm.ResolutionMode(strings.ToLower(endpointMode)), Ports: portConfigs, - }, nil + } } func convertEnvironment(source map[string]*string) []string { @@ -629,14 +622,14 @@ func convertDeployMode(mode string, replicas *uint64) (swarm.ServiceMode, error) return serviceMode, nil } -func convertDNSConfig(DNS []string, DNSSearch []string) (*swarm.DNSConfig, error) { +func convertDNSConfig(DNS []string, DNSSearch []string) *swarm.DNSConfig { if DNS != nil || DNSSearch != nil { return &swarm.DNSConfig{ Nameservers: DNS, Search: DNSSearch, - }, nil + } } - return nil, nil + return nil } func convertCredentialSpec(namespace Namespace, spec composetypes.CredentialSpecConfig, refs []*swarm.ConfigReference) (*swarm.CredentialSpec, error) { diff --git a/cli/compose/convert/service_test.go b/cli/compose/convert/service_test.go index 4205038667..85550628f2 100644 --- a/cli/compose/convert/service_test.go +++ b/cli/compose/convert/service_test.go @@ -177,7 +177,7 @@ func TestConvertEndpointSpec(t *testing.T) { Published: 80, }, } - endpoint, err := convertEndpointSpec("vip", source) + endpoint := convertEndpointSpec("vip", source) expected := swarm.EndpointSpec{ Mode: swarm.ResolutionMode(strings.ToLower("vip")), @@ -195,7 +195,6 @@ func TestConvertEndpointSpec(t *testing.T) { }, } - assert.NilError(t, err) assert.Check(t, is.DeepEqual(expected, *endpoint)) } @@ -271,13 +270,11 @@ func TestConvertServiceNetworksCustomDefault(t *testing.T) { } assert.NilError(t, err) - assert.Check(t, is.DeepEqual(expected, []swarm.NetworkAttachmentConfig(configs))) + assert.Check(t, is.DeepEqual(expected, configs)) } func TestConvertDNSConfigEmpty(t *testing.T) { - dnsConfig, err := convertDNSConfig(nil, nil) - - assert.NilError(t, err) + dnsConfig := convertDNSConfig(nil, nil) assert.Check(t, is.DeepEqual((*swarm.DNSConfig)(nil), dnsConfig)) } @@ -287,8 +284,7 @@ var ( ) func TestConvertDNSConfigAll(t *testing.T) { - dnsConfig, err := convertDNSConfig(nameservers, search) - assert.NilError(t, err) + dnsConfig := convertDNSConfig(nameservers, search) assert.Check(t, is.DeepEqual(&swarm.DNSConfig{ Nameservers: nameservers, Search: search, @@ -296,8 +292,7 @@ func TestConvertDNSConfigAll(t *testing.T) { } func TestConvertDNSConfigNameservers(t *testing.T) { - dnsConfig, err := convertDNSConfig(nameservers, nil) - assert.NilError(t, err) + dnsConfig := convertDNSConfig(nameservers, nil) assert.Check(t, is.DeepEqual(&swarm.DNSConfig{ Nameservers: nameservers, Search: nil, @@ -305,8 +300,7 @@ func TestConvertDNSConfigNameservers(t *testing.T) { } func TestConvertDNSConfigSearch(t *testing.T) { - dnsConfig, err := convertDNSConfig(nil, search) - assert.NilError(t, err) + dnsConfig := convertDNSConfig(nil, search) assert.Check(t, is.DeepEqual(&swarm.DNSConfig{ Nameservers: nil, Search: search, diff --git a/cli/compose/interpolation/interpolation.go b/cli/compose/interpolation/interpolation.go index d4f5c4a43f..fd34ca82ea 100644 --- a/cli/compose/interpolation/interpolation.go +++ b/cli/compose/interpolation/interpolation.go @@ -54,7 +54,6 @@ func Interpolate(config map[string]interface{}, opts Options) (map[string]interf func recursiveInterpolate(value interface{}, path Path, opts Options) (interface{}, error) { switch value := value.(type) { - case string: newValue, err := opts.Substitute(value, template.Mapping(opts.LookupValue)) if err != nil || newValue == value { @@ -91,7 +90,6 @@ func recursiveInterpolate(value interface{}, path Path, opts Options) (interface default: return value, nil - } } diff --git a/cli/compose/loader/loader.go b/cli/compose/loader/loader.go index a17105f08e..28573dc4d5 100644 --- a/cli/compose/loader/loader.go +++ b/cli/compose/loader/loader.go @@ -297,10 +297,13 @@ func Transform(source interface{}, target interface{}, additionalTransformers .. return decoder.Decode(source) } +// TransformerFunc defines a function to perform the actual transformation +type TransformerFunc func(interface{}) (interface{}, error) + // Transformer defines a map to type transformer type Transformer struct { TypeOf reflect.Type - Func func(interface{}) (interface{}, error) + Func TransformerFunc } func createTransformHook(additionalTransformers ...Transformer) mapstructure.DecodeHookFuncType { @@ -684,7 +687,7 @@ func absPath(workingDir string, filePath string) string { return filepath.Join(workingDir, filePath) } -func transformMapStringString(data interface{}) (interface{}, error) { +var transformMapStringString TransformerFunc = func(data interface{}) (interface{}, error) { switch value := data.(type) { case map[string]interface{}: return toMapStringString(value, false), nil @@ -695,7 +698,7 @@ func transformMapStringString(data interface{}) (interface{}, error) { } } -func transformExternal(data interface{}) (interface{}, error) { +var transformExternal TransformerFunc = func(data interface{}) (interface{}, error) { switch value := data.(type) { case bool: return map[string]interface{}{"external": value}, nil @@ -706,7 +709,7 @@ func transformExternal(data interface{}) (interface{}, error) { } } -func transformServicePort(data interface{}) (interface{}, error) { +var transformServicePort TransformerFunc = func(data interface{}) (interface{}, error) { switch entries := data.(type) { case []interface{}: // We process the list instead of individual items here. @@ -739,7 +742,7 @@ func transformServicePort(data interface{}) (interface{}, error) { } } -func transformStringSourceMap(data interface{}) (interface{}, error) { +var transformStringSourceMap TransformerFunc = func(data interface{}) (interface{}, error) { switch value := data.(type) { case string: return map[string]interface{}{"source": value}, nil @@ -750,7 +753,7 @@ func transformStringSourceMap(data interface{}) (interface{}, error) { } } -func transformBuildConfig(data interface{}) (interface{}, error) { +var transformBuildConfig TransformerFunc = func(data interface{}) (interface{}, error) { switch value := data.(type) { case string: return map[string]interface{}{"context": value}, nil @@ -761,7 +764,7 @@ func transformBuildConfig(data interface{}) (interface{}, error) { } } -func transformServiceVolumeConfig(data interface{}) (interface{}, error) { +var transformServiceVolumeConfig TransformerFunc = func(data interface{}) (interface{}, error) { switch value := data.(type) { case string: return ParseVolume(value) @@ -772,7 +775,7 @@ func transformServiceVolumeConfig(data interface{}) (interface{}, error) { } } -func transformServiceNetworkMap(value interface{}) (interface{}, error) { +var transformServiceNetworkMap TransformerFunc = func(value interface{}) (interface{}, error) { if list, ok := value.([]interface{}); ok { mapValue := map[interface{}]interface{}{} for _, name := range list { @@ -783,7 +786,7 @@ func transformServiceNetworkMap(value interface{}) (interface{}, error) { return value, nil } -func transformStringOrNumberList(value interface{}) (interface{}, error) { +var transformStringOrNumberList TransformerFunc = func(value interface{}) (interface{}, error) { list := value.([]interface{}) result := make([]string, len(list)) for i, item := range list { @@ -792,7 +795,7 @@ func transformStringOrNumberList(value interface{}) (interface{}, error) { return result, nil } -func transformStringList(data interface{}) (interface{}, error) { +var transformStringList TransformerFunc = func(data interface{}) (interface{}, error) { switch value := data.(type) { case string: return []string{value}, nil @@ -803,13 +806,13 @@ func transformStringList(data interface{}) (interface{}, error) { } } -func transformMappingOrListFunc(sep string, allowNil bool) func(interface{}) (interface{}, error) { +func transformMappingOrListFunc(sep string, allowNil bool) TransformerFunc { return func(data interface{}) (interface{}, error) { return transformMappingOrList(data, sep, allowNil), nil } } -func transformListOrMappingFunc(sep string, allowNil bool) func(interface{}) (interface{}, error) { +func transformListOrMappingFunc(sep string, allowNil bool) TransformerFunc { return func(data interface{}) (interface{}, error) { return transformListOrMapping(data, sep, allowNil), nil } @@ -848,14 +851,14 @@ func transformMappingOrList(mappingOrList interface{}, sep string, allowNil bool panic(errors.Errorf("expected a map or a list, got %T: %#v", mappingOrList, mappingOrList)) } -func transformShellCommand(value interface{}) (interface{}, error) { +var transformShellCommand TransformerFunc = func(value interface{}) (interface{}, error) { if str, ok := value.(string); ok { return shellwords.Parse(str) } return value, nil } -func transformHealthCheckTest(data interface{}) (interface{}, error) { +var transformHealthCheckTest TransformerFunc = func(data interface{}) (interface{}, error) { switch value := data.(type) { case string: return append([]string{"CMD-SHELL"}, value), nil @@ -866,7 +869,7 @@ func transformHealthCheckTest(data interface{}) (interface{}, error) { } } -func transformSize(value interface{}) (interface{}, error) { +var transformSize TransformerFunc = func(value interface{}) (interface{}, error) { switch value := value.(type) { case int: return int64(value), nil @@ -876,7 +879,7 @@ func transformSize(value interface{}) (interface{}, error) { panic(errors.Errorf("invalid type for size %T", value)) } -func transformStringToDuration(value interface{}) (interface{}, error) { +var transformStringToDuration TransformerFunc = func(value interface{}) (interface{}, error) { switch value := value.(type) { case string: d, err := time.ParseDuration(value) diff --git a/cli/compose/loader/loader_test.go b/cli/compose/loader/loader_test.go index d956fb9f5f..6acdacc160 100644 --- a/cli/compose/loader/loader_test.go +++ b/cli/compose/loader/loader_test.go @@ -1583,6 +1583,7 @@ services: }, } for _, testcase := range testcases { + testcase := testcase t.Run(testcase.doc, func(t *testing.T) { config, err := loadYAML(testcase.yaml) assert.NilError(t, err) diff --git a/cli/compose/loader/merge.go b/cli/compose/loader/merge.go index 24b74ffbc5..015b1f5a55 100644 --- a/cli/compose/loader/merge.go +++ b/cli/compose/loader/merge.go @@ -60,6 +60,7 @@ func mergeServices(base, override []types.ServiceConfig) ([]types.ServiceConfig, }, } for name, overrideService := range overrideServices { + overrideService := overrideService if baseService, ok := baseServices[name]; ok { if err := mergo.Merge(&baseService, &overrideService, mergo.WithAppendSlice, mergo.WithOverride, mergo.WithTransformers(specials)); err != nil { return base, errors.Wrapf(err, "cannot merge service %s", name) diff --git a/cli/compose/schema/schema_test.go b/cli/compose/schema/schema_test.go index 3d3c29a666..27aa70de7a 100644 --- a/cli/compose/schema/schema_test.go +++ b/cli/compose/schema/schema_test.go @@ -118,7 +118,6 @@ func TestValidateCredentialSpecs(t *testing.T) { } }) } - } func TestValidateSecretConfigNames(t *testing.T) { diff --git a/cli/compose/template/template_test.go b/cli/compose/template/template_test.go index ce3690410f..b1610009bb 100644 --- a/cli/compose/template/template_test.go +++ b/cli/compose/template/template_test.go @@ -275,6 +275,7 @@ func TestExtractVariables(t *testing.T) { }, } for _, tc := range testCases { + tc := tc t.Run(tc.name, func(t *testing.T) { actual := ExtractVariables(tc.dict, defaultPattern) assert.Check(t, is.DeepEqual(actual, tc.expected)) diff --git a/cli/compose/types/types.go b/cli/compose/types/types.go index d77c1b63dc..2578b8cf00 100644 --- a/cli/compose/types/types.go +++ b/cli/compose/types/types.go @@ -103,7 +103,7 @@ type Config struct { Volumes map[string]VolumeConfig `yaml:",omitempty" json:"volumes,omitempty"` Secrets map[string]SecretConfig `yaml:",omitempty" json:"secrets,omitempty"` Configs map[string]ConfigObjConfig `yaml:",omitempty" json:"configs,omitempty"` - Extras map[string]interface{} `yaml:",inline", json:"-"` + Extras map[string]interface{} `yaml:",inline" json:"-"` } // MarshalJSON makes Config implement json.Marshaler diff --git a/cli/config/config_test.go b/cli/config/config_test.go index dc46604f11..f9dfa224c4 100644 --- a/cli/config/config_test.go +++ b/cli/config/config_test.go @@ -462,7 +462,6 @@ func TestJSONWithPsFormatNoFile(t *testing.T) { if config.PsFormat != `table {{.ID}}\t{{.Label "com.docker.label.cpu"}}` { t.Fatalf("Unknown ps format: %s\n", config.PsFormat) } - } func TestJSONSaveWithNoFile(t *testing.T) { @@ -586,6 +585,7 @@ func TestConfigPath(t *testing.T) { expectedErr: fmt.Sprintf("is outside of root config directory %q", "dummy"), }, } { + tc := tc t.Run(tc.name, func(t *testing.T) { SetDir(tc.dir) f, err := Path(tc.path...) diff --git a/cli/context/store/store_test.go b/cli/context/store/store_test.go index dd8586551d..d1d92b250c 100644 --- a/cli/context/store/store_test.go +++ b/cli/context/store/store_test.go @@ -153,8 +153,8 @@ func TestImportTarInvalid(t *testing.T) { tf := path.Join(testDir, "test.context") f, err := os.Create(tf) - defer f.Close() assert.NilError(t, err) + defer f.Close() tw := tar.NewWriter(f) hdr := &tar.Header{ @@ -186,8 +186,8 @@ func TestImportZip(t *testing.T) { zf := path.Join(testDir, "test.zip") f, err := os.Create(zf) - defer f.Close() assert.NilError(t, err) + defer f.Close() w := zip.NewWriter(f) meta, err := json.Marshal(Metadata{ @@ -237,8 +237,8 @@ func TestImportZipInvalid(t *testing.T) { zf := path.Join(testDir, "test.zip") f, err := os.Create(zf) - defer f.Close() assert.NilError(t, err) + defer f.Close() w := zip.NewWriter(f) df, err := w.Create("dummy-file") diff --git a/cli/context/store/tlsstore_test.go b/cli/context/store/tlsstore_test.go index 6079de0f8e..e8d029606e 100644 --- a/cli/context/store/tlsstore_test.go +++ b/cli/context/store/tlsstore_test.go @@ -75,5 +75,4 @@ func TestTlsListAndBatchRemove(t *testing.T) { resEmpty, err := testee.listContextData("test-ctx") assert.NilError(t, err) assert.DeepEqual(t, resEmpty, map[string]EndpointFiles{}) - } diff --git a/cli/manifest/store/store_test.go b/cli/manifest/store/store_test.go index ae56fea924..aa06afd35c 100644 --- a/cli/manifest/store/store_test.go +++ b/cli/manifest/store/store_test.go @@ -93,6 +93,7 @@ func TestStoreSaveAndGet(t *testing.T) { } for _, testcase := range testcases { + testcase := testcase t.Run(testcase.manifestRef.String(), func(t *testing.T) { actual, err := store.Get(testcase.listRef, testcase.manifestRef) if testcase.expectedErr != "" { diff --git a/cli/registry/client/fetcher.go b/cli/registry/client/fetcher.go index e3d6cd6069..678ea2649e 100644 --- a/cli/registry/client/fetcher.go +++ b/cli/registry/client/fetcher.go @@ -11,7 +11,7 @@ import ( "github.com/docker/distribution/manifest/schema2" "github.com/docker/distribution/reference" "github.com/docker/distribution/registry/api/errcode" - "github.com/docker/distribution/registry/api/v2" + v2 "github.com/docker/distribution/registry/api/v2" distclient "github.com/docker/distribution/registry/client" "github.com/docker/docker/registry" digest "github.com/opencontainers/go-digest" @@ -103,9 +103,6 @@ func pullManifestSchemaV2ImageConfig(ctx context.Context, dgst digest.Digest, re } verifier := dgst.Verifier() - if err != nil { - return nil, err - } if _, err := verifier.Write(configJSON); err != nil { return nil, err } @@ -212,7 +209,6 @@ func (c *client) iterateEndpoints(ctx context.Context, namedRef reference.Named, confirmedTLSRegistries := make(map[string]bool) for _, endpoint := range endpoints { - if endpoint.Version == registry.APIVersion1 { logrus.Debugf("skipping v1 endpoint %s", endpoint.URL) continue diff --git a/cli/required.go b/cli/required.go index 33a4673546..cce81c86ab 100644 --- a/cli/required.go +++ b/cli/required.go @@ -99,6 +99,7 @@ func ExactArgs(number int) cobra.PositionalArgs { } } +//nolint: unparam func pluralize(word string, number int) string { if number == 1 { return word diff --git a/dockerfiles/Dockerfile.lint b/dockerfiles/Dockerfile.lint index 1d30d87b3f..be30abec28 100644 --- a/dockerfiles/Dockerfile.lint +++ b/dockerfiles/Dockerfile.lint @@ -1,20 +1,23 @@ +# syntax=docker/dockerfile:1.1.3-experimental + ARG GO_VERSION=1.12.12 +ARG GOLANGCI_LINTER_SHA="v1.21.0" -FROM golang:${GO_VERSION}-alpine +FROM golang:${GO_VERSION}-alpine AS build +ENV CGO_ENABLED=0 +RUN apk add --no-cache git +ARG GOLANGCI_LINTER_SHA +ARG GO111MODULE=on +RUN --mount=type=cache,target=/root/.cache/go-build \ + --mount=type=cache,target=/go/pkg/mod \ + go get github.com/golangci/golangci-lint/cmd/golangci-lint@${GOLANGCI_LINTER_SHA} -RUN apk add -U git - -ARG GOMETALINTER_SHA=v2.0.6 -RUN go get -d github.com/alecthomas/gometalinter && \ - cd /go/src/github.com/alecthomas/gometalinter && \ - git checkout -q "$GOMETALINTER_SHA" && \ - go build -v -o /usr/local/bin/gometalinter . && \ - gometalinter --install && \ - rm -rf /go/src/* /go/pkg/* - -WORKDIR /go/src/github.com/docker/cli +FROM golang:${GO_VERSION}-alpine AS lint ENV CGO_ENABLED=0 ENV DISABLE_WARN_OUTSIDE_CONTAINER=1 -ENTRYPOINT ["/usr/local/bin/gometalinter"] -CMD ["--config=gometalinter.json", "./..."] +COPY --from=build /go/bin/golangci-lint /usr/local/bin +WORKDIR /go/src/github.com/docker/cli +ENV GOGC=75 +ENTRYPOINT ["/usr/local/bin/golangci-lint"] +CMD ["run", "--config=.golangci.yml"] COPY . . diff --git a/e2e/cli-plugins/flags_test.go b/e2e/cli-plugins/flags_test.go index 8335dc62fe..34c3ac3281 100644 --- a/e2e/cli-plugins/flags_test.go +++ b/e2e/cli-plugins/flags_test.go @@ -131,6 +131,7 @@ func TestUnknownGlobal(t *testing.T) { "separate-val": {"--unknown", "foo", "helloworld"}, "joined-val": {"--unknown=foo", "helloworld"}, } { + args := args t.Run(name, func(t *testing.T) { res := icmd.RunCmd(run(args...)) res.Assert(t, icmd.Expected{ diff --git a/e2e/container/proxy_signal_test.go b/e2e/container/proxy_signal_test.go index c6d801199f..d6a5853798 100644 --- a/e2e/container/proxy_signal_test.go +++ b/e2e/container/proxy_signal_test.go @@ -26,17 +26,17 @@ func TestSigProxyWithTTY(t *testing.T) { assert.NilError(t, err, "failed to start container") defer icmd.RunCommand("docker", "container", "rm", "-f", t.Name()) - poll.WaitOn(t, containerExistsWithStatus(t, t.Name(), "running"), poll.WithDelay(100*time.Millisecond), poll.WithTimeout(5*time.Second)) + poll.WaitOn(t, containerExistsWithStatus(t.Name(), "running"), poll.WithDelay(100*time.Millisecond), poll.WithTimeout(5*time.Second)) pid := cmd.Process.Pid t.Logf("terminating PID %d", pid) err = syscall.Kill(pid, syscall.SIGTERM) assert.NilError(t, err) - poll.WaitOn(t, containerExistsWithStatus(t, t.Name(), "exited"), poll.WithDelay(100*time.Millisecond), poll.WithTimeout(5*time.Second)) + poll.WaitOn(t, containerExistsWithStatus(t.Name(), "exited"), poll.WithDelay(100*time.Millisecond), poll.WithTimeout(5*time.Second)) } -func containerExistsWithStatus(t *testing.T, containerID, status string) func(poll.LogT) poll.Result { +func containerExistsWithStatus(containerID, status string) func(poll.LogT) poll.Result { return func(poll.LogT) poll.Result { result := icmd.RunCommand("docker", "inspect", "-f", "{{ .State.Status }}", containerID) // ignore initial failures as the container may not yet exist (i.e., don't result.Assert(t, icmd.Success)) diff --git a/e2e/image/push_test.go b/e2e/image/push_test.go index 91dbc1cba8..1bcf025556 100644 --- a/e2e/image/push_test.go +++ b/e2e/image/push_test.go @@ -296,6 +296,7 @@ func createImage(t *testing.T, registryPrefix, repo, tag string) string { return image } +//nolint: unparam func withNotaryPassphrase(pwd string) func(*icmd.Cmd) { return func(c *icmd.Cmd) { c.Env = append(c.Env, []string{ diff --git a/e2e/trust/sign_test.go b/e2e/trust/sign_test.go index ffa320e904..da054530e0 100644 --- a/e2e/trust/sign_test.go +++ b/e2e/trust/sign_test.go @@ -31,7 +31,6 @@ func TestSignLocalImage(t *testing.T) { fixtures.WithConfig(dir.Path()), fixtures.WithNotary) result.Assert(t, icmd.Success) assert.Check(t, is.Contains(result.Stdout(), fmt.Sprintf("v1: digest: sha256:%s", fixtures.AlpineSha))) - } func TestSignWithLocalFlag(t *testing.T) { diff --git a/gometalinter.json b/gometalinter.json deleted file mode 100644 index f2b2e8545d..0000000000 --- a/gometalinter.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "Vendor": true, - "Deadline": "3m", - "Sort": ["linter", "severity", "path", "line"], - "Skip": [ - "cli/compose/schema/bindata.go", - "cli/command/stack/kubernetes/api/openapi", - "cli/command/stack/kubernetes/api/client", - ".*generated.*", - "vendor" - ], - "Exclude": [ - "parameter .* always receives", - "_esc(Dir|FS|FSString|FSMustString) is unused" - ], - "EnableGC": true, - "Linters": { - "nakedret": { - "Command": "nakedret", - "Pattern": "^(?P.*?\\.go):(?P\\d+)\\s*(?P.*)$" - } - }, - "WarnUnmatchedDirective": true, - - "DisableAll": true, - "Enable": [ - "deadcode", - "gocyclo", - "gofmt", - "goimports", - "golint", - "gosimple", - "ineffassign", - "interfacer", - "lll", - "misspell", - "nakedret", - "unconvert", - "unparam", - "unused", - "vet" - ], - - "Cyclo": 16, - "LineLength": 200 -} diff --git a/internal/containerizedengine/progress.go b/internal/containerizedengine/progress.go index 9ff2be52ab..e40b5a45d2 100644 --- a/internal/containerizedengine/progress.go +++ b/internal/containerizedengine/progress.go @@ -93,7 +93,6 @@ outer: } func updateNonActive(ctx context.Context, ongoing *jobs, cs content.Store, statuses map[string]statusInfo, keys *[]string, activeSeen map[string]struct{}, done *bool, start time.Time) error { - for _, j := range ongoing.jobs() { key := remotes.MakeRefKey(ctx, j) *keys = append(*keys, key) diff --git a/internal/containerizedengine/update.go b/internal/containerizedengine/update.go index 3cd7b31082..7c71da19e4 100644 --- a/internal/containerizedengine/update.go +++ b/internal/containerizedengine/update.go @@ -16,7 +16,7 @@ import ( "github.com/docker/distribution/reference" "github.com/docker/docker/api/types" ver "github.com/hashicorp/go-version" - "github.com/opencontainers/image-spec/specs-go/v1" + v1 "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" ) diff --git a/internal/licenseutils/client_test.go b/internal/licenseutils/client_test.go index b0b202ebb1..9e46202f28 100644 --- a/internal/licenseutils/client_test.go +++ b/internal/licenseutils/client_test.go @@ -96,7 +96,6 @@ func (c *fakeLicensingClient) StoreLicense(ctx context.Context, dclnt licensing. } func (c *fakeLicensingClient) LoadLocalLicense(ctx context.Context, dclnt licensing.WrappedDockerClient) (*model.Subscription, error) { - if c.loadLocalLicenseFunc != nil { return c.loadLocalLicenseFunc(ctx, dclnt) diff --git a/internal/versions/versions.go b/internal/versions/versions.go index 9e83bb371a..5e09eb65fd 100644 --- a/internal/versions/versions.go +++ b/internal/versions/versions.go @@ -24,7 +24,6 @@ const ( // GetEngineVersions reports the versions of the engine that are available func GetEngineVersions(ctx context.Context, registryClient registryclient.RegistryClient, registryPrefix, imageName, versionString string) (clitypes.AvailableVersions, error) { - if imageName == "" { var err error localMetadata, err := GetCurrentRuntimeMetadata("") diff --git a/opts/network_test.go b/opts/network_test.go index 1867d8ac8b..0d38955dc5 100644 --- a/opts/network_test.go +++ b/opts/network_test.go @@ -69,6 +69,7 @@ func TestNetworkOptAdvancedSyntax(t *testing.T) { }, } for _, tc := range testCases { + tc := tc t.Run(tc.value, func(t *testing.T) { var network NetworkOpt assert.NilError(t, network.Set(tc.value)) @@ -96,6 +97,7 @@ func TestNetworkOptAdvancedSyntaxInvalid(t *testing.T) { }, } for _, tc := range testCases { + tc := tc t.Run(tc.value, func(t *testing.T) { var network NetworkOpt assert.ErrorContains(t, network.Set(tc.value), tc.expectedError) diff --git a/opts/opts_test.go b/opts/opts_test.go index 4d5ef1749e..9c9f9689ff 100644 --- a/opts/opts_test.go +++ b/opts/opts_test.go @@ -266,6 +266,7 @@ func TestValidateLabel(t *testing.T) { } for _, tc := range tests { + tc := tc t.Run(tc.name, func(t *testing.T) { val, err := ValidateLabel(tc.value) if tc.expectedErr != "" { diff --git a/opts/throttledevice.go b/opts/throttledevice.go index 0959efae35..0bf5dd666f 100644 --- a/opts/throttledevice.go +++ b/opts/throttledevice.go @@ -48,9 +48,6 @@ func ValidateThrottleIOpsDevice(val string) (*blkiodev.ThrottleDevice, error) { if err != nil { return nil, fmt.Errorf("invalid rate for device: %s. The correct format is :. Number must be a positive integer", val) } - if rate < 0 { - return nil, fmt.Errorf("invalid rate for device: %s. The correct format is :. Number must be a positive integer", val) - } return &blkiodev.ThrottleDevice{Path: split[0], Rate: rate}, nil } diff --git a/opts/ulimit_test.go b/opts/ulimit_test.go index 0aa3facdfb..8fc4d5c555 100644 --- a/opts/ulimit_test.go +++ b/opts/ulimit_test.go @@ -8,7 +8,7 @@ import ( func TestUlimitOpt(t *testing.T) { ulimitMap := map[string]*units.Ulimit{ - "nofile": {"nofile", 1024, 512}, + "nofile": {Name: "nofile", Hard: 1024, Soft: 512}, } ulimitOpt := NewUlimitOpt(&ulimitMap) diff --git a/service/logs/parse_logs_test.go b/service/logs/parse_logs_test.go index 24bd0db7b7..4a423b9eb8 100644 --- a/service/logs/parse_logs_test.go +++ b/service/logs/parse_logs_test.go @@ -22,6 +22,7 @@ func TestParseLogDetails(t *testing.T) { {"errors", nil, errors.New("invalid details format")}, } for _, testcase := range testCases { + testcase := testcase t.Run(testcase.line, func(t *testing.T) { actual, err := ParseLogDetails(testcase.line) if testcase.err != nil { diff --git a/templates/templates_test.go b/templates/templates_test.go index 102de2bd9f..3a007e7b9a 100644 --- a/templates/templates_test.go +++ b/templates/templates_test.go @@ -65,6 +65,8 @@ func TestParseTruncateFunction(t *testing.T) { } for _, testCase := range testCases { + testCase := testCase + tm, err := Parse(testCase.template) assert.NilError(t, err)