Merge pull request #2239 from thaJeztah/19.03_backport_carry_golangci_lint

[19.03 backport] Replace gometalinter with Golangci lint [carry 1797]
This commit is contained in:
Silvin Lubecki 2020-01-06 16:33:04 +01:00 committed by GitHub
commit 2c7de2070e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
86 changed files with 286 additions and 289 deletions

83
.golangci.yml Normal file
View File

@ -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<path>.*?\\.go):(?P<line>\\d+)\\s*(?P<message>.*)$
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

View File

@ -152,6 +152,7 @@ func TestInitializeFromClient(t *testing.T) {
} }
for _, testcase := range testcases { for _, testcase := range testcases {
testcase := testcase
t.Run(testcase.doc, func(t *testing.T) { t.Run(testcase.doc, func(t *testing.T) {
apiclient := &fakeClient{ apiclient := &fakeClient{
pingFunc: testcase.pingFunc, pingFunc: testcase.pingFunc,
@ -189,6 +190,7 @@ func TestExperimentalCLI(t *testing.T) {
} }
for _, testcase := range testcases { for _, testcase := range testcases {
testcase := testcase
t.Run(testcase.doc, func(t *testing.T) { t.Run(testcase.doc, func(t *testing.T) {
dir := fs.NewDir(t, testcase.doc, fs.WithFile("config.json", testcase.configfile)) dir := fs.NewDir(t, testcase.doc, fs.WithFile("config.json", testcase.configfile))
defer dir.Remove() defer dir.Remove()
@ -242,6 +244,7 @@ func TestGetClientWithPassword(t *testing.T) {
} }
for _, testcase := range testcases { for _, testcase := range testcases {
testcase := testcase
t.Run(testcase.doc, func(t *testing.T) { t.Run(testcase.doc, func(t *testing.T) {
passRetriever := func(_, _ string, _ bool, attempts int) (passphrase string, giveup bool, err error) { passRetriever := func(_, _ string, _ bool, attempts int) (passphrase string, giveup bool, err error) {
// Always return an invalid pass first to test iteration // Always return an invalid pass first to test iteration
@ -294,11 +297,12 @@ func TestNewDockerCliAndOperators(t *testing.T) {
inbuf := bytes.NewBuffer([]byte("input")) inbuf := bytes.NewBuffer([]byte("input"))
outbuf := bytes.NewBuffer(nil) outbuf := bytes.NewBuffer(nil)
errbuf := bytes.NewBuffer(nil) errbuf := bytes.NewBuffer(nil)
cli.Apply( err = cli.Apply(
WithInputStream(ioutil.NopCloser(inbuf)), WithInputStream(ioutil.NopCloser(inbuf)),
WithOutputStream(outbuf), WithOutputStream(outbuf),
WithErrorStream(errbuf), WithErrorStream(errbuf),
) )
assert.NilError(t, err)
// Check input stream // Check input stream
inputStream, err := ioutil.ReadAll(cli.In()) inputStream, err := ioutil.ReadAll(cli.In())
assert.NilError(t, err) assert.NilError(t, err)

View File

@ -7,10 +7,9 @@ import (
"time" "time"
"github.com/docker/cli/internal/test" "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/docker/docker/api/types/swarm"
"github.com/pkg/errors" "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/assert"
"gotest.tools/golden" "gotest.tools/golden"
) )

View File

@ -7,11 +7,10 @@ import (
"github.com/docker/cli/cli/config/configfile" "github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/internal/test" "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"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"github.com/pkg/errors" "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/assert"
is "gotest.tools/assert/cmp" is "gotest.tools/assert/cmp"
"gotest.tools/golden" "gotest.tools/golden"

View File

@ -4,7 +4,6 @@ import (
"context" "context"
"fmt" "fmt"
"io" "io"
"net/http/httputil"
"github.com/docker/cli/cli" "github.com/docker/cli/cli"
"github.com/docker/cli/cli/command" "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) resp, errAttach := client.ContainerAttach(ctx, opts.container, options)
if errAttach != nil && errAttach != httputil.ErrPersistEOF { if errAttach != nil {
// 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
return errAttach return errAttach
} }
defer resp.Close() defer resp.Close()
@ -142,10 +138,6 @@ func runAttach(dockerCli command.Cli, opts *attachOptions) error {
return err return err
} }
if errAttach != nil {
return errAttach
}
return getExitStatus(errC, resultC) return getExitStatus(errC, resultC)
} }

View File

@ -151,6 +151,7 @@ func TestNewCreateCommandWithContentTrustErrors(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
tc := tc
cli := test.NewFakeCli(&fakeClient{ cli := test.NewFakeCli(&fakeClient{
createContainerFunc: func(config *container.Config, createContainerFunc: func(config *container.Config,
hostConfig *container.HostConfig, hostConfig *container.HostConfig,
@ -209,6 +210,7 @@ func TestNewCreateCommandWithWarnings(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
tc := tc
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{ cli := test.NewFakeCli(&fakeClient{
createContainerFunc: func(config *container.Config, createContainerFunc: func(config *container.Config,

View File

@ -7,9 +7,8 @@ import (
"github.com/docker/cli/cli/config/configfile" "github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/internal/test" "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"
// Import builders to get the builder function as package function
. "github.com/docker/cli/internal/test/builders"
"gotest.tools/assert" "gotest.tools/assert"
"gotest.tools/golden" "gotest.tools/golden"
) )

View File

@ -65,7 +65,7 @@ func setupRunFlags() (*pflag.FlagSet, *containerOptions) {
} }
func parseMustError(t *testing.T, args string) { 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) assert.ErrorContains(t, err, "", args)
} }
@ -539,7 +539,7 @@ func TestParseModes(t *testing.T) {
} }
// uts ko // 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") assert.ErrorContains(t, err, "--uts: invalid UTS mode")
// uts ok // uts ok
@ -600,7 +600,7 @@ func TestParseRestartPolicy(t *testing.T) {
func TestParseRestartPolicyAutoRemove(t *testing.T) { func TestParseRestartPolicyAutoRemove(t *testing.T) {
expected := "Conflicting options: --restart and --rm" 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 { if err == nil || err.Error() != expected {
t.Fatalf("Expected error %v, but got none", expected) t.Fatalf("Expected error %v, but got none", expected)
} }

View File

@ -4,7 +4,6 @@ import (
"context" "context"
"fmt" "fmt"
"io" "io"
"net/http/httputil"
"os" "os"
"runtime" "runtime"
"strings" "strings"
@ -248,10 +247,7 @@ func attachContainer(
} }
resp, errAttach := dockerCli.Client().ContainerAttach(ctx, containerID, options) resp, errAttach := dockerCli.Client().ContainerAttach(ctx, containerID, options)
if errAttach != nil && errAttach != httputil.ErrPersistEOF { if errAttach != nil {
// 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
return nil, errAttach return nil, errAttach
} }

View File

@ -4,7 +4,6 @@ import (
"context" "context"
"fmt" "fmt"
"io" "io"
"net/http/httputil"
"strings" "strings"
"github.com/docker/cli/cli" "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) resp, errAttach := dockerCli.Client().ContainerAttach(ctx, c.ID, options)
if errAttach != nil && errAttach != httputil.ErrPersistEOF { if errAttach != nil {
// 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
return errAttach return errAttach
} }
defer resp.Close() defer resp.Close()
@ -154,7 +150,7 @@ func runStart(dockerCli command.Cli, opts *startOptions) error {
} }
} }
if attachErr := <-cErr; attachErr != nil { if attachErr := <-cErr; attachErr != nil {
if _, ok := err.(term.EscapeError); ok { if _, ok := attachErr.(term.EscapeError); ok {
// The user entered the detach escape sequence. // The user entered the detach escape sequence.
return nil return nil
} }

View File

@ -208,7 +208,9 @@ func runStats(dockerCli command.Cli, opts *statsOptions) error {
} }
var err 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() cleanScreen()
ccstats := []StatsEntry{} ccstats := []StatsEntry{}
cStats.mu.Lock() cStats.mu.Lock()

View File

@ -263,6 +263,7 @@ func TestCreateFromContext(t *testing.T) {
cli.SetCurrentContext("dummy") cli.SetCurrentContext("dummy")
for _, c := range cases { for _, c := range cases {
c := c
t.Run(c.name, func(t *testing.T) { t.Run(c.name, func(t *testing.T) {
cli.ResetOutputBuffers() cli.ResetOutputBuffers()
err := RunCreate(cli, &CreateOptions{ err := RunCreate(cli, &CreateOptions{
@ -339,6 +340,7 @@ func TestCreateFromCurrent(t *testing.T) {
cli.SetCurrentContext("original") cli.SetCurrentContext("original")
for _, c := range cases { for _, c := range cases {
c := c
t.Run(c.name, func(t *testing.T) { t.Run(c.name, func(t *testing.T) {
cli.ResetOutputBuffers() cli.ResetOutputBuffers()
err := RunCreate(cli, &CreateOptions{ err := RunCreate(cli, &CreateOptions{

View File

@ -304,7 +304,8 @@ func TestContainerContextWriteWithNoContainers(t *testing.T) {
} }
for _, context := range contexts { 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())) assert.Check(t, is.Equal(context.expected, out.String()))
// Clean buffer // Clean buffer
out.Reset() out.Reset()

View File

@ -348,7 +348,8 @@ func TestImageContextWriteWithNoImage(t *testing.T) {
} }
for _, context := range contexts { 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())) assert.Check(t, is.Equal(context.expected, out.String()))
// Clean buffer // Clean buffer
out.Reset() out.Reset()

View File

@ -1,16 +1,14 @@
package idresolver package idresolver
import ( import (
"context"
"testing" "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/docker/docker/api/types/swarm"
"github.com/pkg/errors"
"gotest.tools/assert" "gotest.tools/assert"
is "gotest.tools/assert/cmp" 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) { func TestResolveError(t *testing.T) {

View File

@ -474,7 +474,7 @@ func runBuild(dockerCli command.Cli, options buildOptions) error {
// should be just the image ID and we'll print that to stdout. // should be just the image ID and we'll print that to stdout.
if options.quiet { if options.quiet {
imageID = fmt.Sprintf("%s", buildBuff) imageID = fmt.Sprintf("%s", buildBuff)
fmt.Fprintf(dockerCli.Out(), imageID) _, _ = fmt.Fprint(dockerCli.Out(), imageID)
} }
if options.imageIDFile != "" { if options.imageIDFile != "" {

View File

@ -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 // getWithStatusError does an http.Get() and returns an error if the
// status code is 4xx or 5xx. // status code is 4xx or 5xx.
func getWithStatusError(url string) (resp *http.Response, err error) { func getWithStatusError(url string) (resp *http.Response, err error) {
// #nosec G107
if resp, err = http.Get(url); err != nil { if resp, err = http.Get(url); err != nil {
return nil, err return nil, err
} }
@ -344,7 +345,6 @@ func getDockerfileRelPath(absContextDir, givenDockerfile string) (string, error)
absDockerfile, err = filepath.EvalSymlinks(absDockerfile) absDockerfile, err = filepath.EvalSymlinks(absDockerfile)
if err != nil { if err != nil {
return "", errors.Errorf("unable to evaluate symlinks in Dockerfile path: %v", err) return "", errors.Errorf("unable to evaluate symlinks in Dockerfile path: %v", err)
} }
} }

View File

@ -24,12 +24,12 @@ var prepareEmpty = func(t *testing.T) (string, func()) {
} }
var prepareNoFiles = 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()) { var prepareOneFile = func(t *testing.T) (string, func()) {
contextDir, cleanup := createTestTempDir(t, "", "builder-context-test") contextDir, cleanup := createTestTempDir(t, "builder-context-test")
createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents, 0777) createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents)
return contextDir, cleanup return contextDir, cleanup
} }
@ -42,7 +42,7 @@ func testValidateContextDirectory(t *testing.T, prepare func(t *testing.T) (stri
} }
func TestGetContextFromLocalDirNoDockerfile(t *testing.T) { func TestGetContextFromLocalDirNoDockerfile(t *testing.T) {
contextDir, cleanup := createTestTempDir(t, "", "builder-context-test") contextDir, cleanup := createTestTempDir(t, "builder-context-test")
defer cleanup() defer cleanup()
_, _, err := GetContextFromLocalDir(contextDir, "") _, _, err := GetContextFromLocalDir(contextDir, "")
@ -50,7 +50,7 @@ func TestGetContextFromLocalDirNoDockerfile(t *testing.T) {
} }
func TestGetContextFromLocalDirNotExistingDir(t *testing.T) { func TestGetContextFromLocalDirNotExistingDir(t *testing.T) {
contextDir, cleanup := createTestTempDir(t, "", "builder-context-test") contextDir, cleanup := createTestTempDir(t, "builder-context-test")
defer cleanup() defer cleanup()
fakePath := filepath.Join(contextDir, "fake") fakePath := filepath.Join(contextDir, "fake")
@ -60,7 +60,7 @@ func TestGetContextFromLocalDirNotExistingDir(t *testing.T) {
} }
func TestGetContextFromLocalDirNotExistingDockerfile(t *testing.T) { func TestGetContextFromLocalDirNotExistingDockerfile(t *testing.T) {
contextDir, cleanup := createTestTempDir(t, "", "builder-context-test") contextDir, cleanup := createTestTempDir(t, "builder-context-test")
defer cleanup() defer cleanup()
fakePath := filepath.Join(contextDir, "fake") fakePath := filepath.Join(contextDir, "fake")
@ -70,10 +70,10 @@ func TestGetContextFromLocalDirNotExistingDockerfile(t *testing.T) {
} }
func TestGetContextFromLocalDirWithNoDirectory(t *testing.T) { func TestGetContextFromLocalDirWithNoDirectory(t *testing.T) {
contextDir, dirCleanup := createTestTempDir(t, "", "builder-context-test") contextDir, dirCleanup := createTestTempDir(t, "builder-context-test")
defer dirCleanup() defer dirCleanup()
createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents, 0777) createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents)
chdirCleanup := chdir(t, contextDir) chdirCleanup := chdir(t, contextDir)
defer chdirCleanup() defer chdirCleanup()
@ -86,10 +86,10 @@ func TestGetContextFromLocalDirWithNoDirectory(t *testing.T) {
} }
func TestGetContextFromLocalDirWithDockerfile(t *testing.T) { func TestGetContextFromLocalDirWithDockerfile(t *testing.T) {
contextDir, cleanup := createTestTempDir(t, "", "builder-context-test") contextDir, cleanup := createTestTempDir(t, "builder-context-test")
defer cleanup() defer cleanup()
createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents, 0777) createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents)
absContextDir, relDockerfile, err := GetContextFromLocalDir(contextDir, "") absContextDir, relDockerfile, err := GetContextFromLocalDir(contextDir, "")
assert.NilError(t, err) assert.NilError(t, err)
@ -99,11 +99,11 @@ func TestGetContextFromLocalDirWithDockerfile(t *testing.T) {
} }
func TestGetContextFromLocalDirLocalFile(t *testing.T) { func TestGetContextFromLocalDirLocalFile(t *testing.T) {
contextDir, cleanup := createTestTempDir(t, "", "builder-context-test") contextDir, cleanup := createTestTempDir(t, "builder-context-test")
defer cleanup() defer cleanup()
createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents, 0777) createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents)
testFilename := createTestTempFile(t, contextDir, "tmpTest", "test", 0777) testFilename := createTestTempFile(t, contextDir, "tmpTest", "test")
absContextDir, relDockerfile, err := GetContextFromLocalDir(testFilename, "") absContextDir, relDockerfile, err := GetContextFromLocalDir(testFilename, "")
@ -121,13 +121,13 @@ func TestGetContextFromLocalDirLocalFile(t *testing.T) {
} }
func TestGetContextFromLocalDirWithCustomDockerfile(t *testing.T) { func TestGetContextFromLocalDirWithCustomDockerfile(t *testing.T) {
contextDir, cleanup := createTestTempDir(t, "", "builder-context-test") contextDir, cleanup := createTestTempDir(t, "builder-context-test")
defer cleanup() defer cleanup()
chdirCleanup := chdir(t, contextDir) chdirCleanup := chdir(t, contextDir)
defer chdirCleanup() defer chdirCleanup()
createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents, 0777) createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents)
absContextDir, relDockerfile, err := GetContextFromLocalDir(contextDir, DefaultDockerfileName) absContextDir, relDockerfile, err := GetContextFromLocalDir(contextDir, DefaultDockerfileName)
assert.NilError(t, err) assert.NilError(t, err)
@ -173,10 +173,10 @@ func TestGetContextFromReaderString(t *testing.T) {
} }
func TestGetContextFromReaderTar(t *testing.T) { func TestGetContextFromReaderTar(t *testing.T) {
contextDir, cleanup := createTestTempDir(t, "", "builder-context-test") contextDir, cleanup := createTestTempDir(t, "builder-context-test")
defer cleanup() defer cleanup()
createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents, 0777) createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents)
tarStream, err := archive.Tar(contextDir, archive.Uncompressed) tarStream, err := archive.Tar(contextDir, archive.Uncompressed)
assert.NilError(t, err) assert.NilError(t, err)
@ -241,17 +241,18 @@ func TestValidateContextDirectoryWithOneFileExcludes(t *testing.T) {
// createTestTempDir creates a temporary directory for testing. // 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. // 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. // When an error occurs, it terminates the test.
func createTestTempDir(t *testing.T, dir, prefix string) (string, func()) { //nolint: unparam
path, err := ioutil.TempDir(dir, prefix) func createTestTempDir(t *testing.T, prefix string) (string, func()) {
path, err := ioutil.TempDir("", prefix)
assert.NilError(t, err) assert.NilError(t, err)
return path, func() { assert.NilError(t, os.RemoveAll(path)) } return path, func() { assert.NilError(t, os.RemoveAll(path)) }
} }
// createTestTempFile creates a temporary file within dir with specific contents and permissions. // createTestTempFile creates a temporary file within dir with specific contents and permissions.
// When an error occurs, it terminates the test // 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) filePath := filepath.Join(dir, filename)
err := ioutil.WriteFile(filePath, []byte(contents), perm) err := ioutil.WriteFile(filePath, []byte(contents), 0777)
assert.NilError(t, err) assert.NilError(t, err)
return filePath return filePath
} }

View File

@ -476,16 +476,13 @@ func parseSecret(value string) (*secretsprovider.FileSource, error) {
func parseSSHSpecs(sl []string) (session.Attachable, error) { func parseSSHSpecs(sl []string) (session.Attachable, error) {
configs := make([]sshprovider.AgentConfig, 0, len(sl)) configs := make([]sshprovider.AgentConfig, 0, len(sl))
for _, v := range sl { for _, v := range sl {
c, err := parseSSH(v) c := parseSSH(v)
if err != nil {
return nil, err
}
configs = append(configs, *c) configs = append(configs, *c)
} }
return sshprovider.NewSSHAgentProvider(configs) return sshprovider.NewSSHAgentProvider(configs)
} }
func parseSSH(value string) (*sshprovider.AgentConfig, error) { func parseSSH(value string) *sshprovider.AgentConfig {
parts := strings.SplitN(value, "=", 2) parts := strings.SplitN(value, "=", 2)
cfg := sshprovider.AgentConfig{ cfg := sshprovider.AgentConfig{
ID: parts[0], ID: parts[0],
@ -493,5 +490,5 @@ func parseSSH(value string) (*sshprovider.AgentConfig, error) {
if len(parts) > 1 { if len(parts) > 1 {
cfg.Paths = strings.Split(parts[1], ",") cfg.Paths = strings.Split(parts[1], ",")
} }
return &cfg, nil return &cfg
} }

View File

@ -35,16 +35,13 @@ func isSessionSupported(dockerCli command.Cli, forStream bool) bool {
} }
func trySession(dockerCli command.Cli, contextDir string, forStream bool) (*session.Session, error) { func trySession(dockerCli command.Cli, contextDir string, forStream bool) (*session.Session, error) {
var s *session.Session if !isSessionSupported(dockerCli, forStream) {
if isSessionSupported(dockerCli, forStream) { return nil, nil
sharedKey, err := getBuildSharedKey(contextDir) }
if err != nil { sharedKey := getBuildSharedKey(contextDir)
return nil, errors.Wrap(err, "failed to get build shared key") s, err := session.NewSession(context.Background(), filepath.Base(contextDir), sharedKey)
} if err != nil {
s, err = session.NewSession(context.Background(), filepath.Base(contextDir), sharedKey) return nil, errors.Wrap(err, "failed to create session")
if err != nil {
return nil, errors.Wrap(err, "failed to create session")
}
} }
return s, nil return s, nil
} }
@ -130,10 +127,10 @@ func (bw *bufferedWriter) String() string {
return fmt.Sprintf("%s", bw.Writer) return fmt.Sprintf("%s", bw.Writer)
} }
func getBuildSharedKey(dir string) (string, error) { func getBuildSharedKey(dir string) string {
// build session is hash of build dir with node based randomness // build session is hash of build dir with node based randomness
s := sha256.Sum256([]byte(fmt.Sprintf("%s:%s", tryNodeIdentifier(), dir))) s := sha256.Sum256([]byte(fmt.Sprintf("%s:%s", tryNodeIdentifier(), dir)))
return hex.EncodeToString(s[:]), nil return hex.EncodeToString(s[:])
} }
func tryNodeIdentifier() string { func tryNodeIdentifier() string {

View File

@ -5,11 +5,10 @@ import (
"testing" "testing"
"github.com/docker/cli/internal/test" "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/docker/docker/api/types/swarm"
"github.com/pkg/errors" "github.com/pkg/errors"
"gotest.tools/assert" "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) { func TestNodeDemoteErrors(t *testing.T) {

View File

@ -6,11 +6,10 @@ import (
"testing" "testing"
"github.com/docker/cli/internal/test" "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"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"github.com/pkg/errors" "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/assert"
"gotest.tools/golden" "gotest.tools/golden"
) )

View File

@ -6,14 +6,13 @@ import (
"github.com/docker/cli/cli/config/configfile" "github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/internal/test" "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"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"github.com/pkg/errors" "github.com/pkg/errors"
"gotest.tools/assert" "gotest.tools/assert"
is "gotest.tools/assert/cmp" is "gotest.tools/assert/cmp"
"gotest.tools/golden" "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) { func TestNodeListErrorOnAPIFailure(t *testing.T) {

View File

@ -5,11 +5,10 @@ import (
"testing" "testing"
"github.com/docker/cli/internal/test" "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/docker/docker/api/types/swarm"
"github.com/pkg/errors" "github.com/pkg/errors"
"gotest.tools/assert" "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) { func TestNodePromoteErrors(t *testing.T) {

View File

@ -8,11 +8,10 @@ import (
"time" "time"
"github.com/docker/cli/internal/test" "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"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"github.com/pkg/errors" "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/assert"
"gotest.tools/golden" "gotest.tools/golden"
) )

View File

@ -5,11 +5,10 @@ import (
"testing" "testing"
"github.com/docker/cli/internal/test" "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/docker/docker/api/types/swarm"
"github.com/pkg/errors" "github.com/pkg/errors"
"gotest.tools/assert" "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) { func TestNodeUpdateErrors(t *testing.T) {

View File

@ -58,7 +58,7 @@ func TestListErrors(t *testing.T) {
} }
func TestList(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{ return types.PluginsListResponse{
{ {
ID: "id-foo", ID: "id-foo",
@ -113,7 +113,7 @@ func TestList(t *testing.T) {
"format": "{{ .ID }}", "format": "{{ .ID }}",
}, },
golden: "plugin-list-with-no-trunc-option.golden", 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{ return types.PluginsListResponse{
{ {
ID: "xyg4z2hiSLO5yTnBJfg4OYia9gKA6Qjd", ID: "xyg4z2hiSLO5yTnBJfg4OYia9gKA6Qjd",
@ -142,7 +142,7 @@ func TestList(t *testing.T) {
"format": "{{ .Name }}", "format": "{{ .Name }}",
}, },
golden: "plugin-list-sort.golden", golden: "plugin-list-sort.golden",
listFunc: func(filter filters.Args) (types.PluginsListResponse, error) { listFunc: func(_ filters.Args) (types.PluginsListResponse, error) {
return types.PluginsListResponse{ return types.PluginsListResponse{
{ {
ID: "id-1", ID: "id-1",

View File

@ -69,7 +69,7 @@ func TestLoginWithCredStoreCreds(t *testing.T) {
} }
ctx := context.Background() ctx := context.Background()
for _, tc := range testCases { for _, tc := range testCases {
cli := (*test.FakeCli)(test.NewFakeCli(&fakeClient{})) cli := test.NewFakeCli(&fakeClient{})
errBuf := new(bytes.Buffer) errBuf := new(bytes.Buffer)
cli.SetErr(errBuf) cli.SetErr(errBuf)
loginWithCredStoreCreds(ctx, cli, &tc.inputAuthConfig) loginWithCredStoreCreds(ctx, cli, &tc.inputAuthConfig)
@ -166,7 +166,7 @@ func TestRunLogin(t *testing.T) {
if tc.inputStoredCred != nil { if tc.inputStoredCred != nil {
cred := *tc.inputStoredCred cred := *tc.inputStoredCred
configfile.GetCredentialsStore(cred.ServerAddress).Store(cred) assert.NilError(t, configfile.GetCredentialsStore(cred.ServerAddress).Store(cred))
} }
loginErr := runLogin(cli, tc.inputLoginOption) loginErr := runLogin(cli, tc.inputLoginOption)
if tc.expectedErr != "" { if tc.expectedErr != "" {

View File

@ -13,7 +13,7 @@ import (
) )
const ( 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" secretIDHeader = "ID"
secretCreatedHeader = "CREATED" secretCreatedHeader = "CREATED"
secretUpdatedHeader = "UPDATED" secretUpdatedHeader = "UPDATED"

View File

@ -7,10 +7,9 @@ import (
"time" "time"
"github.com/docker/cli/internal/test" "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/docker/docker/api/types/swarm"
"github.com/pkg/errors" "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/assert"
"gotest.tools/golden" "gotest.tools/golden"
) )

View File

@ -7,11 +7,10 @@ import (
"github.com/docker/cli/cli/config/configfile" "github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/internal/test" "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"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"github.com/pkg/errors" "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/assert"
is "gotest.tools/assert/cmp" is "gotest.tools/assert/cmp"
"gotest.tools/golden" "gotest.tools/golden"

View File

@ -3,11 +3,10 @@ package service
import ( import (
"context" "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"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/client" "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 { type fakeClient struct {

View File

@ -202,9 +202,9 @@ func TestToServiceNetwork(t *testing.T) {
} }
nwo := opts.NetworkOpt{} nwo := opts.NetworkOpt{}
nwo.Set("zzz-network") assert.NilError(t, nwo.Set("zzz-network"))
nwo.Set("mmm-network") assert.NilError(t, nwo.Set("mmm-network"))
nwo.Set("aaa-network") assert.NilError(t, nwo.Set("aaa-network"))
o := newServiceOptions() o := newServiceOptions()
o.mode = "replicated" o.mode = "replicated"

View File

@ -28,7 +28,7 @@ func TestUpdateServiceArgs(t *testing.T) {
cspec := spec.TaskTemplate.ContainerSpec cspec := spec.TaskTemplate.ContainerSpec
cspec.Args = []string{"old", "args"} 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)) 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 // Update with --read-only=true, changed to true
flags := newUpdateCommand(nil).Flags() flags := newUpdateCommand(nil).Flags()
flags.Set("read-only", "true") flags.Set("read-only", "true")
updateService(nil, nil, flags, spec) updateService(context.TODO(), nil, flags, spec)
assert.Check(t, cspec.ReadOnly) assert.Check(t, cspec.ReadOnly)
// Update without --read-only, no change // Update without --read-only, no change
flags = newUpdateCommand(nil).Flags() flags = newUpdateCommand(nil).Flags()
updateService(nil, nil, flags, spec) updateService(context.TODO(), nil, flags, spec)
assert.Check(t, cspec.ReadOnly) assert.Check(t, cspec.ReadOnly)
// Update with --read-only=false, changed to false // Update with --read-only=false, changed to false
flags = newUpdateCommand(nil).Flags() flags = newUpdateCommand(nil).Flags()
flags.Set("read-only", "false") flags.Set("read-only", "false")
updateService(nil, nil, flags, spec) updateService(context.TODO(), nil, flags, spec)
assert.Check(t, !cspec.ReadOnly) assert.Check(t, !cspec.ReadOnly)
} }
@ -558,18 +558,18 @@ func TestUpdateInit(t *testing.T) {
// Update with --init=true // Update with --init=true
flags := newUpdateCommand(nil).Flags() flags := newUpdateCommand(nil).Flags()
flags.Set("init", "true") flags.Set("init", "true")
updateService(nil, nil, flags, spec) updateService(context.TODO(), nil, flags, spec)
assert.Check(t, is.Equal(true, *cspec.Init)) assert.Check(t, is.Equal(true, *cspec.Init))
// Update without --init, no change // Update without --init, no change
flags = newUpdateCommand(nil).Flags() flags = newUpdateCommand(nil).Flags()
updateService(nil, nil, flags, spec) updateService(context.TODO(), nil, flags, spec)
assert.Check(t, is.Equal(true, *cspec.Init)) assert.Check(t, is.Equal(true, *cspec.Init))
// Update with --init=false // Update with --init=false
flags = newUpdateCommand(nil).Flags() flags = newUpdateCommand(nil).Flags()
flags.Set("init", "false") flags.Set("init", "false")
updateService(nil, nil, flags, spec) updateService(context.TODO(), nil, flags, spec)
assert.Check(t, is.Equal(false, *cspec.Init)) assert.Check(t, is.Equal(false, *cspec.Init))
} }
@ -584,18 +584,18 @@ func TestUpdateStopSignal(t *testing.T) {
// Update with --stop-signal=SIGUSR1 // Update with --stop-signal=SIGUSR1
flags := newUpdateCommand(nil).Flags() flags := newUpdateCommand(nil).Flags()
flags.Set("stop-signal", "SIGUSR1") flags.Set("stop-signal", "SIGUSR1")
updateService(nil, nil, flags, spec) updateService(context.TODO(), nil, flags, spec)
assert.Check(t, is.Equal("SIGUSR1", cspec.StopSignal)) assert.Check(t, is.Equal("SIGUSR1", cspec.StopSignal))
// Update without --stop-signal, no change // Update without --stop-signal, no change
flags = newUpdateCommand(nil).Flags() flags = newUpdateCommand(nil).Flags()
updateService(nil, nil, flags, spec) updateService(context.TODO(), nil, flags, spec)
assert.Check(t, is.Equal("SIGUSR1", cspec.StopSignal)) assert.Check(t, is.Equal("SIGUSR1", cspec.StopSignal))
// Update with --stop-signal=SIGWINCH // Update with --stop-signal=SIGWINCH
flags = newUpdateCommand(nil).Flags() flags = newUpdateCommand(nil).Flags()
flags.Set("stop-signal", "SIGWINCH") flags.Set("stop-signal", "SIGWINCH")
updateService(nil, nil, flags, spec) updateService(context.TODO(), nil, flags, spec)
assert.Check(t, is.Equal("SIGWINCH", cspec.StopSignal)) assert.Check(t, is.Equal("SIGWINCH", cspec.StopSignal))
} }

View File

@ -195,6 +195,7 @@ func TestHandlePullSecret(t *testing.T) {
} }
for _, c := range cases { for _, c := range cases {
c := c
t.Run(c.version, func(t *testing.T) { t.Run(c.version, func(t *testing.T) {
conv, err := NewStackConverter(c.version) conv, err := NewStackConverter(c.version)
assert.NilError(t, err) assert.NilError(t, err)
@ -222,6 +223,7 @@ func TestHandlePullPolicy(t *testing.T) {
} }
for _, c := range cases { for _, c := range cases {
c := c
t.Run(c.version, func(t *testing.T) { t.Run(c.version, func(t *testing.T) {
conv, err := NewStackConverter(c.version) conv, err := NewStackConverter(c.version)
assert.NilError(t, err) assert.NilError(t, err)
@ -271,6 +273,7 @@ func TestHandleInternalServiceType(t *testing.T) {
}, },
} }
for _, c := range cases { for _, c := range cases {
c := c
t.Run(c.name, func(t *testing.T) { t.Run(c.name, func(t *testing.T) {
res, err := fromComposeServiceConfig(composetypes.ServiceConfig{ res, err := fromComposeServiceConfig(composetypes.ServiceConfig{
Name: "test", Name: "test",

View File

@ -56,16 +56,16 @@ func TestCreateChildResourcesV1Beta1(t *testing.T) {
secrets)) secrets))
c, err := configs.Get("test", metav1.GetOptions{}) c, err := configs.Get("test", metav1.GetOptions{})
assert.NilError(t, err) 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{}) s, err := secrets.Get("test", metav1.GetOptions{})
assert.NilError(t, err) 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() t.Helper()
assert.Equal(t, len(objMeta.OwnerReferences), 1) 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].Kind, "Stack")
assert.Equal(t, objMeta.OwnerReferences[0].APIVersion, stackVersion) assert.Equal(t, objMeta.OwnerReferences[0].APIVersion, stackVersion)
} }
@ -82,10 +82,10 @@ func TestCreateChildResourcesV1Beta2(t *testing.T) {
secrets)) secrets))
c, err := configs.Get("test", metav1.GetOptions{}) c, err := configs.Get("test", metav1.GetOptions{})
assert.NilError(t, err) 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{}) s, err := secrets.Get("test", metav1.GetOptions{})
assert.NilError(t, err) assert.NilError(t, err)
checkOwnerReferences(t, s.ObjectMeta, "test", v1beta2.SchemeGroupVersion.String()) checkOwnerReferences(t, s.ObjectMeta, v1beta2.SchemeGroupVersion.String())
} }
func TestCreateChildResourcesV1Alpha3(t *testing.T) { func TestCreateChildResourcesV1Alpha3(t *testing.T) {
@ -100,10 +100,10 @@ func TestCreateChildResourcesV1Alpha3(t *testing.T) {
secrets)) secrets))
c, err := configs.Get("test", metav1.GetOptions{}) c, err := configs.Get("test", metav1.GetOptions{})
assert.NilError(t, err) 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{}) s, err := secrets.Get("test", metav1.GetOptions{})
assert.NilError(t, err) assert.NilError(t, err)
checkOwnerReferences(t, s.ObjectMeta, "test", v1alpha3.SchemeGroupVersion.String()) checkOwnerReferences(t, s.ObjectMeta, v1alpha3.SchemeGroupVersion.String())
} }
func TestCreateChildResourcesWithStackCreationErrorV1Beta1(t *testing.T) { func TestCreateChildResourcesWithStackCreationErrorV1Beta1(t *testing.T) {

View File

@ -29,7 +29,7 @@ func GetStacks(kubeCli *KubeCli, opts options.List) ([]*formatter.Stack, error)
} }
func isAllNamespacesDisabled(kubeCliConfig *configfile.KubernetesConfig) bool { 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) { func getStacks(kubeCli *KubeCli, opts options.List) ([]*formatter.Stack, error) {

View File

@ -41,11 +41,13 @@ func newTestPodAndStackRepository(initialPods []apiv1.Pod, initialStacks []apiv1
o := k8stesting.NewObjectTracker(scheme, codecs.UniversalDecoder()) o := k8stesting.NewObjectTracker(scheme, codecs.UniversalDecoder())
for _, obj := range initialPods { for _, obj := range initialPods {
obj := obj
if err := o.Add(&obj); err != nil { if err := o.Add(&obj); err != nil {
panic(err) panic(err)
} }
} }
for _, obj := range initialStacks { for _, obj := range initialStacks {
obj := obj
if err := o.Add(&obj); err != nil { if err := o.Add(&obj); err != nil {
panic(err) panic(err)
} }

View File

@ -6,8 +6,7 @@ import (
"github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command"
"github.com/docker/cli/internal/test" "github.com/docker/cli/internal/test"
// Import builders to get the builder function as package function . "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function
. "github.com/docker/cli/internal/test/builders"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"github.com/pkg/errors" "github.com/pkg/errors"

View File

@ -7,8 +7,7 @@ import (
"github.com/docker/cli/cli/config/configfile" "github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/internal/test" "github.com/docker/cli/internal/test"
// Import builders to get the builder function as package function . "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function
. "github.com/docker/cli/internal/test/builders"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"github.com/pkg/errors" "github.com/pkg/errors"

View File

@ -6,8 +6,7 @@ import (
"github.com/docker/cli/cli/config/configfile" "github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/internal/test" "github.com/docker/cli/internal/test"
// Import builders to get the builder function as package function . "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function
. "github.com/docker/cli/internal/test/builders"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"github.com/pkg/errors" "github.com/pkg/errors"

View File

@ -6,11 +6,10 @@ import (
"testing" "testing"
"github.com/docker/cli/internal/test" "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"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"github.com/pkg/errors" "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/assert"
"gotest.tools/golden" "gotest.tools/golden"
) )

View File

@ -6,11 +6,10 @@ import (
"testing" "testing"
"github.com/docker/cli/internal/test" "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"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"github.com/pkg/errors" "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/assert"
"gotest.tools/golden" "gotest.tools/golden"
) )

View File

@ -7,12 +7,10 @@ import (
"time" "time"
"github.com/docker/cli/internal/test" "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"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"github.com/pkg/errors" "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/assert"
"gotest.tools/golden" "gotest.tools/golden"
) )

View File

@ -88,9 +88,7 @@ func runInfo(cmd *cobra.Command, dockerCli command.Cli, opts *infoOptions) error
func prettyPrintInfo(dockerCli command.Cli, info info) error { func prettyPrintInfo(dockerCli command.Cli, info info) error {
fmt.Fprintln(dockerCli.Out(), "Client:") fmt.Fprintln(dockerCli.Out(), "Client:")
if info.ClientInfo != nil { if info.ClientInfo != nil {
if err := prettyPrintClientInfo(dockerCli, *info.ClientInfo); err != nil { prettyPrintClientInfo(dockerCli, *info.ClientInfo)
info.ClientErrors = append(info.ClientErrors, err.Error())
}
} }
for _, err := range info.ClientErrors { for _, err := range info.ClientErrors {
fmt.Fprintln(dockerCli.Out(), "ERROR:", err) fmt.Fprintln(dockerCli.Out(), "ERROR:", err)
@ -113,7 +111,7 @@ func prettyPrintInfo(dockerCli command.Cli, info info) error {
return nil 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) fmt.Fprintln(dockerCli.Out(), " Debug Mode:", info.Debug)
if len(info.Plugins) > 0 { if len(info.Plugins) > 0 {
@ -134,8 +132,6 @@ func prettyPrintClientInfo(dockerCli command.Cli, info clientInfo) error {
if len(info.Warnings) > 0 { if len(info.Warnings) > 0 {
fmt.Fprintln(dockerCli.Err(), strings.Join(info.Warnings, "\n")) fmt.Fprintln(dockerCli.Err(), strings.Join(info.Warnings, "\n"))
} }
return nil
} }
// nolint: gocyclo // nolint: gocyclo

View File

@ -8,8 +8,7 @@ import (
"github.com/docker/cli/cli/command/formatter" "github.com/docker/cli/cli/command/formatter"
"github.com/docker/cli/cli/command/idresolver" "github.com/docker/cli/cli/command/idresolver"
"github.com/docker/cli/internal/test" "github.com/docker/cli/internal/test"
// Import builders to get the builder function as package function . "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function
. "github.com/docker/cli/internal/test/builders"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"gotest.tools/assert" "gotest.tools/assert"

View File

@ -393,11 +393,6 @@ func TestGetSignerRolesWithKeyIDs(t *testing.T) {
"bob": {"key71", "key72"}, "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) signerRoleToKeyIDs := getDelegationRoleToKeyMap(roles)
assert.Check(t, is.DeepEqual(expectedSignerRoleToKeyIDs, signerRoleToKeyIDs)) assert.Check(t, is.DeepEqual(expectedSignerRoleToKeyIDs, signerRoleToKeyIDs))
} }

View File

@ -88,7 +88,7 @@ func validateAndGenerateKey(streams command.Streams, keyName string, workingDir
pubPEM, err := generateKeyAndOutputPubPEM(keyName, privKeyFileStore) pubPEM, err := generateKeyAndOutputPubPEM(keyName, privKeyFileStore)
if err != nil { 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) 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 return pem.Block{}, err
} }
privKeyStore.AddKey(trustmanager.KeyInfo{Role: data.RoleName(keyName)}, privKey) if err := privKeyStore.AddKey(trustmanager.KeyInfo{Role: data.RoleName(keyName)}, privKey); err != nil {
if err != nil {
return pem.Block{}, err return pem.Block{}, err
} }

View File

@ -117,6 +117,7 @@ var testKeys = map[string][]byte{
func TestLoadKeyFromPath(t *testing.T) { func TestLoadKeyFromPath(t *testing.T) {
skip.If(t, runtime.GOOS == "windows") skip.If(t, runtime.GOOS == "windows")
for keyID, keyBytes := range testKeys { for keyID, keyBytes := range testKeys {
keyID, keyBytes := keyID, keyBytes
t.Run(fmt.Sprintf("load-key-id-%s-from-path", keyID), func(t *testing.T) { t.Run(fmt.Sprintf("load-key-id-%s-from-path", keyID), func(t *testing.T) {
testLoadKeyFromPath(t, keyID, keyBytes) testLoadKeyFromPath(t, keyID, keyBytes)
}) })
@ -172,6 +173,7 @@ func testLoadKeyFromPath(t *testing.T, privKeyID string, privKeyFixture []byte)
func TestLoadKeyTooPermissive(t *testing.T) { func TestLoadKeyTooPermissive(t *testing.T) {
skip.If(t, runtime.GOOS == "windows") skip.If(t, runtime.GOOS == "windows")
for keyID, keyBytes := range testKeys { for keyID, keyBytes := range testKeys {
keyID, keyBytes := keyID, keyBytes
t.Run(fmt.Sprintf("load-key-id-%s-too-permissive", keyID), func(t *testing.T) { t.Run(fmt.Sprintf("load-key-id-%s-too-permissive", keyID), func(t *testing.T) {
testLoadKeyTooPermissive(t, keyBytes) testLoadKeyTooPermissive(t, keyBytes)
}) })

View File

@ -116,7 +116,7 @@ func TestGetOrGenerateNotaryKey(t *testing.T) {
assert.Check(t, is.DeepEqual(rootKeyA.Public(), rootKeyB.Public())) assert.Check(t, is.DeepEqual(rootKeyA.Public(), rootKeyB.Public()))
// Now also try with a delegation key // 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.NilError(t, err)
assert.Check(t, releasesKey != nil) assert.Check(t, releasesKey != nil)

View File

@ -78,7 +78,7 @@ func PromptForConfirmation(ins io.Reader, outs io.Writer, message string) bool {
} }
message += " [y/N] " message += " [y/N] "
fmt.Fprintf(outs, message) _, _ = fmt.Fprint(outs, message)
// On Windows, force the use of the regular OS stdin stream. // On Windows, force the use of the regular OS stdin stream.
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {

View File

@ -6,10 +6,9 @@ import (
"testing" "testing"
"github.com/docker/cli/internal/test" "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"
"github.com/pkg/errors" "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/assert"
"gotest.tools/golden" "gotest.tools/golden"
) )

View File

@ -6,12 +6,11 @@ import (
"github.com/docker/cli/cli/config/configfile" "github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/internal/test" "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"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
volumetypes "github.com/docker/docker/api/types/volume" volumetypes "github.com/docker/docker/api/types/volume"
"github.com/pkg/errors" "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/assert"
"gotest.tools/golden" "gotest.tools/golden"
) )

View File

@ -109,7 +109,7 @@ func Secrets(namespace Namespace, secrets map[string]composetypes.SecretConfig)
var obj swarmFileObject var obj swarmFileObject
var err error var err error
if secret.Driver != "" { if secret.Driver != "" {
obj, err = driverObjectConfig(namespace, name, composetypes.FileObjectConfig(secret)) obj = driverObjectConfig(namespace, name, composetypes.FileObjectConfig(secret))
} else { } else {
obj, err = fileObjectConfig(namespace, name, composetypes.FileObjectConfig(secret)) obj, err = fileObjectConfig(namespace, name, composetypes.FileObjectConfig(secret))
} }
@ -161,7 +161,7 @@ type swarmFileObject struct {
Data []byte 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 != "" { if obj.Name != "" {
name = obj.Name name = obj.Name
} else { } else {
@ -174,7 +174,7 @@ func driverObjectConfig(namespace Namespace, name string, obj composetypes.FileO
Labels: AddStackLabel(namespace, obj.Labels), Labels: AddStackLabel(namespace, obj.Labels),
}, },
Data: []byte{}, Data: []byte{},
}, nil }
} }
func fileObjectConfig(namespace Namespace, name string, obj composetypes.FileObjectConfig) (swarmFileObject, error) { func fileObjectConfig(namespace Namespace, name string, obj composetypes.FileObjectConfig) (swarmFileObject, error) {

View File

@ -66,11 +66,7 @@ func Service(
configs []*swarm.ConfigReference, configs []*swarm.ConfigReference,
) (swarm.ServiceSpec, error) { ) (swarm.ServiceSpec, error) {
name := namespace.Scope(service.Name) name := namespace.Scope(service.Name)
endpoint := convertEndpointSpec(service.Deploy.EndpointMode, service.Ports)
endpoint, err := convertEndpointSpec(service.Deploy.EndpointMode, service.Ports)
if err != nil {
return swarm.ServiceSpec{}, err
}
mode, err := convertDeployMode(service.Deploy.Mode, service.Deploy.Replicas) mode, err := convertDeployMode(service.Deploy.Mode, service.Deploy.Replicas)
if err != nil { if err != nil {
@ -103,10 +99,7 @@ func Service(
return swarm.ServiceSpec{}, err return swarm.ServiceSpec{}, err
} }
dnsConfig, err := convertDNSConfig(service.DNS, service.DNSSearch) dnsConfig := convertDNSConfig(service.DNS, service.DNSSearch)
if err != nil {
return swarm.ServiceSpec{}, err
}
var privileges swarm.Privileges var privileges swarm.Privileges
privileges.CredentialSpec, err = convertCredentialSpec( privileges.CredentialSpec, err = convertCredentialSpec(
@ -575,7 +568,7 @@ func convertResources(source composetypes.Resources) (*swarm.ResourceRequirement
return resources, nil 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{} portConfigs := []swarm.PortConfig{}
for _, port := range source { for _, port := range source {
portConfig := swarm.PortConfig{ portConfig := swarm.PortConfig{
@ -594,7 +587,7 @@ func convertEndpointSpec(endpointMode string, source []composetypes.ServicePortC
return &swarm.EndpointSpec{ return &swarm.EndpointSpec{
Mode: swarm.ResolutionMode(strings.ToLower(endpointMode)), Mode: swarm.ResolutionMode(strings.ToLower(endpointMode)),
Ports: portConfigs, Ports: portConfigs,
}, nil }
} }
func convertEnvironment(source map[string]*string) []string { func convertEnvironment(source map[string]*string) []string {
@ -629,14 +622,14 @@ func convertDeployMode(mode string, replicas *uint64) (swarm.ServiceMode, error)
return serviceMode, nil 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 { if DNS != nil || DNSSearch != nil {
return &swarm.DNSConfig{ return &swarm.DNSConfig{
Nameservers: DNS, Nameservers: DNS,
Search: DNSSearch, Search: DNSSearch,
}, nil }
} }
return nil, nil return nil
} }
func convertCredentialSpec(namespace Namespace, spec composetypes.CredentialSpecConfig, refs []*swarm.ConfigReference) (*swarm.CredentialSpec, error) { func convertCredentialSpec(namespace Namespace, spec composetypes.CredentialSpecConfig, refs []*swarm.ConfigReference) (*swarm.CredentialSpec, error) {

View File

@ -177,7 +177,7 @@ func TestConvertEndpointSpec(t *testing.T) {
Published: 80, Published: 80,
}, },
} }
endpoint, err := convertEndpointSpec("vip", source) endpoint := convertEndpointSpec("vip", source)
expected := swarm.EndpointSpec{ expected := swarm.EndpointSpec{
Mode: swarm.ResolutionMode(strings.ToLower("vip")), 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)) assert.Check(t, is.DeepEqual(expected, *endpoint))
} }
@ -271,13 +270,11 @@ func TestConvertServiceNetworksCustomDefault(t *testing.T) {
} }
assert.NilError(t, err) 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) { func TestConvertDNSConfigEmpty(t *testing.T) {
dnsConfig, err := convertDNSConfig(nil, nil) dnsConfig := convertDNSConfig(nil, nil)
assert.NilError(t, err)
assert.Check(t, is.DeepEqual((*swarm.DNSConfig)(nil), dnsConfig)) assert.Check(t, is.DeepEqual((*swarm.DNSConfig)(nil), dnsConfig))
} }
@ -287,8 +284,7 @@ var (
) )
func TestConvertDNSConfigAll(t *testing.T) { func TestConvertDNSConfigAll(t *testing.T) {
dnsConfig, err := convertDNSConfig(nameservers, search) dnsConfig := convertDNSConfig(nameservers, search)
assert.NilError(t, err)
assert.Check(t, is.DeepEqual(&swarm.DNSConfig{ assert.Check(t, is.DeepEqual(&swarm.DNSConfig{
Nameservers: nameservers, Nameservers: nameservers,
Search: search, Search: search,
@ -296,8 +292,7 @@ func TestConvertDNSConfigAll(t *testing.T) {
} }
func TestConvertDNSConfigNameservers(t *testing.T) { func TestConvertDNSConfigNameservers(t *testing.T) {
dnsConfig, err := convertDNSConfig(nameservers, nil) dnsConfig := convertDNSConfig(nameservers, nil)
assert.NilError(t, err)
assert.Check(t, is.DeepEqual(&swarm.DNSConfig{ assert.Check(t, is.DeepEqual(&swarm.DNSConfig{
Nameservers: nameservers, Nameservers: nameservers,
Search: nil, Search: nil,
@ -305,8 +300,7 @@ func TestConvertDNSConfigNameservers(t *testing.T) {
} }
func TestConvertDNSConfigSearch(t *testing.T) { func TestConvertDNSConfigSearch(t *testing.T) {
dnsConfig, err := convertDNSConfig(nil, search) dnsConfig := convertDNSConfig(nil, search)
assert.NilError(t, err)
assert.Check(t, is.DeepEqual(&swarm.DNSConfig{ assert.Check(t, is.DeepEqual(&swarm.DNSConfig{
Nameservers: nil, Nameservers: nil,
Search: search, Search: search,

View File

@ -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) { func recursiveInterpolate(value interface{}, path Path, opts Options) (interface{}, error) {
switch value := value.(type) { switch value := value.(type) {
case string: case string:
newValue, err := opts.Substitute(value, template.Mapping(opts.LookupValue)) newValue, err := opts.Substitute(value, template.Mapping(opts.LookupValue))
if err != nil || newValue == value { if err != nil || newValue == value {
@ -91,7 +90,6 @@ func recursiveInterpolate(value interface{}, path Path, opts Options) (interface
default: default:
return value, nil return value, nil
} }
} }

View File

@ -297,10 +297,13 @@ func Transform(source interface{}, target interface{}, additionalTransformers ..
return decoder.Decode(source) 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 // Transformer defines a map to type transformer
type Transformer struct { type Transformer struct {
TypeOf reflect.Type TypeOf reflect.Type
Func func(interface{}) (interface{}, error) Func TransformerFunc
} }
func createTransformHook(additionalTransformers ...Transformer) mapstructure.DecodeHookFuncType { func createTransformHook(additionalTransformers ...Transformer) mapstructure.DecodeHookFuncType {
@ -684,7 +687,7 @@ func absPath(workingDir string, filePath string) string {
return filepath.Join(workingDir, filePath) return filepath.Join(workingDir, filePath)
} }
func transformMapStringString(data interface{}) (interface{}, error) { var transformMapStringString TransformerFunc = func(data interface{}) (interface{}, error) {
switch value := data.(type) { switch value := data.(type) {
case map[string]interface{}: case map[string]interface{}:
return toMapStringString(value, false), nil 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) { switch value := data.(type) {
case bool: case bool:
return map[string]interface{}{"external": value}, nil 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) { switch entries := data.(type) {
case []interface{}: case []interface{}:
// We process the list instead of individual items here. // 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) { switch value := data.(type) {
case string: case string:
return map[string]interface{}{"source": value}, nil 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) { switch value := data.(type) {
case string: case string:
return map[string]interface{}{"context": value}, nil 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) { switch value := data.(type) {
case string: case string:
return ParseVolume(value) 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 { if list, ok := value.([]interface{}); ok {
mapValue := map[interface{}]interface{}{} mapValue := map[interface{}]interface{}{}
for _, name := range list { for _, name := range list {
@ -783,7 +786,7 @@ func transformServiceNetworkMap(value interface{}) (interface{}, error) {
return value, nil return value, nil
} }
func transformStringOrNumberList(value interface{}) (interface{}, error) { var transformStringOrNumberList TransformerFunc = func(value interface{}) (interface{}, error) {
list := value.([]interface{}) list := value.([]interface{})
result := make([]string, len(list)) result := make([]string, len(list))
for i, item := range list { for i, item := range list {
@ -792,7 +795,7 @@ func transformStringOrNumberList(value interface{}) (interface{}, error) {
return result, nil return result, nil
} }
func transformStringList(data interface{}) (interface{}, error) { var transformStringList TransformerFunc = func(data interface{}) (interface{}, error) {
switch value := data.(type) { switch value := data.(type) {
case string: case string:
return []string{value}, nil 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 func(data interface{}) (interface{}, error) {
return transformMappingOrList(data, sep, allowNil), nil 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 func(data interface{}) (interface{}, error) {
return transformListOrMapping(data, sep, allowNil), nil 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)) 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 { if str, ok := value.(string); ok {
return shellwords.Parse(str) return shellwords.Parse(str)
} }
return value, nil return value, nil
} }
func transformHealthCheckTest(data interface{}) (interface{}, error) { var transformHealthCheckTest TransformerFunc = func(data interface{}) (interface{}, error) {
switch value := data.(type) { switch value := data.(type) {
case string: case string:
return append([]string{"CMD-SHELL"}, value), nil 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) { switch value := value.(type) {
case int: case int:
return int64(value), nil return int64(value), nil
@ -876,7 +879,7 @@ func transformSize(value interface{}) (interface{}, error) {
panic(errors.Errorf("invalid type for size %T", value)) 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) { switch value := value.(type) {
case string: case string:
d, err := time.ParseDuration(value) d, err := time.ParseDuration(value)

View File

@ -1583,6 +1583,7 @@ services:
}, },
} }
for _, testcase := range testcases { for _, testcase := range testcases {
testcase := testcase
t.Run(testcase.doc, func(t *testing.T) { t.Run(testcase.doc, func(t *testing.T) {
config, err := loadYAML(testcase.yaml) config, err := loadYAML(testcase.yaml)
assert.NilError(t, err) assert.NilError(t, err)

View File

@ -60,6 +60,7 @@ func mergeServices(base, override []types.ServiceConfig) ([]types.ServiceConfig,
}, },
} }
for name, overrideService := range overrideServices { for name, overrideService := range overrideServices {
overrideService := overrideService
if baseService, ok := baseServices[name]; ok { if baseService, ok := baseServices[name]; ok {
if err := mergo.Merge(&baseService, &overrideService, mergo.WithAppendSlice, mergo.WithOverride, mergo.WithTransformers(specials)); err != nil { 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) return base, errors.Wrapf(err, "cannot merge service %s", name)

View File

@ -43,7 +43,8 @@ var winisabstests = []IsAbsTest{
} }
func TestIsAbs(t *testing.T) { func TestIsAbs(t *testing.T) {
tests := append(isabstests, winisabstests...) tests := winisabstests
// All non-windows tests should fail, because they have no volume letter. // All non-windows tests should fail, because they have no volume letter.
for _, test := range isabstests { for _, test := range isabstests {
tests = append(tests, IsAbsTest{test.path, false}) tests = append(tests, IsAbsTest{test.path, false})
@ -53,7 +54,7 @@ func TestIsAbs(t *testing.T) {
tests = append(tests, IsAbsTest{"c:" + test.path, test.isAbs}) tests = append(tests, IsAbsTest{"c:" + test.path, test.isAbs})
} }
for _, test := range winisabstests { for _, test := range tests {
if r := isAbs(test.path); r != test.isAbs { if r := isAbs(test.path); r != test.isAbs {
t.Errorf("IsAbs(%q) = %v, want %v", test.path, r, test.isAbs) t.Errorf("IsAbs(%q) = %v, want %v", test.path, r, test.isAbs)
} }

View File

@ -117,7 +117,6 @@ func TestValidateCredentialSpecs(t *testing.T) {
} }
}) })
} }
} }
func TestValidateSecretConfigNames(t *testing.T) { func TestValidateSecretConfigNames(t *testing.T) {

View File

@ -275,6 +275,7 @@ func TestExtractVariables(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
tc := tc
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
actual := ExtractVariables(tc.dict, defaultPattern) actual := ExtractVariables(tc.dict, defaultPattern)
assert.Check(t, is.DeepEqual(actual, tc.expected)) assert.Check(t, is.DeepEqual(actual, tc.expected))

View File

@ -103,7 +103,7 @@ type Config struct {
Volumes map[string]VolumeConfig `yaml:",omitempty" json:"volumes,omitempty"` Volumes map[string]VolumeConfig `yaml:",omitempty" json:"volumes,omitempty"`
Secrets map[string]SecretConfig `yaml:",omitempty" json:"secrets,omitempty"` Secrets map[string]SecretConfig `yaml:",omitempty" json:"secrets,omitempty"`
Configs map[string]ConfigObjConfig `yaml:",omitempty" json:"configs,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 // MarshalJSON makes Config implement json.Marshaler

View File

@ -454,7 +454,6 @@ func TestJSONWithPsFormatNoFile(t *testing.T) {
if config.PsFormat != `table {{.ID}}\t{{.Label "com.docker.label.cpu"}}` { if config.PsFormat != `table {{.ID}}\t{{.Label "com.docker.label.cpu"}}` {
t.Fatalf("Unknown ps format: %s\n", config.PsFormat) t.Fatalf("Unknown ps format: %s\n", config.PsFormat)
} }
} }
func TestJSONSaveWithNoFile(t *testing.T) { func TestJSONSaveWithNoFile(t *testing.T) {
@ -578,6 +577,7 @@ func TestConfigPath(t *testing.T) {
expectedErr: fmt.Sprintf("is outside of root config directory %q", "dummy"), expectedErr: fmt.Sprintf("is outside of root config directory %q", "dummy"),
}, },
} { } {
tc := tc
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
SetDir(tc.dir) SetDir(tc.dir)
f, err := Path(tc.path...) f, err := Path(tc.path...)

View File

@ -153,8 +153,8 @@ func TestImportTarInvalid(t *testing.T) {
tf := path.Join(testDir, "test.context") tf := path.Join(testDir, "test.context")
f, err := os.Create(tf) f, err := os.Create(tf)
defer f.Close()
assert.NilError(t, err) assert.NilError(t, err)
defer f.Close()
tw := tar.NewWriter(f) tw := tar.NewWriter(f)
hdr := &tar.Header{ hdr := &tar.Header{
@ -186,8 +186,8 @@ func TestImportZip(t *testing.T) {
zf := path.Join(testDir, "test.zip") zf := path.Join(testDir, "test.zip")
f, err := os.Create(zf) f, err := os.Create(zf)
defer f.Close()
assert.NilError(t, err) assert.NilError(t, err)
defer f.Close()
w := zip.NewWriter(f) w := zip.NewWriter(f)
meta, err := json.Marshal(Metadata{ meta, err := json.Marshal(Metadata{
@ -237,8 +237,8 @@ func TestImportZipInvalid(t *testing.T) {
zf := path.Join(testDir, "test.zip") zf := path.Join(testDir, "test.zip")
f, err := os.Create(zf) f, err := os.Create(zf)
defer f.Close()
assert.NilError(t, err) assert.NilError(t, err)
defer f.Close()
w := zip.NewWriter(f) w := zip.NewWriter(f)
df, err := w.Create("dummy-file") df, err := w.Create("dummy-file")

View File

@ -75,5 +75,4 @@ func TestTlsListAndBatchRemove(t *testing.T) {
resEmpty, err := testee.listContextData("test-ctx") resEmpty, err := testee.listContextData("test-ctx")
assert.NilError(t, err) assert.NilError(t, err)
assert.DeepEqual(t, resEmpty, map[string]EndpointFiles{}) assert.DeepEqual(t, resEmpty, map[string]EndpointFiles{})
} }

View File

@ -93,6 +93,7 @@ func TestStoreSaveAndGet(t *testing.T) {
} }
for _, testcase := range testcases { for _, testcase := range testcases {
testcase := testcase
t.Run(testcase.manifestRef.String(), func(t *testing.T) { t.Run(testcase.manifestRef.String(), func(t *testing.T) {
actual, err := store.Get(testcase.listRef, testcase.manifestRef) actual, err := store.Get(testcase.listRef, testcase.manifestRef)
if testcase.expectedErr != "" { if testcase.expectedErr != "" {

View File

@ -11,7 +11,7 @@ import (
"github.com/docker/distribution/manifest/schema2" "github.com/docker/distribution/manifest/schema2"
"github.com/docker/distribution/reference" "github.com/docker/distribution/reference"
"github.com/docker/distribution/registry/api/errcode" "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" distclient "github.com/docker/distribution/registry/client"
"github.com/docker/docker/registry" "github.com/docker/docker/registry"
digest "github.com/opencontainers/go-digest" digest "github.com/opencontainers/go-digest"
@ -103,9 +103,6 @@ func pullManifestSchemaV2ImageConfig(ctx context.Context, dgst digest.Digest, re
} }
verifier := dgst.Verifier() verifier := dgst.Verifier()
if err != nil {
return nil, err
}
if _, err := verifier.Write(configJSON); err != nil { if _, err := verifier.Write(configJSON); err != nil {
return nil, err return nil, err
} }
@ -212,7 +209,6 @@ func (c *client) iterateEndpoints(ctx context.Context, namedRef reference.Named,
confirmedTLSRegistries := make(map[string]bool) confirmedTLSRegistries := make(map[string]bool)
for _, endpoint := range endpoints { for _, endpoint := range endpoints {
if endpoint.Version == registry.APIVersion1 { if endpoint.Version == registry.APIVersion1 {
logrus.Debugf("skipping v1 endpoint %s", endpoint.URL) logrus.Debugf("skipping v1 endpoint %s", endpoint.URL)
continue continue

View File

@ -99,6 +99,7 @@ func ExactArgs(number int) cobra.PositionalArgs {
} }
} }
//nolint: unparam
func pluralize(word string, number int) string { func pluralize(word string, number int) string {
if number == 1 { if number == 1 {
return word return word

View File

@ -1,20 +1,23 @@
# syntax=docker/dockerfile:1.1.3-experimental
ARG GO_VERSION=1.12.12 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 FROM golang:${GO_VERSION}-alpine AS lint
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
ENV CGO_ENABLED=0 ENV CGO_ENABLED=0
ENV DISABLE_WARN_OUTSIDE_CONTAINER=1 ENV DISABLE_WARN_OUTSIDE_CONTAINER=1
ENTRYPOINT ["/usr/local/bin/gometalinter"] COPY --from=build /go/bin/golangci-lint /usr/local/bin
CMD ["--config=gometalinter.json", "./..."] WORKDIR /go/src/github.com/docker/cli
ENV GOGC=75
ENTRYPOINT ["/usr/local/bin/golangci-lint"]
CMD ["run", "--config=.golangci.yml"]
COPY . . COPY . .

View File

@ -131,6 +131,7 @@ func TestUnknownGlobal(t *testing.T) {
"separate-val": {"--unknown", "foo", "helloworld"}, "separate-val": {"--unknown", "foo", "helloworld"},
"joined-val": {"--unknown=foo", "helloworld"}, "joined-val": {"--unknown=foo", "helloworld"},
} { } {
args := args
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
res := icmd.RunCmd(run(args...)) res := icmd.RunCmd(run(args...))
res.Assert(t, icmd.Expected{ res.Assert(t, icmd.Expected{

View File

@ -26,17 +26,17 @@ func TestSigProxyWithTTY(t *testing.T) {
assert.NilError(t, err, "failed to start container") assert.NilError(t, err, "failed to start container")
defer icmd.RunCommand("docker", "container", "rm", "-f", t.Name()) 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 pid := cmd.Process.Pid
t.Logf("terminating PID %d", pid) t.Logf("terminating PID %d", pid)
err = syscall.Kill(pid, syscall.SIGTERM) err = syscall.Kill(pid, syscall.SIGTERM)
assert.NilError(t, err) 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 { return func(poll.LogT) poll.Result {
result := icmd.RunCommand("docker", "inspect", "-f", "{{ .State.Status }}", containerID) 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)) // ignore initial failures as the container may not yet exist (i.e., don't result.Assert(t, icmd.Success))

View File

@ -296,6 +296,7 @@ func createImage(t *testing.T, registryPrefix, repo, tag string) string {
return image return image
} }
//nolint: unparam
func withNotaryPassphrase(pwd string) func(*icmd.Cmd) { func withNotaryPassphrase(pwd string) func(*icmd.Cmd) {
return func(c *icmd.Cmd) { return func(c *icmd.Cmd) {
c.Env = append(c.Env, []string{ c.Env = append(c.Env, []string{

View File

@ -31,7 +31,6 @@ func TestSignLocalImage(t *testing.T) {
fixtures.WithConfig(dir.Path()), fixtures.WithNotary) fixtures.WithConfig(dir.Path()), fixtures.WithNotary)
result.Assert(t, icmd.Success) result.Assert(t, icmd.Success)
assert.Check(t, is.Contains(result.Stdout(), fmt.Sprintf("v1: digest: sha256:%s", fixtures.AlpineSha))) assert.Check(t, is.Contains(result.Stdout(), fmt.Sprintf("v1: digest: sha256:%s", fixtures.AlpineSha)))
} }
func TestSignWithLocalFlag(t *testing.T) { func TestSignWithLocalFlag(t *testing.T) {

View File

@ -1,42 +0,0 @@
{
"Vendor": true,
"Deadline": "2m",
"Sort": ["linter", "severity", "path", "line"],
"Exclude": [
"cli/compose/schema/bindata.go",
"cli/command/stack/kubernetes/api/openapi",
"cli/command/stack/kubernetes/api/client",
".*generated.*",
"parameter .* always receives"
],
"EnableGC": true,
"Linters": {
"nakedret": {
"Command": "nakedret",
"Pattern": "^(?P<path>.*?\\.go):(?P<line>\\d+)\\s*(?P<message>.*)$"
}
},
"WarnUnmatchedDirective": true,
"DisableAll": true,
"Enable": [
"deadcode",
"gocyclo",
"gofmt",
"goimports",
"golint",
"gosimple",
"ineffassign",
"interfacer",
"lll",
"misspell",
"nakedret",
"unconvert",
"unparam",
"unused",
"vet"
],
"Cyclo": 16,
"LineLength": 200
}

View File

@ -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 { 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() { for _, j := range ongoing.jobs() {
key := remotes.MakeRefKey(ctx, j) key := remotes.MakeRefKey(ctx, j)
*keys = append(*keys, key) *keys = append(*keys, key)

View File

@ -16,7 +16,7 @@ import (
"github.com/docker/distribution/reference" "github.com/docker/distribution/reference"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
ver "github.com/hashicorp/go-version" 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" "github.com/pkg/errors"
) )

View File

@ -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) { func (c *fakeLicensingClient) LoadLocalLicense(ctx context.Context, dclnt licensing.WrappedDockerClient) (*model.Subscription, error) {
if c.loadLocalLicenseFunc != nil { if c.loadLocalLicenseFunc != nil {
return c.loadLocalLicenseFunc(ctx, dclnt) return c.loadLocalLicenseFunc(ctx, dclnt)

View File

@ -24,7 +24,6 @@ const (
// GetEngineVersions reports the versions of the engine that are available // 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) { func GetEngineVersions(ctx context.Context, registryClient registryclient.RegistryClient, registryPrefix, imageName, versionString string) (clitypes.AvailableVersions, error) {
if imageName == "" { if imageName == "" {
var err error var err error
localMetadata, err := GetCurrentRuntimeMetadata("") localMetadata, err := GetCurrentRuntimeMetadata("")

View File

@ -69,6 +69,7 @@ func TestNetworkOptAdvancedSyntax(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
tc := tc
t.Run(tc.value, func(t *testing.T) { t.Run(tc.value, func(t *testing.T) {
var network NetworkOpt var network NetworkOpt
assert.NilError(t, network.Set(tc.value)) assert.NilError(t, network.Set(tc.value))
@ -96,6 +97,7 @@ func TestNetworkOptAdvancedSyntaxInvalid(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
tc := tc
t.Run(tc.value, func(t *testing.T) { t.Run(tc.value, func(t *testing.T) {
var network NetworkOpt var network NetworkOpt
assert.ErrorContains(t, network.Set(tc.value), tc.expectedError) assert.ErrorContains(t, network.Set(tc.value), tc.expectedError)

View File

@ -266,6 +266,7 @@ func TestValidateLabel(t *testing.T) {
} }
for _, tc := range tests { for _, tc := range tests {
tc := tc
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
val, err := ValidateLabel(tc.value) val, err := ValidateLabel(tc.value)
if tc.expectedErr != "" { if tc.expectedErr != "" {

View File

@ -48,9 +48,6 @@ func ValidateThrottleIOpsDevice(val string) (*blkiodev.ThrottleDevice, error) {
if err != nil { if err != nil {
return nil, fmt.Errorf("invalid rate for device: %s. The correct format is <device-path>:<number>. Number must be a positive integer", val) return nil, fmt.Errorf("invalid rate for device: %s. The correct format is <device-path>:<number>. Number must be a positive integer", val)
} }
if rate < 0 {
return nil, fmt.Errorf("invalid rate for device: %s. The correct format is <device-path>:<number>. Number must be a positive integer", val)
}
return &blkiodev.ThrottleDevice{Path: split[0], Rate: rate}, nil return &blkiodev.ThrottleDevice{Path: split[0], Rate: rate}, nil
} }

View File

@ -8,7 +8,7 @@ import (
func TestUlimitOpt(t *testing.T) { func TestUlimitOpt(t *testing.T) {
ulimitMap := map[string]*units.Ulimit{ ulimitMap := map[string]*units.Ulimit{
"nofile": {"nofile", 1024, 512}, "nofile": {Name: "nofile", Hard: 1024, Soft: 512},
} }
ulimitOpt := NewUlimitOpt(&ulimitMap) ulimitOpt := NewUlimitOpt(&ulimitMap)

View File

@ -22,6 +22,7 @@ func TestParseLogDetails(t *testing.T) {
{"errors", nil, errors.New("invalid details format")}, {"errors", nil, errors.New("invalid details format")},
} }
for _, testcase := range testCases { for _, testcase := range testCases {
testcase := testcase
t.Run(testcase.line, func(t *testing.T) { t.Run(testcase.line, func(t *testing.T) {
actual, err := ParseLogDetails(testcase.line) actual, err := ParseLogDetails(testcase.line)
if testcase.err != nil { if testcase.err != nil {

View File

@ -65,6 +65,8 @@ func TestParseTruncateFunction(t *testing.T) {
} }
for _, testCase := range testCases { for _, testCase := range testCases {
testCase := testCase
tm, err := Parse(testCase.template) tm, err := Parse(testCase.template)
assert.NilError(t, err) assert.NilError(t, err)