Compare commits

...

63 Commits

Author SHA1 Message Date
Laura Brehm a041983765
Merge f632123c41 into a4228409d2 2024-11-14 09:22:43 +00:00
Sebastiaan van Stijn a4228409d2
Merge pull request #5608 from thaJeztah/go1.22_buildtags
update go:build tags to use go1.22
2024-11-12 14:12:00 +01:00
Sebastiaan van Stijn 7c80e4f938
update go:build tags to use go1.22
commit 4a7b04d412 configured golangci-lint
to use go1.23 semantics, which enabled the copyloopvar linter.

go1.22 now creates a copy of variables when assigned in a loop; make sure we
don't have files that may downgrade semantics to go1.21 in case that also means
disabling that feature; https://go.dev/ref/spec#Go_1.22

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-12 12:38:18 +01:00
Sebastiaan van Stijn 917d2dc837
Merge pull request #5601 from vvoland/update-go
update to go1.23.3
2024-11-07 14:42:18 +01:00
Sebastiaan van Stijn f9497b8a46
Merge pull request #5600 from aevesdocker/desktop-link-fix
docs: change link to desktop docs
2024-11-07 13:56:47 +01:00
Paweł Gronowski 382d4c34a9
update to go1.23.3
- https://github.com/golang/go/issues?q=milestone%3AGo1.23.3+label%3ACherryPickApproved
- full diff: https://github.com/golang/go/compare/go1.23.2...go1.23.3

go1.23.3 (released 2024-11-06) includes fixes to the linker, the
runtime, and the net/http, os, and syscall packages. See the
[Go 1.23.3 milestone](https://github.com/golang/go/issues?q=milestone%3AGo1.23.3+label%3ACherryPickApproved)
for details.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2024-11-07 13:24:16 +01:00
aevesdocker 1440f9f8cf docs: change link to desktop docs
Signed-off-by: aevesdocker <allie.sadler@docker.com>
2024-11-07 09:38:19 +00:00
Sebastiaan van Stijn 9c01d924fb
Merge pull request #5595 from dvdksn/docs-redis-example-tags
docs: update example redis tags from 3.0.x to 7.4.x
2024-11-06 15:52:12 +01:00
Sebastiaan van Stijn 8c22315e31
Merge pull request #5596 from laurazard/update-jwt-dep-v4
deps: update `go-jose/go-jose` to `v4`
2024-11-05 15:29:00 +01:00
Laura Brehm 13754f6776
deps: update `go-jose/go-jose` to `v4`
See: https://github.com/go-jose/go-jose

Signed-off-by: Laura Brehm <laurabrehm@hey.com>
2024-11-05 14:12:16 +00:00
Sebastiaan van Stijn 9eb7b52189
Merge pull request #5594 from thaJeztah/fix_golangci_go_version
golangci-lint: set go version to prevent fallback to go1.17, and fix copyloopvar linting issues
2024-11-05 11:24:44 +01:00
David Karlsson 172f340112 docs: update example redis tags from 3.0.x to 7.4.x
Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
2024-11-05 11:20:17 +01:00
Sebastiaan van Stijn 750b8ebcdc
Merge pull request #5590 from thaJeztah/bump_engine_28
vendor: github.com/docker/docker 6ac445c42bad (master, v28.0-dev)
2024-11-05 10:21:26 +01:00
Sebastiaan van Stijn 4a7b04d412
golangci-lint: set go version to prevent fallback to go1.17
GolangCI-lint attempts to deduct the Go version to lint for through the
go version specified in go.mod, which we don't have, and therefore it
falls back to go1.17 semantics:

    level=warning msg="[linters_context] copyloopvar: this linter is disabled because the Go version (1.17) of your project is lower than Go 1.22

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-05 10:15:36 +01:00
Sebastiaan van Stijn d77760fe53
cli-plugins/manager: remove redundant capturing of loop vars (copyloopvar)
go1.22 and up now produce a unique variable in loops, tehrefore no longer
requiring to capture the variable manually;

    cli-plugins/manager/cobra.go:55:4: The copy of the 'for' variable "p" can be deleted (Go 1.22+) (copyloopvar)
                p := p
                ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-05 10:14:32 +01:00
Sebastiaan van Stijn 32b40deb46
cli/command/service: remove redundant capturing of loop vars (copyloopvar)
go1.22 and up now produce a unique variable in loops, tehrefore no longer
requiring to capture the variable manually;

    cli/command/service/update.go:1061:3: The copy of the 'for' variable "entry" can be deleted (Go 1.22+) (copyloopvar)
            entry := entry
            ^
    cli/command/service/update.go:1089:4: The copy of the 'for' variable "port" can be deleted (Go 1.22+) (copyloopvar)
                port := port
                ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-05 10:14:32 +01:00
Sebastiaan van Stijn 40833fd296
cli/compose/loader: remove redundant capturing of loop vars (copyloopvar)
go1.22 and up now produce a unique variable in loops, tehrefore no longer
requiring to capture the variable manually;

    cli/compose/loader/merge.go:71:3: The copy of the 'for' variable "overrideService" can be deleted (Go 1.22+) (copyloopvar)
            overrideService := overrideService
            ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-05 10:14:32 +01:00
Sebastiaan van Stijn 78a7e15032
cli/command/container: remove redundant capturing of loop vars (copyloopvar)
go1.22 and up now produce a unique variable in loops, tehrefore no longer
requiring to capture the variable manually;

    cli/command/container/opts.go:765:3: The copy of the 'for' variable "n" can be deleted (Go 1.22+) (copyloopvar)
            n := n
            ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-05 10:14:32 +01:00
Sebastiaan van Stijn 4a71ce02e6
cli/command/image: remove redundant capturing of loop vars (copyloopvar)
go1.22 and up now produce a unique variable in loops, tehrefore no longer
requiring to capture the variable manually;

    cli/command/image/tree.go:59:4: The copy of the 'for' variable "im" can be deleted (Go 1.22+) (copyloopvar)
                im := im
                ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-05 10:14:31 +01:00
Sebastiaan van Stijn 7d9ea25564
templates: remove redundant capturing of loop vars in tests (copyloopvar)
go1.22 and up now produce a unique variable in loops, tehrefore no longer
requiring to capture the variable manually;

    service/logs/parse_logs_test.go:50:3: The copy of the 'for' variable "tc" can be deleted (Go 1.22+) (copyloopvar)
            tc := tc
            ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-05 10:14:31 +01:00
Sebastiaan van Stijn 046ac9714c
service: remove redundant capturing of loop vars in tests (copyloopvar)
go1.22 and up now produce a unique variable in loops, tehrefore no longer
requiring to capture the variable manually;

    service/logs/parse_logs_test.go:50:3: The copy of the 'for' variable "tc" can be deleted (Go 1.22+) (copyloopvar)
            tc := tc
            ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-05 10:14:31 +01:00
Sebastiaan van Stijn 762b5a8df3
opts: remove redundant capturing of loop vars in tests (copyloopvar)
go1.22 and up now produce a unique variable in loops, tehrefore no longer
requiring to capture the variable manually;

    service/logs/parse_logs_test.go:50:3: The copy of the 'for' variable "tc" can be deleted (Go 1.22+) (copyloopvar)
            tc := tc
            ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-05 10:14:31 +01:00
Sebastiaan van Stijn 417974cdc3
cmd/docker: remove redundant capturing of loop vars in tests (copyloopvar)
go1.22 and up now produce a unique variable in loops, tehrefore no longer
requiring to capture the variable manually;

    service/logs/parse_logs_test.go:50:3: The copy of the 'for' variable "tc" can be deleted (Go 1.22+) (copyloopvar)
            tc := tc
            ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-05 10:14:31 +01:00
Sebastiaan van Stijn bf37e26b33
cli/manifest: remove redundant capturing of loop vars in tests (copyloopvar)
go1.22 and up now produce a unique variable in loops, tehrefore no longer
requiring to capture the variable manually;

    service/logs/parse_logs_test.go:50:3: The copy of the 'for' variable "tc" can be deleted (Go 1.22+) (copyloopvar)
            tc := tc
            ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-05 10:14:30 +01:00
Sebastiaan van Stijn 6489a777e5
e2e: remove redundant capturing of loop vars in tests (copyloopvar)
go1.22 and up now produce a unique variable in loops, tehrefore no longer
requiring to capture the variable manually;

    service/logs/parse_logs_test.go:50:3: The copy of the 'for' variable "tc" can be deleted (Go 1.22+) (copyloopvar)
            tc := tc
            ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-05 10:14:30 +01:00
Sebastiaan van Stijn 20de861134
cli/config: remove redundant capturing of loop vars in tests (copyloopvar)
go1.22 and up now produce a unique variable in loops, tehrefore no longer
requiring to capture the variable manually;

    service/logs/parse_logs_test.go:50:3: The copy of the 'for' variable "tc" can be deleted (Go 1.22+) (copyloopvar)
            tc := tc
            ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-05 10:14:30 +01:00
Sebastiaan van Stijn 1448cecba1
cli/compose: remove redundant capturing of loop vars in tests (copyloopvar)
go1.22 and up now produce a unique variable in loops, tehrefore no longer
requiring to capture the variable manually;

    service/logs/parse_logs_test.go:50:3: The copy of the 'for' variable "tc" can be deleted (Go 1.22+) (copyloopvar)
            tc := tc
            ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-05 10:14:30 +01:00
Sebastiaan van Stijn 67458f710d
cli/command: remove redundant capturing of loop vars in tests (copyloopvar)
go1.22 and up now produce a unique variable in loops, tehrefore no longer
requiring to capture the variable manually;

    service/logs/parse_logs_test.go:50:3: The copy of the 'for' variable "tc" can be deleted (Go 1.22+) (copyloopvar)
            tc := tc
            ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-05 10:14:30 +01:00
Sebastiaan van Stijn b45477bffa
Merge pull request #5591 from noahsilas/docs-run-exit-code
docs: Correct `run` exit code 126 description
2024-11-04 17:27:25 +01:00
Noah Silas 0c999fe95b docs: Correct `run` exit code 126 description
The command to run inside the container is `/etc`. The semicolon is a
statement terminator, which ends the command `docker run busybox /etc`,
while `echo $?` prints the exit code of that full docker command.

Having this mistake could confuse someone who thinks that `/etc; echo
$?` is all run inside the container, which wouldn't help the reader
understand the exit code of the `docker run` command itself.

Signed-off-by: Noah Silas <noah@hustle.com>
2024-11-04 00:21:33 +00:00
Sebastiaan van Stijn 5f1311ae8d
vendor: github.com/docker/docker 6ac445c42bad (master, v28.0-dev)
full diff: 36a3bd0904...6ac445c42b

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-01 14:10:15 +01:00
Sebastiaan van Stijn 10c5a57927
vendor: go.opentelemetry.io/contrib/instrumentation/xxx v0.53.0
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-01 14:10:09 +01:00
Sebastiaan van Stijn 5e40d288c7
vendor: go.opentelemetry.io/otel v1.28.0
aligning all related packages to v1.28.0 as well

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-01 14:08:45 +01:00
Sebastiaan van Stijn 9ba73a1a05
vendor: github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0
full diff: https://github.com/grpc-ecosystem/grpc-gateway/compare/v2.16.0...v2.20.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-01 14:04:41 +01:00
Sebastiaan van Stijn f3cf1b4213
vendor: go.etcd.io/etcd/raft/v3 v3.5.16
no changes in vendored code

full diff: https://github.com/etcd-io/etcd/compare/v3.5.6...v3.5.16

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-01 13:54:25 +01:00
Sebastiaan van Stijn cae19e3928
vendor: github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6
no changes in vendored code

full diff: ced1acdcaa...e8a1dd7889

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-01 13:46:38 +01:00
Sebastiaan van Stijn 074d1028b5
vendor: update prometheus dependencies
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-01 13:44:05 +01:00
Sebastiaan van Stijn 1dbcce2057
vendor: google.golang.org/grpc v1.67.1
full diff:

- https://github.com/grpc/grpc-go/compare/v1.66.2...v1.67.1
- ef581f9131...5fefd90f89

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-01 13:39:15 +01:00
Sebastiaan van Stijn 1bba009944
vendor: google.golang.org/protobuf v1.35.1
full diff: https://github.com/protocolbuffers/protobuf-go/compare/v1.34.1...v1.35.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-01 13:31:29 +01:00
Sebastiaan van Stijn e3942d46a0
vendor: github.com/klauspost/compress v1.17.11
full diff: https://github.com/klauspost/compress/compare/v1.17.9...v1.17.11

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-01 13:28:47 +01:00
Sebastiaan van Stijn 97ff1b7c0a
vendor: github.com/go-logr/logr v1.4.2
full diff: https://github.com/go-logr/logr/compare/v1.4.1...v1.4.2

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-01 13:25:17 +01:00
Sebastiaan van Stijn 4c85feb4dd
vendor: github.com/cenkalti/backoff/v4 v4.3.0
full diff: https://github.com/cenkalti/backoff/compare/v4.2.1...v4.3.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-01 13:23:39 +01:00
Sebastiaan van Stijn 3b48a57b04
vendor: github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161
documentation changes only, no changes in vendored code

full diff: d185dfc1b5...306776ec81

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-01 13:20:48 +01:00
Sebastiaan van Stijn 36e6c42977
vendor: golang.org/x/net v0.30.0
full diff: https://github.com/golang/net/compare/v0.29.0...v0.30.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-01 13:17:57 +01:00
Sebastiaan van Stijn 84bfa52a6c
vendor: golang.org/x/crypto v0.28.0
no changes in vendored code

full diff: https://github.com/golang/crypto/compare/v0.27.0...v0.28.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-01 13:16:26 +01:00
Sebastiaan van Stijn 7a94f592ed
vendor: golang.org/x/text v0.19.0
no changes in vendored code

full diff: https://github.com/golang/text/compare/v0.18.0...v0.19.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-01 13:14:25 +01:00
Sebastiaan van Stijn ef197f7314
vendor: golang.org/x/term v0.25.0
no changes in vendored code

full diff: https://github.com/golang/term/compare/v0.24.0...v0.25.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-01 13:12:59 +01:00
Sebastiaan van Stijn 02b92c699d
vendor: golang.org/x/sys v0.26.0
full diff: https://github.com/golang/sys/compare/v0.25.0...v0.26.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-01 13:11:15 +01:00
Laura Brehm 2995631498
Merge pull request #5586 from Giedriusj1/master 2024-10-31 13:29:09 +00:00
Paweł Gronowski fb103cb982
Merge pull request #5583 from thaJeztah/bump_golang_1.23.2
update to go1.23.2
2024-10-31 13:10:28 +00:00
Sebastiaan van Stijn 42cda38840
update to go1.23.2
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-10-31 13:04:02 +01:00
Sebastiaan van Stijn 5e51513a8b
Merge pull request #5585 from thaJeztah/bump_golangci_lint
bump golangci-lint to v1.61.0 and cleanup config
2024-10-31 13:03:00 +01:00
Giedrius Jonikas 0b16070ae6 Buffer 'docker stats' text to avoid terminal flickering
This change reduces the flickering of the terminal when
running `docker stats` by buffering the formatted stats
text and printing it in one write.

Should also consume less CPU as we now only have to issue
a single syscall to write the stats text to the terminal.

Signed-off-by: Giedrius Jonikas <giedriusj1@gmail.com>
2024-10-31 11:23:57 +00:00
Sebastiaan van Stijn 9af049c618
bump golangci-lint to v1.61.0
Also updating a linter that was deprecated;

    The linter 'exportloopref' is deprecated (since v1.60.2) due to: Since Go1.22 (loopvar) this linter is no longer relevant. Replaced by copyloopvar.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-10-30 15:54:47 +01:00
Sebastiaan van Stijn 745629bd55
golangci-lint: update comment, and disable "exclude-dirs-use-default"
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-10-30 15:52:18 +01:00
Sebastiaan van Stijn 7451339ab0
golangci-lint: move gosec excludes to linters-settings
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-10-30 15:52:18 +01:00
Sebastiaan van Stijn 020f3a7ad9
golangci-lint: enable G204, add #nosec comments instead
There's only 3 locations where it's hit, so putting #gosec ignore comments
in those locations.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-10-30 15:52:18 +01:00
Sebastiaan van Stijn aa331e94cc
Merge pull request #5579 from thaJeztah/remove_warning
cli/command/container: parse: remove client-side warning
2024-10-30 10:50:34 +01:00
Sebastiaan van Stijn 1875d9fdcb
Merge pull request #5538 from albers/completion-events--filter
Completion for `events --filter`
2024-10-29 17:58:16 +01:00
Harald Albers e1c5180dba Add tests for completions that call the API
Signed-off-by: Harald Albers <github@albersweb.de>
2024-10-29 15:58:17 +00:00
Harald Albers d4f4cf1418 Add completion for `events --filter`
Signed-off-by: Harald Albers <github@albersweb.de>
2024-10-29 15:58:17 +00:00
Sebastiaan van Stijn 59b90305f7
cli/command/container: parse: remove client-side warning
remove a client-side warning about volume drivers combined with "mounts"
in favor of producing the warning on the daemon side.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-10-28 23:13:31 +01:00
Laura Brehm f632123c41
WIP: add configurable detach delay to logs
Signed-off-by: Laura Brehm <laurabrehm@hey.com>
2024-07-30 15:01:19 +01:00
736 changed files with 35168 additions and 9889 deletions

View File

@ -62,7 +62,7 @@ jobs:
name: Update Go name: Update Go
uses: actions/setup-go@v5 uses: actions/setup-go@v5
with: with:
go-version: 1.22.8 go-version: 1.23.3
- -
name: Initialize CodeQL name: Initialize CodeQL
uses: github/codeql-action/init@v3 uses: github/codeql-action/init@v3

View File

@ -68,7 +68,7 @@ jobs:
name: Set up Go name: Set up Go
uses: actions/setup-go@v5 uses: actions/setup-go@v5
with: with:
go-version: 1.22.8 go-version: 1.23.3
- -
name: Test name: Test
run: | run: |

View File

@ -1,12 +1,12 @@
linters: linters:
enable: enable:
- bodyclose - bodyclose
- copyloopvar # Detects places where loop variables are copied.
- depguard - depguard
- dogsled - dogsled
- dupword # Detects duplicate words. - dupword # Detects duplicate words.
- durationcheck - durationcheck
- errchkjson - errchkjson
- exportloopref # Detects pointers to enclosing loop variables.
- gocritic # Metalinter; detects bugs, performance, and styling issues. - gocritic # Metalinter; detects bugs, performance, and styling issues.
- gocyclo - gocyclo
- gofumpt # Detects whether code was gofumpt-ed. - gofumpt # Detects whether code was gofumpt-ed.
@ -41,6 +41,9 @@ linters:
- errcheck - errcheck
run: run:
# prevent golangci-lint from deducting the go version to lint for through go.mod,
# which causes it to fallback to go1.17 semantics.
go: "1.23.3"
timeout: 5m timeout: 5m
linters-settings: linters-settings:
@ -52,6 +55,13 @@ linters-settings:
desc: The io/ioutil package has been deprecated, see https://go.dev/doc/go1.16#ioutil desc: The io/ioutil package has been deprecated, see https://go.dev/doc/go1.16#ioutil
gocyclo: gocyclo:
min-complexity: 16 min-complexity: 16
gosec:
excludes:
- G104 # G104: Errors unhandled; (TODO: reduce unhandled errors, or explicitly ignore)
- G113 # G113: Potential uncontrolled memory consumption in Rat.SetString (CVE-2022-23772); (only affects go < 1.16.14. and go < 1.17.7)
- G115 # G115: integer overflow conversion; (TODO: verify these: https://github.com/docker/cli/issues/5584)
- G306 # G306: Expect WriteFile permissions to be 0600 or less (too restrictive; also flags "0o644" permissions)
- G307 # G307: Deferring unsafe method "*os.File" on type "Close" (also EXC0008); (TODO: evaluate these and fix where needed: G307: Deferring unsafe method "*os.File" on type "Close")
govet: govet:
enable: enable:
- shadow - shadow
@ -87,6 +97,10 @@ issues:
# The default exclusion rules are a bit too permissive, so copying the relevant ones below # The default exclusion rules are a bit too permissive, so copying the relevant ones below
exclude-use-default: false exclude-use-default: false
# This option has been defined when Go modules was not existed and when the
# golangci-lint core was different, this is not something we still recommend.
exclude-dirs-use-default: false
exclude: exclude:
- parameter .* always receives - parameter .* always receives
@ -104,6 +118,9 @@ issues:
# #
# These exclusion patterns are copied from the default excluses at: # These exclusion patterns are copied from the default excluses at:
# https://github.com/golangci/golangci-lint/blob/v1.44.0/pkg/config/issues.go#L10-L104 # https://github.com/golangci/golangci-lint/blob/v1.44.0/pkg/config/issues.go#L10-L104
#
# The default list of exclusions can be found at:
# https://golangci-lint.run/usage/false-positives/#default-exclusions
# EXC0001 # EXC0001
- text: "Error return value of .((os\\.)?std(out|err)\\..*|.*Close|.*Flush|os\\.Remove(All)?|.*print(f|ln)?|os\\.(Un)?Setenv). is not checked" - text: "Error return value of .((os\\.)?std(out|err)\\..*|.*Close|.*Flush|os\\.Remove(All)?|.*print(f|ln)?|os\\.(Un)?Setenv). is not checked"
@ -121,11 +138,6 @@ issues:
- text: "Subprocess launch(ed with variable|ing should be audited)" - text: "Subprocess launch(ed with variable|ing should be audited)"
linters: linters:
- gosec - gosec
# EXC0008
# TODO: evaluate these and fix where needed: G307: Deferring unsafe method "*os.File" on type "Close" (gosec)
- text: "G307"
linters:
- gosec
# EXC0009 # EXC0009
- text: "(Expect directory permissions to be 0750 or less|Expect file permissions to be 0600 or less)" - text: "(Expect directory permissions to be 0750 or less|Expect file permissions to be 0600 or less)"
linters: linters:
@ -135,26 +147,6 @@ issues:
linters: linters:
- gosec - gosec
# G113 Potential uncontrolled memory consumption in Rat.SetString (CVE-2022-23772)
# only affects gp < 1.16.14. and go < 1.17.7
- text: "G113"
linters:
- gosec
# TODO: G104: Errors unhandled. (gosec)
- text: "G104"
linters:
- gosec
# Looks like the match in "EXC0007" above doesn't catch this one
# TODO: consider upstreaming this to golangci-lint's default exclusion rules
- text: "G204: Subprocess launched with a potential tainted input or cmd arguments"
linters:
- gosec
# Looks like the match in "EXC0009" above doesn't catch this one
# TODO: consider upstreaming this to golangci-lint's default exclusion rules
- text: "G306: Expect WriteFile permissions to be 0600 or less"
linters:
- gosec
# TODO: make sure all packages have a description. Currently, there's 67 packages without. # TODO: make sure all packages have a description. Currently, there's 67 packages without.
- text: "package-comments: should have a package comment" - text: "package-comments: should have a package comment"
linters: linters:

View File

@ -4,7 +4,7 @@ ARG BASE_VARIANT=alpine
ARG ALPINE_VERSION=3.20 ARG ALPINE_VERSION=3.20
ARG BASE_DEBIAN_DISTRO=bookworm ARG BASE_DEBIAN_DISTRO=bookworm
ARG GO_VERSION=1.22.8 ARG GO_VERSION=1.23.3
ARG XX_VERSION=1.5.0 ARG XX_VERSION=1.5.0
ARG GOVERSIONINFO_VERSION=v1.3.0 ARG GOVERSIONINFO_VERSION=v1.3.0
ARG GOTESTSUM_VERSION=v1.10.0 ARG GOTESTSUM_VERSION=v1.10.0

View File

@ -17,5 +17,5 @@ func (c *candidate) Path() string {
} }
func (c *candidate) Metadata() ([]byte, error) { func (c *candidate) Metadata() ([]byte, error) {
return exec.Command(c.path, MetadataSubcommandName).Output() return exec.Command(c.path, MetadataSubcommandName).Output() // #nosec G204 -- ignore "Subprocess launched with a potential tainted input or cmd arguments"
} }

View File

@ -52,7 +52,6 @@ func AddPluginCommandStubs(dockerCli command.Cli, rootCmd *cobra.Command) (err e
return return
} }
for _, p := range plugins { for _, p := range plugins {
p := p
vendor := p.Vendor vendor := p.Vendor
if vendor == "" { if vendor == "" {
vendor = "unknown" vendor = "unknown"

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.21 //go:build go1.22
package manager package manager

View File

@ -240,7 +240,8 @@ func PluginRunCommand(dockerCli command.Cli, name string, rootcmd *cobra.Command
// TODO: why are we not returning plugin.Err? // TODO: why are we not returning plugin.Err?
return nil, errPluginNotFound(name) return nil, errPluginNotFound(name)
} }
cmd := exec.Command(plugin.Path, args...) cmd := exec.Command(plugin.Path, args...) // #nosec G204 -- ignore "Subprocess launched with a potential tainted input or cmd arguments"
// Using dockerCli.{In,Out,Err}() here results in a hang until something is input. // Using dockerCli.{In,Out,Err}() here results in a hang until something is input.
// See: - https://github.com/golang/go/issues/10338 // See: - https://github.com/golang/go/issues/10338
// - https://github.com/golang/go/commit/d000e8742a173aa0659584aa01b7ba2834ba28ab // - https://github.com/golang/go/commit/d000e8742a173aa0659584aa01b7ba2834ba28ab

View File

@ -112,7 +112,7 @@ func (p *Plugin) RunHook(ctx context.Context, hookData HookPluginData) ([]byte,
return nil, wrapAsPluginError(err, "failed to marshall hook data") return nil, wrapAsPluginError(err, "failed to marshall hook data")
} }
pCmd := exec.CommandContext(ctx, p.Path, p.Name, HookSubcommandName, string(hDataBytes)) pCmd := exec.CommandContext(ctx, p.Path, p.Name, HookSubcommandName, string(hDataBytes)) // #nosec G204 -- ignore "Subprocess launched with a potential tainted input or cmd arguments"
pCmd.Env = os.Environ() pCmd.Env = os.Environ()
pCmd.Env = append(pCmd.Env, ReexecEnvvar+"="+os.Args[0]) pCmd.Env = append(pCmd.Env, ReexecEnvvar+"="+os.Args[0])
hookCmdOutput, err := pCmd.Output() hookCmdOutput, err := pCmd.Output()

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.21 //go:build go1.22
package command package command

View File

@ -187,19 +187,18 @@ func TestInitializeFromClient(t *testing.T) {
}, },
} }
for _, testcase := range testcases { for _, tc := range testcases {
testcase := testcase t.Run(tc.doc, func(t *testing.T) {
t.Run(testcase.doc, func(t *testing.T) {
apiclient := &fakeClient{ apiclient := &fakeClient{
pingFunc: testcase.pingFunc, pingFunc: tc.pingFunc,
version: defaultVersion, version: defaultVersion,
} }
cli := &DockerCli{client: apiclient} cli := &DockerCli{client: apiclient}
err := cli.Initialize(flags.NewClientOptions()) err := cli.Initialize(flags.NewClientOptions())
assert.NilError(t, err) assert.NilError(t, err)
assert.DeepEqual(t, cli.ServerInfo(), testcase.expectedServer) assert.DeepEqual(t, cli.ServerInfo(), tc.expectedServer)
assert.Equal(t, apiclient.negotiated, testcase.negotiated) assert.Equal(t, apiclient.negotiated, tc.negotiated)
}) })
} }
} }
@ -277,10 +276,9 @@ func TestExperimentalCLI(t *testing.T) {
}, },
} }
for _, testcase := range testcases { for _, tc := range testcases {
testcase := testcase t.Run(tc.doc, func(t *testing.T) {
t.Run(testcase.doc, func(t *testing.T) { dir := fs.NewDir(t, tc.doc, fs.WithFile("config.json", tc.configfile))
dir := fs.NewDir(t, testcase.doc, fs.WithFile("config.json", testcase.configfile))
defer dir.Remove() defer dir.Remove()
apiclient := &fakeClient{ apiclient := &fakeClient{
version: defaultVersion, version: defaultVersion,

View File

@ -150,7 +150,6 @@ func TestCompleteContainerNames(t *testing.T) {
} }
for _, tc := range tests { for _, tc := range tests {
tc := tc
t.Run(tc.doc, func(t *testing.T) { t.Run(tc.doc, func(t *testing.T) {
if tc.showIDs { if tc.showIDs {
t.Setenv("DOCKER_COMPLETION_SHOW_CONTAINER_IDS", "yes") t.Setenv("DOCKER_COMPLETION_SHOW_CONTAINER_IDS", "yes")
@ -227,7 +226,6 @@ func TestCompleteImageNames(t *testing.T) {
} }
for _, tc := range tests { for _, tc := range tests {
tc := tc
t.Run(tc.doc, func(t *testing.T) { t.Run(tc.doc, func(t *testing.T) {
comp := ImageNames(fakeCLI{&fakeClient{ comp := ImageNames(fakeCLI{&fakeClient{
imageListFunc: func(options image.ListOptions) ([]image.Summary, error) { imageListFunc: func(options image.ListOptions) ([]image.Summary, error) {
@ -273,7 +271,6 @@ func TestCompleteNetworkNames(t *testing.T) {
} }
for _, tc := range tests { for _, tc := range tests {
tc := tc
t.Run(tc.doc, func(t *testing.T) { t.Run(tc.doc, func(t *testing.T) {
comp := NetworkNames(fakeCLI{&fakeClient{ comp := NetworkNames(fakeCLI{&fakeClient{
networkListFunc: func(ctx context.Context, options network.ListOptions) ([]network.Summary, error) { networkListFunc: func(ctx context.Context, options network.ListOptions) ([]network.Summary, error) {
@ -331,7 +328,6 @@ func TestCompleteVolumeNames(t *testing.T) {
} }
for _, tc := range tests { for _, tc := range tests {
tc := tc
t.Run(tc.doc, func(t *testing.T) { t.Run(tc.doc, func(t *testing.T) {
comp := VolumeNames(fakeCLI{&fakeClient{ comp := VolumeNames(fakeCLI{&fakeClient{
volumeListFunc: func(filter filters.Args) (volume.ListResponse, error) { volumeListFunc: func(filter filters.Args) (volume.ListResponse, error) {

View File

@ -43,7 +43,6 @@ func TestConfigCreateErrors(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
tc := tc
t.Run(tc.expectedError, func(t *testing.T) { t.Run(tc.expectedError, func(t *testing.T) {
cmd := newConfigCreateCommand( cmd := newConfigCreateCommand(
test.NewFakeCli(&fakeClient{ test.NewFakeCli(&fakeClient{

View File

@ -61,7 +61,6 @@ id_rsa
}, },
} }
for _, tc := range cases { for _, tc := range cases {
tc := tc
t.Run(string(tc.context.Format), func(t *testing.T) { t.Run(string(tc.context.Format), func(t *testing.T) {
var out bytes.Buffer var out bytes.Buffer
tc.context.Output = &out tc.context.Output = &out

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.21 //go:build go1.22
package config package config

View File

@ -73,7 +73,6 @@ func TestNewAttachCommandErrors(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) {
cmd := NewAttachCommand(test.NewFakeCli(&fakeClient{inspectFunc: tc.containerInspectFunc})) cmd := NewAttachCommand(test.NewFakeCli(&fakeClient{inspectFunc: tc.containerInspectFunc}))
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)

View File

@ -178,7 +178,6 @@ func TestSplitCpArg(t *testing.T) {
}, },
} }
for _, tc := range testcases { for _, tc := range testcases {
tc := tc
t.Run(tc.doc, func(t *testing.T) { t.Run(tc.doc, func(t *testing.T) {
if tc.os == "windows" && runtime.GOOS != "windows" { if tc.os == "windows" && runtime.GOOS != "windows" {
t.Skip("skipping windows test on non-windows platform") t.Skip("skipping windows test on non-windows platform")

View File

@ -113,7 +113,6 @@ func TestCreateContainerImagePullPolicy(t *testing.T) {
}, },
} }
for _, tc := range cases { for _, tc := range cases {
tc := tc
t.Run(tc.PullPolicy, func(t *testing.T) { t.Run(tc.PullPolicy, func(t *testing.T) {
pullCounter := 0 pullCounter := 0
@ -176,7 +175,6 @@ func TestCreateContainerImagePullPolicyInvalid(t *testing.T) {
}, },
} }
for _, tc := range cases { for _, tc := range cases {
tc := tc
t.Run(tc.PullPolicy, func(t *testing.T) { t.Run(tc.PullPolicy, func(t *testing.T) {
dockerCli := test.NewFakeCli(&fakeClient{}) dockerCli := test.NewFakeCli(&fakeClient{})
err := runCreate( err := runCreate(
@ -207,7 +205,6 @@ func TestCreateContainerValidateFlags(t *testing.T) {
expectedErr: `invalid argument "STDINFO" for "-a, --attach" flag: valid streams are STDIN, STDOUT and STDERR`, expectedErr: `invalid argument "STDINFO" for "-a, --attach" flag: valid streams are STDIN, STDOUT and STDERR`,
}, },
} { } {
tc := tc
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
cmd := NewCreateCommand(test.NewFakeCli(&fakeClient{})) cmd := NewCreateCommand(test.NewFakeCli(&fakeClient{}))
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
@ -251,7 +248,6 @@ func TestNewCreateCommandWithContentTrustErrors(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
tc := tc
fakeCLI := test.NewFakeCli(&fakeClient{ fakeCLI := test.NewFakeCli(&fakeClient{
createContainerFunc: func(config *container.Config, createContainerFunc: func(config *container.Config,
hostConfig *container.HostConfig, hostConfig *container.HostConfig,
@ -312,7 +308,6 @@ 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) {
fakeCLI := test.NewFakeCli(&fakeClient{ fakeCLI := test.NewFakeCli(&fakeClient{
createContainerFunc: func(config *container.Config, createContainerFunc: func(config *container.Config,

View File

@ -47,7 +47,6 @@ D: /usr/app/old_app.js
} }
for _, tc := range cases { for _, tc := range cases {
tc := tc
t.Run(string(tc.context.Format), func(t *testing.T) { t.Run(string(tc.context.Format), func(t *testing.T) {
out := bytes.NewBufferString("") out := bytes.NewBufferString("")
tc.context.Output = out tc.context.Output = out

View File

@ -178,7 +178,6 @@ container2 -- --
} }
for _, tc := range cases { for _, tc := range cases {
tc := tc
t.Run(string(tc.context.Format), func(t *testing.T) { t.Run(string(tc.context.Format), func(t *testing.T) {
var out bytes.Buffer var out bytes.Buffer
tc.context.Output = &out tc.context.Output = &out
@ -223,7 +222,6 @@ func TestContainerStatsContextWriteWithNoStats(t *testing.T) {
} }
for _, tc := range cases { for _, tc := range cases {
tc := tc
t.Run(string(tc.context.Format), func(t *testing.T) { t.Run(string(tc.context.Format), func(t *testing.T) {
err := statsFormatWrite(tc.context, []StatsEntry{}, "linux", false) err := statsFormatWrite(tc.context, []StatsEntry{}, "linux", false)
assert.NilError(t, err) assert.NilError(t, err)
@ -265,7 +263,6 @@ func TestContainerStatsContextWriteWithNoStatsWindows(t *testing.T) {
} }
for _, tc := range cases { for _, tc := range cases {
tc := tc
t.Run(string(tc.context.Format), func(t *testing.T) { t.Run(string(tc.context.Format), func(t *testing.T) {
err := statsFormatWrite(tc.context, []StatsEntry{}, "windows", false) err := statsFormatWrite(tc.context, []StatsEntry{}, "windows", false)
assert.NilError(t, err) assert.NilError(t, err)

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.21 //go:build go1.22
package container package container

View File

@ -277,7 +277,6 @@ func TestContainerListFormatSizeSetsOption(t *testing.T) {
} }
for _, tc := range tests { for _, tc := range tests {
tc := tc
t.Run(tc.doc, func(t *testing.T) { t.Run(tc.doc, func(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{ cli := test.NewFakeCli(&fakeClient{
containerListFunc: func(options container.ListOptions) ([]container.Summary, error) { containerListFunc: func(options container.ListOptions) ([]container.Summary, error) {

View File

@ -3,11 +3,14 @@ package container
import ( import (
"context" "context"
"io" "io"
"strconv"
"time"
"github.com/docker/cli/cli" "github.com/docker/cli/cli"
"github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/completion" "github.com/docker/cli/cli/command/completion"
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/events"
"github.com/docker/docker/pkg/stdcopy" "github.com/docker/docker/pkg/stdcopy"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -20,6 +23,8 @@ type logsOptions struct {
details bool details bool
tail string tail string
detachDelay int
container string container string
} }
@ -49,6 +54,7 @@ func NewLogsCommand(dockerCli command.Cli) *cobra.Command {
flags.BoolVarP(&opts.timestamps, "timestamps", "t", false, "Show timestamps") flags.BoolVarP(&opts.timestamps, "timestamps", "t", false, "Show timestamps")
flags.BoolVar(&opts.details, "details", false, "Show extra details provided to logs") flags.BoolVar(&opts.details, "details", false, "Show extra details provided to logs")
flags.StringVarP(&opts.tail, "tail", "n", "all", "Number of lines to show from the end of the logs") flags.StringVarP(&opts.tail, "tail", "n", "all", "Number of lines to show from the end of the logs")
flags.IntVarP(&opts.detachDelay, "delay", "d", 0, "Number of seconds to wait for container restart before exiting")
return cmd return cmd
} }
@ -58,6 +64,45 @@ func runLogs(ctx context.Context, dockerCli command.Cli, opts *logsOptions) erro
return err return err
} }
since := opts.since
for {
restarting := make(chan events.Message)
if opts.detachDelay != 0 {
go func() {
eventsCtx, eventsCtxCancel := context.WithCancel(ctx)
eventC, eventErrs := dockerCli.Client().Events(eventsCtx, events.ListOptions{})
defer eventsCtxCancel()
for {
select {
case event := <-eventC:
if event.Action == events.ActionRestart && event.Actor.ID == c.ID {
restarting <- event
return
}
case <-eventErrs:
return
}
}
}()
}
opts.since = since
err = streamLogs(ctx, dockerCli, opts, c)
if opts.detachDelay == 0 {
return err
}
select {
case restartEvent := <-restarting:
since = strconv.FormatInt(restartEvent.Time, 10)
case <-time.After(time.Duration(opts.detachDelay) * time.Second):
return err
}
}
}
func streamLogs(ctx context.Context, dockerCli command.Cli, opts *logsOptions, c container.InspectResponse) error {
responseBody, err := dockerCli.Client().ContainerLogs(ctx, c.ID, container.LogsOptions{ responseBody, err := dockerCli.Client().ContainerLogs(ctx, c.ID, container.LogsOptions{
ShowStdout: true, ShowStdout: true,
ShowStderr: true, ShowStderr: true,
@ -78,5 +123,6 @@ func runLogs(ctx context.Context, dockerCli command.Cli, opts *logsOptions) erro
} else { } else {
_, err = stdcopy.StdCopy(dockerCli.Out(), dockerCli.Err(), responseBody) _, err = stdcopy.StdCopy(dockerCli.Out(), dockerCli.Err(), responseBody)
} }
return err return err
} }

View File

@ -23,7 +23,6 @@ import (
"github.com/docker/docker/errdefs" "github.com/docker/docker/errdefs"
"github.com/docker/go-connections/nat" "github.com/docker/go-connections/nat"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/pflag" "github.com/spf13/pflag"
cdi "tags.cncf.io/container-device-interface/pkg/parser" cdi "tags.cncf.io/container-device-interface/pkg/parser"
) )
@ -364,10 +363,6 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*con
return nil, errors.Errorf("invalid value: %d. Valid memory swappiness range is 0-100", swappiness) return nil, errors.Errorf("invalid value: %d. Valid memory swappiness range is 0-100", swappiness)
} }
mounts := copts.mounts.Value()
if len(mounts) > 0 && copts.volumeDriver != "" {
logrus.Warn("`--volume-driver` is ignored for volumes specified via `--mount`. Use `--mount type=volume,volume-driver=...` instead.")
}
var binds []string var binds []string
volumes := copts.volumes.GetMap() volumes := copts.volumes.GetMap()
// add any bind targets to the list of container volumes // add any bind targets to the list of container volumes
@ -697,7 +692,7 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*con
Tmpfs: tmpfs, Tmpfs: tmpfs,
Sysctls: copts.sysctls.GetAll(), Sysctls: copts.sysctls.GetAll(),
Runtime: copts.runtime, Runtime: copts.runtime,
Mounts: mounts, Mounts: copts.mounts.Value(),
MaskedPaths: maskedPaths, MaskedPaths: maskedPaths,
ReadonlyPaths: readonlyPaths, ReadonlyPaths: readonlyPaths,
Annotations: copts.annotations.GetAll(), Annotations: copts.annotations.GetAll(),
@ -767,7 +762,6 @@ func parseNetworkOpts(copts *containerOptions) (map[string]*networktypes.Endpoin
} }
for i, n := range copts.netMode.Value() { for i, n := range copts.netMode.Value() {
n := n
if container.NetworkMode(n.Target).IsUserDefined() { if container.NetworkMode(n.Target).IsUserDefined() {
hasUserDefined = true hasUserDefined = true
} else { } else {

View File

@ -126,7 +126,6 @@ func TestParseRunAttach(t *testing.T) {
}, },
} }
for _, tc := range tests { for _, tc := range tests {
tc := tc
t.Run(tc.input, func(t *testing.T) { t.Run(tc.input, func(t *testing.T) {
config, _, _ := mustParse(t, tc.input) config, _, _ := mustParse(t, tc.input)
assert.Equal(t, config.AttachStdin, tc.expected.AttachStdin) assert.Equal(t, config.AttachStdin, tc.expected.AttachStdin)
@ -802,7 +801,6 @@ func TestParseRestartPolicy(t *testing.T) {
}, },
} }
for _, tc := range tests { for _, tc := range tests {
tc := tc
t.Run(tc.input, func(t *testing.T) { t.Run(tc.input, func(t *testing.T) {
_, hostConfig, _, err := parseRun([]string{"--restart=" + tc.input, "img", "cmd"}) _, hostConfig, _, err := parseRun([]string{"--restart=" + tc.input, "img", "cmd"})
if tc.expectedErr != "" { if tc.expectedErr != "" {

View File

@ -43,7 +43,6 @@ func TestNewPortCommandOutput(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{
inspectFunc: func(string) (container.InspectResponse, error) { inspectFunc: func(string) (container.InspectResponse, error) {

View File

@ -58,7 +58,6 @@ func TestRestart(t *testing.T) {
expectedErr: "conflicting options: cannot specify both --timeout and --time", expectedErr: "conflicting options: cannot specify both --timeout and --time",
}, },
} { } {
tc := tc
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
var restarted []string var restarted []string
mutex := new(sync.Mutex) mutex := new(sync.Mutex)

View File

@ -23,7 +23,6 @@ func TestRemoveForce(t *testing.T) {
{name: "without force", args: []string{"nosuchcontainer", "mycontainer"}, expectedErr: "no such container"}, {name: "without force", args: []string{"nosuchcontainer", "mycontainer"}, expectedErr: "no such container"},
{name: "with force", args: []string{"--force", "nosuchcontainer", "mycontainer"}, expectedErr: ""}, {name: "with force", args: []string{"--force", "nosuchcontainer", "mycontainer"}, expectedErr: ""},
} { } {
tc := tc
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
var removed []string var removed []string
mutex := new(sync.Mutex) mutex := new(sync.Mutex)

View File

@ -35,7 +35,6 @@ func TestRunValidateFlags(t *testing.T) {
expectedErr: "conflicting options: cannot specify both --attach and --detach", expectedErr: "conflicting options: cannot specify both --attach and --detach",
}, },
} { } {
tc := tc
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
cmd := NewRunCommand(test.NewFakeCli(&fakeClient{})) cmd := NewRunCommand(test.NewFakeCli(&fakeClient{}))
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
@ -245,7 +244,6 @@ func TestRunCommandWithContentTrustErrors(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) {
fakeCLI := test.NewFakeCli(&fakeClient{ fakeCLI := test.NewFakeCli(&fakeClient{
createContainerFunc: func(config *container.Config, createContainerFunc: func(config *container.Config,
@ -286,7 +284,6 @@ func TestRunContainerImagePullPolicyInvalid(t *testing.T) {
}, },
} }
for _, tc := range cases { for _, tc := range cases {
tc := tc
t.Run(tc.PullPolicy, func(t *testing.T) { t.Run(tc.PullPolicy, func(t *testing.T) {
dockerCli := test.NewFakeCli(&fakeClient{}) dockerCli := test.NewFakeCli(&fakeClient{})
err := runRun( err := runRun(

View File

@ -1,6 +1,7 @@
package container package container
import ( import (
"bytes"
"context" "context"
"fmt" "fmt"
"io" "io"
@ -264,31 +265,40 @@ func RunStats(ctx context.Context, dockerCLI command.Cli, options *StatsOptions)
// so we unlikely hit this code in practice. // so we unlikely hit this code in practice.
daemonOSType = dockerCLI.ServerInfo().OSType daemonOSType = dockerCLI.ServerInfo().OSType
} }
// Buffer to store formatted stats text.
// Once formatted, it will be printed in one write to avoid screen flickering.
var statsTextBuffer bytes.Buffer
statsCtx := formatter.Context{ statsCtx := formatter.Context{
Output: dockerCLI.Out(), Output: &statsTextBuffer,
Format: NewStatsFormat(format, daemonOSType), Format: NewStatsFormat(format, daemonOSType),
} }
cleanScreen := func() {
if !options.NoStream {
_, _ = fmt.Fprint(dockerCLI.Out(), "\033[2J")
_, _ = fmt.Fprint(dockerCLI.Out(), "\033[H")
}
}
var err error var err error
ticker := time.NewTicker(500 * time.Millisecond) ticker := time.NewTicker(500 * time.Millisecond)
defer ticker.Stop() defer ticker.Stop()
for range ticker.C { for range ticker.C {
cleanScreen()
var ccStats []StatsEntry var ccStats []StatsEntry
cStats.mu.RLock() cStats.mu.RLock()
for _, c := range cStats.cs { for _, c := range cStats.cs {
ccStats = append(ccStats, c.GetStatistics()) ccStats = append(ccStats, c.GetStatistics())
} }
cStats.mu.RUnlock() cStats.mu.RUnlock()
if !options.NoStream {
// Start by clearing the screen and moving the cursor to the top-left
_, _ = fmt.Fprint(&statsTextBuffer, "\033[2J\033[H")
}
if err = statsFormatWrite(statsCtx, ccStats, daemonOSType, !options.NoTrunc); err != nil { if err = statsFormatWrite(statsCtx, ccStats, daemonOSType, !options.NoTrunc); err != nil {
break break
} }
_, _ = fmt.Fprint(dockerCLI.Out(), statsTextBuffer.String())
statsTextBuffer.Reset()
if len(cStats.cs) == 0 && !showAll { if len(cStats.cs) == 0 && !showAll {
break break
} }

View File

@ -58,7 +58,6 @@ func TestStop(t *testing.T) {
expectedErr: "conflicting options: cannot specify both --timeout and --time", expectedErr: "conflicting options: cannot specify both --timeout and --time",
}, },
} { } {
tc := tc
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
var stopped []string var stopped []string
mutex := new(sync.Mutex) mutex := new(sync.Mutex)

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.21 //go:build go1.22
package command package command

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.21 //go:build go1.22
package context package context

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.21 //go:build go1.22
package context package context
@ -94,7 +94,6 @@ func TestCreate(t *testing.T) {
}, },
} }
for _, tc := range tests { for _, tc := range tests {
tc := tc
t.Run(tc.options.Name, func(t *testing.T) { t.Run(tc.options.Name, func(t *testing.T) {
err := RunCreate(cli, &tc.options) err := RunCreate(cli, &tc.options)
if tc.expecterErr == "" { if tc.expecterErr == "" {
@ -164,25 +163,24 @@ func TestCreateFromContext(t *testing.T) {
cli.SetCurrentContext("dummy") cli.SetCurrentContext("dummy")
for _, c := range cases { for _, tc := range cases {
c := c t.Run(tc.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{
From: "original", From: "original",
Name: c.name, Name: tc.name,
Description: c.description, Description: tc.description,
Docker: c.docker, Docker: tc.docker,
}) })
assert.NilError(t, err) assert.NilError(t, err)
assertContextCreateLogging(t, cli, c.name) assertContextCreateLogging(t, cli, tc.name)
newContext, err := cli.ContextStore().GetMetadata(c.name) newContext, err := cli.ContextStore().GetMetadata(tc.name)
assert.NilError(t, err) assert.NilError(t, err)
newContextTyped, err := command.GetDockerContext(newContext) newContextTyped, err := command.GetDockerContext(newContext)
assert.NilError(t, err) assert.NilError(t, err)
dockerEndpoint, err := docker.EndpointFromContext(newContext) dockerEndpoint, err := docker.EndpointFromContext(newContext)
assert.NilError(t, err) assert.NilError(t, err)
assert.Equal(t, newContextTyped.Description, c.expectedDescription) assert.Equal(t, newContextTyped.Description, tc.expectedDescription)
assert.Equal(t, dockerEndpoint.Host, "tcp://42.42.42.42:2375") assert.Equal(t, dockerEndpoint.Host, "tcp://42.42.42.42:2375")
}) })
} }
@ -219,23 +217,22 @@ func TestCreateFromCurrent(t *testing.T) {
cli.SetCurrentContext("original") cli.SetCurrentContext("original")
for _, c := range cases { for _, tc := range cases {
c := c t.Run(tc.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{
Name: c.name, Name: tc.name,
Description: c.description, Description: tc.description,
}) })
assert.NilError(t, err) assert.NilError(t, err)
assertContextCreateLogging(t, cli, c.name) assertContextCreateLogging(t, cli, tc.name)
newContext, err := cli.ContextStore().GetMetadata(c.name) newContext, err := cli.ContextStore().GetMetadata(tc.name)
assert.NilError(t, err) assert.NilError(t, err)
newContextTyped, err := command.GetDockerContext(newContext) newContextTyped, err := command.GetDockerContext(newContext)
assert.NilError(t, err) assert.NilError(t, err)
dockerEndpoint, err := docker.EndpointFromContext(newContext) dockerEndpoint, err := docker.EndpointFromContext(newContext)
assert.NilError(t, err) assert.NilError(t, err)
assert.Equal(t, newContextTyped.Description, c.expectedDescription) assert.Equal(t, newContextTyped.Description, tc.expectedDescription)
assert.Equal(t, dockerEndpoint.Host, "tcp://42.42.42.42:2375") assert.Equal(t, dockerEndpoint.Host, "tcp://42.42.42.42:2375")
}) })
} }

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.21 //go:build go1.22
package context package context

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.21 //go:build go1.22
package context package context

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.21 //go:build go1.22
package command package command

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.21 //go:build go1.22
package command package command

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.21 //go:build go1.22
package command package command

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.21 //go:build go1.22
package formatter package formatter

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.21 //go:build go1.22
package formatter package formatter
@ -346,7 +346,6 @@ size: 0B
} }
for _, tc := range cases { for _, tc := range cases {
tc := tc
t.Run(string(tc.context.Format), func(t *testing.T) { t.Run(string(tc.context.Format), func(t *testing.T) {
var out bytes.Buffer var out bytes.Buffer
tc.context.Output = &out tc.context.Output = &out
@ -411,7 +410,6 @@ func TestContainerContextWriteWithNoContainers(t *testing.T) {
} }
for _, tc := range cases { for _, tc := range cases {
tc := tc
t.Run(string(tc.context.Format), func(t *testing.T) { t.Run(string(tc.context.Format), func(t *testing.T) {
err := ContainerWrite(tc.context, containers) err := ContainerWrite(tc.context, containers)
assert.NilError(t, err) assert.NilError(t, err)

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.21 //go:build go1.22
package formatter package formatter

View File

@ -106,7 +106,6 @@ Build Cache 0 0 0B 0B
} }
for _, tc := range cases { for _, tc := range cases {
tc := tc
t.Run(string(tc.context.Format), func(t *testing.T) { t.Run(string(tc.context.Format), func(t *testing.T) {
var out bytes.Buffer var out bytes.Buffer
tc.context.Output = &out tc.context.Output = &out

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.21 //go:build go1.22
package formatter package formatter

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.21 //go:build go1.22
package formatter package formatter

View File

@ -304,7 +304,6 @@ image_id: imageID3
} }
for _, tc := range cases { for _, tc := range cases {
tc := tc
t.Run(string(tc.context.Format), func(t *testing.T) { t.Run(string(tc.context.Format), func(t *testing.T) {
var out bytes.Buffer var out bytes.Buffer
tc.context.Output = &out tc.context.Output = &out
@ -365,7 +364,6 @@ func TestImageContextWriteWithNoImage(t *testing.T) {
} }
for _, tc := range cases { for _, tc := range cases {
tc := tc
t.Run(string(tc.context.Format), func(t *testing.T) { t.Run(string(tc.context.Format), func(t *testing.T) {
err := ImageWrite(tc.context, images) err := ImageWrite(tc.context, images)
assert.NilError(t, err) assert.NilError(t, err)

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.21 //go:build go1.22
package formatter package formatter

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.21 //go:build go1.22
package formatter package formatter

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.21 //go:build go1.22
package formatter package formatter
@ -131,7 +131,6 @@ foobar_bar
} }
for _, tc := range cases { for _, tc := range cases {
tc := tc
t.Run(string(tc.context.Format), func(t *testing.T) { t.Run(string(tc.context.Format), func(t *testing.T) {
var out bytes.Buffer var out bytes.Buffer
tc.context.Output = &out tc.context.Output = &out

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.21 //go:build go1.22
package idresolver package idresolver

View File

@ -255,7 +255,6 @@ imageID6 17 years ago /bin/bash echo 183MB
} }
for _, tc := range cases { for _, tc := range cases {
tc := tc
t.Run(string(tc.context.Format), func(t *testing.T) { t.Run(string(tc.context.Format), func(t *testing.T) {
err := HistoryWrite(tc.context, true, histories) err := HistoryWrite(tc.context, true, histories)
assert.NilError(t, err) assert.NilError(t, err)

View File

@ -42,7 +42,6 @@ func TestNewHistoryCommandErrors(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) {
cmd := NewHistoryCommand(test.NewFakeCli(&fakeClient{imageHistoryFunc: tc.imageHistoryFunc})) cmd := NewHistoryCommand(test.NewFakeCli(&fakeClient{imageHistoryFunc: tc.imageHistoryFunc}))
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
@ -109,7 +108,6 @@ func TestNewHistoryCommandSuccess(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) {
// Set to UTC timezone as timestamps in output are // Set to UTC timezone as timestamps in output are
// printed in the current timezone // printed in the current timezone

View File

@ -98,7 +98,6 @@ func TestNewImportCommandSuccess(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) {
cmd := NewImportCommand(test.NewFakeCli(&fakeClient{imageImportFunc: tc.imageImportFunc})) cmd := NewImportCommand(test.NewFakeCli(&fakeClient{imageImportFunc: tc.imageImportFunc}))
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.21 //go:build go1.22
package image package image

View File

@ -25,7 +25,6 @@ func TestNewInspectCommandErrors(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) {
cmd := newInspectCommand(test.NewFakeCli(&fakeClient{})) cmd := newInspectCommand(test.NewFakeCli(&fakeClient{}))
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
@ -79,7 +78,6 @@ func TestNewInspectCommandSuccess(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) {
imageInspectInvocationCount = 0 imageInspectInvocationCount = 0
cli := test.NewFakeCli(&fakeClient{imageInspectFunc: tc.imageInspectFunc}) cli := test.NewFakeCli(&fakeClient{imageInspectFunc: tc.imageInspectFunc})

View File

@ -35,7 +35,6 @@ func TestNewImagesCommandErrors(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) {
cmd := NewImagesCommand(test.NewFakeCli(&fakeClient{imageListFunc: tc.imageListFunc})) cmd := NewImagesCommand(test.NewFakeCli(&fakeClient{imageListFunc: tc.imageListFunc}))
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
@ -83,7 +82,6 @@ func TestNewImagesCommandSuccess(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{imageListFunc: tc.imageListFunc}) cli := test.NewFakeCli(&fakeClient{imageListFunc: tc.imageListFunc})
cli.SetConfigFile(&configfile.ConfigFile{ImagesFormat: tc.imageFormat}) cli.SetConfigFile(&configfile.ConfigFile{ImagesFormat: tc.imageFormat})

View File

@ -52,7 +52,6 @@ func TestNewLoadCommandErrors(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{imageLoadFunc: tc.imageLoadFunc}) cli := test.NewFakeCli(&fakeClient{imageLoadFunc: tc.imageLoadFunc})
cli.In().SetIsTerminal(tc.isTerminalIn) cli.In().SetIsTerminal(tc.isTerminalIn)
@ -116,7 +115,6 @@ func TestNewLoadCommandSuccess(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{imageLoadFunc: tc.imageLoadFunc}) cli := test.NewFakeCli(&fakeClient{imageLoadFunc: tc.imageLoadFunc})
cmd := NewLoadCommand(cli) cmd := NewLoadCommand(cli)

View File

@ -39,7 +39,6 @@ func TestNewPruneCommandErrors(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) {
cmd := NewPruneCommand(test.NewFakeCli(&fakeClient{ cmd := NewPruneCommand(test.NewFakeCli(&fakeClient{
imagesPruneFunc: tc.imagesPruneFunc, imagesPruneFunc: tc.imagesPruneFunc,
@ -98,7 +97,6 @@ func TestNewPruneCommandSuccess(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{imagesPruneFunc: tc.imagesPruneFunc}) cli := test.NewFakeCli(&fakeClient{imagesPruneFunc: tc.imagesPruneFunc})
// when prompted, answer "Y" to confirm the prune. // when prompted, answer "Y" to confirm the prune.

View File

@ -38,7 +38,6 @@ func TestNewPullCommandErrors(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{})
cmd := NewPullCommand(cli) cmd := NewPullCommand(cli)
@ -73,7 +72,6 @@ func TestNewPullCommandSuccess(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{
imagePullFunc: func(ref string, options image.PullOptions) (io.ReadCloser, error) { imagePullFunc: func(ref string, options image.PullOptions) (io.ReadCloser, error) {
@ -119,7 +117,6 @@ func TestNewPullCommandWithContentTrustErrors(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{
imagePullFunc: func(ref string, options image.PullOptions) (io.ReadCloser, error) { imagePullFunc: func(ref string, options image.PullOptions) (io.ReadCloser, error) {

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.21 //go:build go1.22
package image package image

View File

@ -38,7 +38,6 @@ func TestNewPushCommandErrors(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{imagePushFunc: tc.imagePushFunc}) cli := test.NewFakeCli(&fakeClient{imagePushFunc: tc.imagePushFunc})
cmd := NewPushCommand(cli) cmd := NewPushCommand(cli)
@ -68,7 +67,6 @@ func TestNewPushCommandSuccess(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{
imagePushFunc: func(ref string, options image.PushOptions) (io.ReadCloser, error) { imagePushFunc: func(ref string, options image.PushOptions) (io.ReadCloser, error) {

View File

@ -62,7 +62,6 @@ func TestNewRemoveCommandErrors(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) {
cmd := NewRemoveCommand(test.NewFakeCli(&fakeClient{ cmd := NewRemoveCommand(test.NewFakeCli(&fakeClient{
imageRemoveFunc: tc.imageRemoveFunc, imageRemoveFunc: tc.imageRemoveFunc,
@ -121,7 +120,6 @@ func TestNewRemoveCommandSuccess(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{imageRemoveFunc: tc.imageRemoveFunc}) cli := test.NewFakeCli(&fakeClient{imageRemoveFunc: tc.imageRemoveFunc})
cmd := NewRemoveCommand(cli) cmd := NewRemoveCommand(cli)

View File

@ -59,7 +59,6 @@ func TestNewSaveCommandErrors(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{imageSaveFunc: tc.imageSaveFunc}) cli := test.NewFakeCli(&fakeClient{imageSaveFunc: tc.imageSaveFunc})
cli.Out().SetIsTerminal(tc.isTerminal) cli.Out().SetIsTerminal(tc.isTerminal)
@ -113,7 +112,6 @@ func TestNewSaveCommandSuccess(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
tc := tc
t.Run(strings.Join(tc.args, " "), func(t *testing.T) { t.Run(strings.Join(tc.args, " "), func(t *testing.T) {
cmd := NewSaveCommand(test.NewFakeCli(&fakeClient{ cmd := NewSaveCommand(test.NewFakeCli(&fakeClient{
imageSaveFunc: tc.imageSaveFunc, imageSaveFunc: tc.imageSaveFunc,

View File

@ -56,7 +56,6 @@ func runTree(ctx context.Context, dockerCLI command.Cli, opts treeOptions) error
continue continue
} }
im := im
sub := subImage{ sub := subImage{
Platform: platforms.Format(im.ImageData.Platform), Platform: platforms.Format(im.ImageData.Platform),
Available: im.Available, Available: im.Available,

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.21 //go:build go1.22
package inspect package inspect

View File

@ -31,7 +31,6 @@ func TestManifestCreateErrors(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
tc := tc
t.Run(tc.expectedError, func(t *testing.T) { t.Run(tc.expectedError, func(t *testing.T) {
cli := test.NewFakeCli(nil) cli := test.NewFakeCli(nil)
cmd := newCreateListCommand(cli) cmd := newCreateListCommand(cli)

View File

@ -218,7 +218,6 @@ func TestNetworkCreateIPv6(t *testing.T) {
} }
for _, tc := range tests { for _, tc := range tests {
tc := tc
t.Run(tc.doc, func(t *testing.T) { t.Run(tc.doc, func(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{ cli := test.NewFakeCli(&fakeClient{
networkCreateFunc: func(ctx context.Context, name string, createBody network.CreateOptions) (network.CreateResponse, error) { networkCreateFunc: func(ctx context.Context, name string, createBody network.CreateOptions) (network.CreateResponse, error) {

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.21 //go:build go1.22
package network package network
@ -161,7 +161,6 @@ foobar_bar 2017-01-01 00:00:00 +0000 UTC
} }
for _, tc := range cases { for _, tc := range cases {
tc := tc
t.Run(string(tc.context.Format), func(t *testing.T) { t.Run(string(tc.context.Format), func(t *testing.T) {
var out bytes.Buffer var out bytes.Buffer
tc.context.Output = &out tc.context.Output = &out

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.21 //go:build go1.22
package network package network

View File

@ -83,7 +83,6 @@ func TestNetworkList(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
tc := tc
t.Run(tc.doc, func(t *testing.T) { t.Run(tc.doc, func(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{networkListFunc: tc.networkListFunc}) cli := test.NewFakeCli(&fakeClient{networkListFunc: tc.networkListFunc})
cmd := newListCommand(cli) cmd := newListCommand(cli)

View File

@ -63,7 +63,6 @@ func TestNetworkRemoveForce(t *testing.T) {
} }
for _, tc := range tests { for _, tc := range tests {
tc := tc
t.Run(tc.doc, func(t *testing.T) { t.Run(tc.doc, func(t *testing.T) {
fakeCli := test.NewFakeCli(&fakeClient{ fakeCli := test.NewFakeCli(&fakeClient{
networkRemoveFunc: func(ctx context.Context, networkID string) error { networkRemoveFunc: func(ctx context.Context, networkID string) error {

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.21 //go:build go1.22
package node package node
@ -202,7 +202,6 @@ foobar_boo Unknown
} }
for _, tc := range cases { for _, tc := range cases {
tc := tc
t.Run(string(tc.context.Format), func(t *testing.T) { t.Run(string(tc.context.Format), func(t *testing.T) {
var out bytes.Buffer var out bytes.Buffer
tc.context.Output = &out tc.context.Output = &out

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.21 //go:build go1.22
package node package node

View File

@ -106,7 +106,6 @@ func TestNodeInspectPretty(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{
nodeInspectFunc: tc.nodeInspectFunc, nodeInspectFunc: tc.nodeInspectFunc,

View File

@ -134,7 +134,6 @@ func TestNodePs(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{
infoFunc: tc.infoFunc, infoFunc: tc.infoFunc,

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.21 //go:build go1.22
package plugin package plugin
@ -131,7 +131,6 @@ foobar_bar
} }
for _, tc := range cases { for _, tc := range cases {
tc := tc
t.Run(string(tc.context.Format), func(t *testing.T) { t.Run(string(tc.context.Format), func(t *testing.T) {
var out bytes.Buffer var out bytes.Buffer
tc.context.Output = &out tc.context.Output = &out

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.21 //go:build go1.22
package plugin package plugin

View File

@ -66,7 +66,6 @@ func TestInspectErrors(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
tc := tc
t.Run(tc.description, func(t *testing.T) { t.Run(tc.description, func(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{pluginInspectFunc: tc.inspectFunc}) cli := test.NewFakeCli(&fakeClient{pluginInspectFunc: tc.inspectFunc})
cmd := newInspectCommand(cli) cmd := newInspectCommand(cli)
@ -138,7 +137,6 @@ func TestInspect(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
tc := tc
t.Run(tc.description, func(t *testing.T) { t.Run(tc.description, func(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{pluginInspectFunc: tc.inspectFunc}) cli := test.NewFakeCli(&fakeClient{pluginInspectFunc: tc.inspectFunc})
cmd := newInspectCommand(cli) cmd := newInspectCommand(cli)

View File

@ -54,7 +54,6 @@ func TestInstallErrors(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
tc := tc
t.Run(tc.description, func(t *testing.T) { t.Run(tc.description, func(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{pluginInstallFunc: tc.installFunc}) cli := test.NewFakeCli(&fakeClient{pluginInstallFunc: tc.installFunc})
cmd := newInstallCommand(cli) cmd := newInstallCommand(cli)
@ -94,7 +93,6 @@ func TestInstallContentTrustErrors(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
tc := tc
t.Run(tc.description, func(t *testing.T) { t.Run(tc.description, func(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{ cli := test.NewFakeCli(&fakeClient{
pluginInstallFunc: func(name string, options types.PluginInstallOptions) (io.ReadCloser, error) { pluginInstallFunc: func(name string, options types.PluginInstallOptions) (io.ReadCloser, error) {
@ -138,7 +136,6 @@ func TestInstall(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
tc := tc
t.Run(tc.description, func(t *testing.T) { t.Run(tc.description, func(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{pluginInstallFunc: tc.installFunc}) cli := test.NewFakeCli(&fakeClient{pluginInstallFunc: tc.installFunc})
cmd := newInstallCommand(cli) cmd := newInstallCommand(cli)

View File

@ -46,7 +46,6 @@ func TestListErrors(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
tc := tc
t.Run(tc.description, func(t *testing.T) { t.Run(tc.description, func(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{pluginListFunc: tc.listFunc}) cli := test.NewFakeCli(&fakeClient{pluginListFunc: tc.listFunc})
cmd := newListCommand(cli) cmd := newListCommand(cli)
@ -166,7 +165,6 @@ func TestList(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
tc := tc
t.Run(tc.description, func(t *testing.T) { t.Run(tc.description, func(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{pluginListFunc: tc.listFunc}) cli := test.NewFakeCli(&fakeClient{pluginListFunc: tc.listFunc})
cmd := newListCommand(cli) cmd := newListCommand(cli)

View File

@ -203,7 +203,6 @@ result2 5
} }
for _, tc := range cases { for _, tc := range cases {
tc := tc
t.Run(tc.doc, func(t *testing.T) { t.Run(tc.doc, func(t *testing.T) {
var out bytes.Buffer var out bytes.Buffer
err := SearchWrite(formatter.Context{Format: tc.format, Output: &out}, results) err := SearchWrite(formatter.Context{Format: tc.format, Output: &out}, results)

View File

@ -61,7 +61,6 @@ id_rsa
}, },
} }
for _, tc := range cases { for _, tc := range cases {
tc := tc
t.Run(string(tc.context.Format), func(t *testing.T) { t.Run(string(tc.context.Format), func(t *testing.T) {
var out bytes.Buffer var out bytes.Buffer
tc.context.Output = &out tc.context.Output = &out

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.21 //go:build go1.22
package secret package secret

View File

@ -93,7 +93,6 @@ func TestSecretInspectWithoutFormat(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{
secretInspectFunc: tc.secretInspectFunc, secretInspectFunc: tc.secretInspectFunc,
@ -132,7 +131,6 @@ func TestSecretInspectWithFormat(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{
secretInspectFunc: tc.secretInspectFunc, secretInspectFunc: tc.secretInspectFunc,

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.21 //go:build go1.22
package service package service
@ -223,7 +223,6 @@ zarp2
} }
for _, tc := range cases { for _, tc := range cases {
tc := tc
t.Run(string(tc.context.Format), func(t *testing.T) { t.Run(string(tc.context.Format), func(t *testing.T) {
var out bytes.Buffer var out bytes.Buffer
tc.context.Output = &out tc.context.Output = &out

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.21 //go:build go1.22
package service package service

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.21 //go:build go1.22
package service package service

View File

@ -168,7 +168,6 @@ func TestServiceListServiceStatus(t *testing.T) {
} }
for _, tc := range matrix { for _, tc := range matrix {
tc := tc
t.Run(tc.doc, func(t *testing.T) { t.Run(tc.doc, func(t *testing.T) {
if tc.cluster == nil { if tc.cluster == nil {
tc.cluster = generateCluster(t, tc.opts) tc.cluster = generateCluster(t, tc.opts)

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.21 //go:build go1.22
package service package service

View File

@ -50,7 +50,6 @@ func TestCredentialSpecOpt(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) {
var cs credentialSpecOpt var cs credentialSpecOpt

View File

@ -91,7 +91,6 @@ func TestRollbackWithErrors(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) {
cmd := newRollbackCommand( cmd := newRollbackCommand(
test.NewFakeCli(&fakeClient{ test.NewFakeCli(&fakeClient{

View File

@ -1058,7 +1058,6 @@ func updatePorts(flags *pflag.FlagSet, portConfig *[]swarm.PortConfig) error {
// Build the current list of portConfig // Build the current list of portConfig
for _, entry := range *portConfig { for _, entry := range *portConfig {
entry := entry
if _, ok := portSet[portConfigToString(&entry)]; !ok { if _, ok := portSet[portConfigToString(&entry)]; !ok {
portSet[portConfigToString(&entry)] = entry portSet[portConfigToString(&entry)] = entry
} }
@ -1086,7 +1085,6 @@ portLoop:
ports := flags.Lookup(flagPublishAdd).Value.(*opts.PortOpt).Value() ports := flags.Lookup(flagPublishAdd).Value.(*opts.PortOpt).Value()
for _, port := range ports { for _, port := range ports {
port := port
if _, ok := portSet[portConfigToString(&port)]; ok { if _, ok := portSet[portConfigToString(&port)]; ok {
continue continue
} }

View File

@ -1690,7 +1690,6 @@ func TestUpdateUlimits(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) {
svc := swarm.ServiceSpec{ svc := swarm.ServiceSpec{
TaskTemplate: swarm.TaskSpec{ TaskTemplate: swarm.TaskSpec{

View File

@ -51,7 +51,6 @@ bar
{Name: "bar", Services: 1}, {Name: "bar", Services: 1},
} }
for _, tc := range cases { for _, tc := range cases {
tc := tc
t.Run(string(tc.context.Format), func(t *testing.T) { t.Run(string(tc.context.Format), func(t *testing.T) {
var out bytes.Buffer var out bytes.Buffer
tc.context.Output = &out tc.context.Output = &out

View File

@ -48,7 +48,6 @@ func TestListErrors(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
tc := tc
t.Run(tc.expectedError, func(t *testing.T) { t.Run(tc.expectedError, func(t *testing.T) {
cmd := newListCommand(test.NewFakeCli(&fakeClient{ cmd := newListCommand(test.NewFakeCli(&fakeClient{
serviceListFunc: tc.serviceListFunc, serviceListFunc: tc.serviceListFunc,
@ -104,7 +103,6 @@ func TestStackList(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
tc := tc
t.Run(tc.doc, func(t *testing.T) { t.Run(tc.doc, func(t *testing.T) {
var services []swarm.Service var services []swarm.Service
for _, name := range tc.serviceNames { for _, name := range tc.serviceNames {

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.21 //go:build go1.22
package loader package loader

View File

@ -40,7 +40,6 @@ func TestStackPsErrors(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
tc := tc
t.Run(tc.expectedError, func(t *testing.T) { t.Run(tc.expectedError, func(t *testing.T) {
cmd := newPsCommand(test.NewFakeCli(&fakeClient{ cmd := newPsCommand(test.NewFakeCli(&fakeClient{
taskListFunc: tc.taskListFunc, taskListFunc: tc.taskListFunc,
@ -160,7 +159,6 @@ func TestStackPs(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
tc := tc
t.Run(tc.doc, func(t *testing.T) { t.Run(tc.doc, func(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{ cli := test.NewFakeCli(&fakeClient{
taskListFunc: tc.taskListFunc, taskListFunc: tc.taskListFunc,

View File

@ -67,7 +67,6 @@ func TestStackServicesErrors(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
tc := tc
t.Run(tc.expectedError, func(t *testing.T) { t.Run(tc.expectedError, func(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{ cli := test.NewFakeCli(&fakeClient{
serviceListFunc: tc.serviceListFunc, serviceListFunc: tc.serviceListFunc,

View File

@ -88,7 +88,6 @@ func TestServiceUpdateResolveImageChanged(t *testing.T) {
ctx := context.Background() ctx := context.Background()
for _, tc := range testcases { for _, tc := range testcases {
tc := tc
t.Run(tc.image, func(t *testing.T) { t.Run(tc.image, func(t *testing.T) {
spec := map[string]swarm.ServiceSpec{ spec := map[string]swarm.ServiceSpec{
"myservice": { "myservice": {

View File

@ -63,7 +63,6 @@ func TestSwarmInitErrorOnAPIFailure(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) {
cmd := newInitCommand( cmd := newInitCommand(
test.NewFakeCli(&fakeClient{ test.NewFakeCli(&fakeClient{

Some files were not shown because too many files have changed in this diff Show More