From 580ebf41a089bb9190b65ec9d2d71a402ce5eea1 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Mon, 20 Nov 2023 10:04:36 +0100 Subject: [PATCH 01/19] dockerfiles: update golangci-lint to v1.55.2 Signed-off-by: Sebastiaan van Stijn --- dockerfiles/Dockerfile.lint | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockerfiles/Dockerfile.lint b/dockerfiles/Dockerfile.lint index d1ac42b1ad..575465cbda 100644 --- a/dockerfiles/Dockerfile.lint +++ b/dockerfiles/Dockerfile.lint @@ -2,7 +2,7 @@ ARG GO_VERSION=1.21.3 ARG ALPINE_VERSION=3.17 -ARG GOLANGCI_LINT_VERSION=v1.55.0 +ARG GOLANGCI_LINT_VERSION=v1.55.2 FROM golangci/golangci-lint:${GOLANGCI_LINT_VERSION}-alpine AS golangci-lint From efbcdce9b9ea0a8cf512b0b563b25e7cc3e96b27 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Mon, 20 Nov 2023 15:59:39 +0100 Subject: [PATCH 02/19] linting: cli/command/trust: unusedwrite: unused write to field Hashes (govet) cli/command/trust/sign_test.go:211:9: unusedwrite: unused write to field Hashes (govet) target.Hashes, target.Length, err = getSignedManifestHashAndSize(notaryRepo, "test") ^ Signed-off-by: Sebastiaan van Stijn --- cli/command/trust/sign_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cli/command/trust/sign_test.go b/cli/command/trust/sign_test.go index 83863de953..632403ebf5 100644 --- a/cli/command/trust/sign_test.go +++ b/cli/command/trust/sign_test.go @@ -207,8 +207,7 @@ func TestAddStageSigners(t *testing.T) { func TestGetSignedManifestHashAndSize(t *testing.T) { notaryRepo, err := client.NewFileCachedRepository(t.TempDir(), "gun", "https://localhost", nil, passphrase.ConstantRetriever(passwd), trustpinning.TrustPinConfig{}) assert.NilError(t, err) - target := &client.Target{} - target.Hashes, target.Length, err = getSignedManifestHashAndSize(notaryRepo, "test") + _, _, err = getSignedManifestHashAndSize(notaryRepo, "test") assert.Error(t, err, "client is offline") } From d0dee3cebe71401a387aea70e9b9e67710089075 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Sat, 3 Sep 2022 20:07:29 +0200 Subject: [PATCH 03/19] linting: Consider pre-allocating sliceVar (prealloc) While updating, also addressed some redundant fmt.Sprintf() opts/throttledevice.go:86:2: Consider pre-allocating `out` (prealloc) var out []string ^ opts/ulimit.go:37:2: Consider pre-allocating `out` (prealloc) var out []string ^ opts/ulimit.go:47:2: Consider pre-allocating `ulimits` (prealloc) var ulimits []*units.Ulimit ^ opts/weightdevice.go:68:2: Consider pre-allocating `out` (prealloc) var out []string ^ cli/context/store/metadatastore.go:96:2: Consider pre-allocating `res` (prealloc) var res []Metadata ^ cli/context/store/store.go:127:2: Consider pre-allocating `names` (prealloc) var names []string ^ cli/compose/loader/loader.go:223:2: Consider pre-allocating `keys` (prealloc) var keys []string ^ cli/compose/loader/loader.go:397:2: Consider pre-allocating `services` (prealloc) var services []types.ServiceConfig ^ cli/command/stack/loader/loader.go:63:2: Consider pre-allocating `msgs` (prealloc) var msgs []string ^ cli/command/stack/loader/loader.go:118:2: Consider pre-allocating `configFiles` (prealloc) var configFiles []composetypes.ConfigFile ^ cli/command/formatter/container.go:245:2: Consider pre-allocating `joinLabels` (prealloc) var joinLabels []string ^ cli/command/formatter/container.go:265:2: Consider pre-allocating `mounts` (prealloc) var mounts []string ^ cli/command/formatter/container.go:316:2: Consider pre-allocating `result` (prealloc) var result []string ^ cli/command/formatter/displayutils.go:43:2: Consider pre-allocating `display` (prealloc) var ( ^ cli/command/formatter/volume.go:103:2: Consider pre-allocating `joinLabels` (prealloc) var joinLabels []string ^ cli-plugins/manager/manager_test.go:49:2: Consider pre-allocating `dirs` (prealloc) var dirs []string ^ cli/command/swarm/init.go:69:2: Consider pre-allocating `defaultAddrPool` (prealloc) var defaultAddrPool []string ^ cli/command/manifest/push.go:195:2: Consider pre-allocating `blobReqs` (prealloc) var blobReqs []manifestBlob ^ cli/command/secret/formatter.go:111:2: Consider pre-allocating `joinLabels` (prealloc) var joinLabels []string ^ cli/command/network/formatter.go:104:2: Consider pre-allocating `joinLabels` (prealloc) var joinLabels []string ^ cli/command/context/list.go:52:2: Consider pre-allocating `contexts` (prealloc) var contexts []*formatter.ClientContext ^ cli/command/config/formatter.go:104:2: Consider pre-allocating `joinLabels` (prealloc) var joinLabels []string ^ cli/command/trust/common_test.go:23:2: Consider pre-allocating `targetNames` (prealloc) var targetNames []string ^ cli/command/service/generic_resource_opts.go:55:2: Consider pre-allocating `generic` (prealloc) var generic []swarm.GenericResource ^ cli/command/service/generic_resource_opts.go:98:2: Consider pre-allocating `l` (prealloc) var l []swarm.GenericResource ^ cli/command/service/opts.go:378:2: Consider pre-allocating `netAttach` (prealloc) var netAttach []swarm.NetworkAttachmentConfig ^ cli/command/service/update.go:731:2: Consider pre-allocating `limits` (prealloc) var limits []*units.Ulimit ^ cli/command/service/update.go:1315:2: Consider pre-allocating `newNetworks` (prealloc) var newNetworks []swarm.NetworkAttachmentConfig ^ cli/command/service/update.go:1514:2: Consider pre-allocating `out` (prealloc) var out []string ^ cli/compose/convert/service.go:713:2: Consider pre-allocating `ulimits` (prealloc) var ulimits []*units.Ulimit ^ cli/compose/convert/volume.go:13:2: Consider pre-allocating `mounts` (prealloc) var mounts []mount.Mount ^ cli/command/stack/swarm/list.go:39:2: Consider pre-allocating `stacks` (prealloc) var stacks []*formatter.Stack ^ Signed-off-by: Sebastiaan van Stijn --- cli-plugins/manager/manager_test.go | 2 +- cli/command/config/formatter.go | 2 +- cli/command/context/list.go | 2 +- cli/command/formatter/container.go | 14 +++++++------- cli/command/formatter/displayutils.go | 2 +- cli/command/formatter/volume.go | 2 +- cli/command/manifest/push.go | 6 +++--- cli/command/network/formatter.go | 2 +- cli/command/secret/formatter.go | 2 +- cli/command/service/generic_resource_opts.go | 4 ++-- cli/command/service/opts.go | 5 +++-- cli/command/service/update.go | 13 +++++++++---- cli/command/stack/loader/loader.go | 4 ++-- cli/command/stack/swarm/list.go | 2 +- cli/command/swarm/init.go | 3 +-- cli/command/system/events_test.go | 2 +- cli/command/trust/common_test.go | 2 +- cli/compose/convert/service.go | 2 +- cli/compose/convert/volume.go | 7 +++---- cli/compose/loader/loader.go | 4 ++-- cli/context/store/metadatastore.go | 2 +- cli/context/store/store.go | 2 +- cli/manifest/types/types.go | 10 +++++++--- opts/throttledevice.go | 9 +++++---- opts/ulimit.go | 4 ++-- opts/weightdevice.go | 2 +- 26 files changed, 60 insertions(+), 51 deletions(-) diff --git a/cli-plugins/manager/manager_test.go b/cli-plugins/manager/manager_test.go index 228d3099cc..405b6691db 100644 --- a/cli-plugins/manager/manager_test.go +++ b/cli-plugins/manager/manager_test.go @@ -46,7 +46,7 @@ func TestListPluginCandidates(t *testing.T) { ) defer dir.Remove() - var dirs []string + dirs := make([]string, 0, 6) for _, d := range []string{"plugins1", "nonexistent", "plugins2", "plugins3", "plugins4", "plugins5"} { dirs = append(dirs, dir.Join(d)) } diff --git a/cli/command/config/formatter.go b/cli/command/config/formatter.go index ee8bc23467..4f69f880b0 100644 --- a/cli/command/config/formatter.go +++ b/cli/command/config/formatter.go @@ -101,7 +101,7 @@ func (c *configContext) Labels() string { if mapLabels == nil { return "" } - var joinLabels []string + joinLabels := make([]string, 0, len(mapLabels)) for k, v := range mapLabels { joinLabels = append(joinLabels, k+"="+v) } diff --git a/cli/command/context/list.go b/cli/command/context/list.go index 7798f131ae..aaf0195a73 100644 --- a/cli/command/context/list.go +++ b/cli/command/context/list.go @@ -51,7 +51,7 @@ func runList(dockerCli command.Cli, opts *listOptions) error { var ( curContext = dockerCli.CurrentContext() curFound bool - contexts []*formatter.ClientContext + contexts = make([]*formatter.ClientContext, 0, len(contextMap)) ) for _, rawMeta := range contextMap { isCurrent := rawMeta.Name == curContext diff --git a/cli/command/formatter/container.go b/cli/command/formatter/container.go index a46f97488d..5151a2194b 100644 --- a/cli/command/formatter/container.go +++ b/cli/command/formatter/container.go @@ -245,7 +245,7 @@ func (c *ContainerContext) Labels() string { return "" } - var joinLabels []string + joinLabels := make([]string, 0, len(c.c.Labels)) for k, v := range c.c.Labels { joinLabels = append(joinLabels, k+"="+v) } @@ -265,7 +265,7 @@ func (c *ContainerContext) Label(name string) string { // If the trunc option is set, names can be truncated (ellipsized). func (c *ContainerContext) Mounts() string { var name string - var mounts []string + mounts := make([]string, 0, len(c.c.Mounts)) for _, m := range c.c.Mounts { if m.Name == "" { name = m.Source @@ -289,7 +289,7 @@ func (c *ContainerContext) LocalVolumes() string { } } - return fmt.Sprintf("%d", count) + return strconv.Itoa(count) } // Networks returns a comma-separated string of networks that the container is @@ -299,7 +299,7 @@ func (c *ContainerContext) Networks() string { return "" } - networks := []string{} + networks := make([]string, 0, len(c.c.NetworkSettings.Networks)) for k := range c.c.NetworkSettings.Networks { networks = append(networks, k) } @@ -316,7 +316,7 @@ func DisplayablePorts(ports []types.Port) string { last uint16 } groupMap := make(map[string]*portGroup) - var result []string + var result []string //nolint:prealloc var hostMappings []string var groupMapKeys []string sort.Slice(ports, func(i, j int) bool { @@ -331,7 +331,7 @@ func DisplayablePorts(ports []types.Port) string { hostMappings = append(hostMappings, fmt.Sprintf("%s:%d->%d/%s", port.IP, port.PublicPort, port.PrivatePort, port.Type)) continue } - portKey = fmt.Sprintf("%s/%s", port.IP, port.Type) + portKey = port.IP + "/" + port.Type } group := groupMap[portKey] @@ -372,7 +372,7 @@ func formGroup(key string, start, last uint16) string { if ip != "" { group = fmt.Sprintf("%s:%s->%s", ip, group, group) } - return fmt.Sprintf("%s/%s", group, groupType) + return group + "/" + groupType } func comparePorts(i, j types.Port) bool { diff --git a/cli/command/formatter/displayutils.go b/cli/command/formatter/displayutils.go index 0c3b6ebbb0..7847bb307e 100644 --- a/cli/command/formatter/displayutils.go +++ b/cli/command/formatter/displayutils.go @@ -41,7 +41,7 @@ func Ellipsis(s string, maxDisplayWidth int) string { } var ( - display []int + display = make([]int, 0, len(rs)) displayWidth int ) for _, r := range rs { diff --git a/cli/command/formatter/volume.go b/cli/command/formatter/volume.go index fa8ef7f23c..85f0707931 100644 --- a/cli/command/formatter/volume.go +++ b/cli/command/formatter/volume.go @@ -100,7 +100,7 @@ func (c *volumeContext) Labels() string { return "" } - var joinLabels []string + joinLabels := make([]string, 0, len(c.v.Labels)) for k, v := range c.v.Labels { joinLabels = append(joinLabels, k+"="+v) } diff --git a/cli/command/manifest/push.go b/cli/command/manifest/push.go index 993432d43a..34c57e749a 100644 --- a/cli/command/manifest/push.go +++ b/cli/command/manifest/push.go @@ -192,9 +192,9 @@ func buildManifestDescriptor(targetRepo *registry.RepositoryInfo, imageManifest } func buildBlobRequestList(imageManifest types.ImageManifest, repoName reference.Named) ([]manifestBlob, error) { - var blobReqs []manifestBlob - - for _, blobDigest := range imageManifest.Blobs() { + blobs := imageManifest.Blobs() + blobReqs := make([]manifestBlob, 0, len(blobs)) + for _, blobDigest := range blobs { canonical, err := reference.WithDigest(repoName, blobDigest) if err != nil { return nil, err diff --git a/cli/command/network/formatter.go b/cli/command/network/formatter.go index 3229dfdd0a..604095a9d4 100644 --- a/cli/command/network/formatter.go +++ b/cli/command/network/formatter.go @@ -101,7 +101,7 @@ func (c *networkContext) Labels() string { return "" } - var joinLabels []string + joinLabels := make([]string, 0, len(c.n.Labels)) for k, v := range c.n.Labels { joinLabels = append(joinLabels, k+"="+v) } diff --git a/cli/command/secret/formatter.go b/cli/command/secret/formatter.go index 33c1451249..a950478431 100644 --- a/cli/command/secret/formatter.go +++ b/cli/command/secret/formatter.go @@ -108,7 +108,7 @@ func (c *secretContext) Labels() string { if mapLabels == nil { return "" } - var joinLabels []string + joinLabels := make([]string, 0, len(mapLabels)) for k, v := range mapLabels { joinLabels = append(joinLabels, k+"="+v) } diff --git a/cli/command/service/generic_resource_opts.go b/cli/command/service/generic_resource_opts.go index d406d06e64..613c255749 100644 --- a/cli/command/service/generic_resource_opts.go +++ b/cli/command/service/generic_resource_opts.go @@ -52,7 +52,7 @@ func ParseGenericResources(value []string) ([]swarm.GenericResource, error) { // genericResourcesFromGRPC converts a GRPC GenericResource to a GenericResource func genericResourcesFromGRPC(genericRes []*swarmapi.GenericResource) []swarm.GenericResource { - var generic []swarm.GenericResource + generic := make([]swarm.GenericResource, 0, len(genericRes)) for _, res := range genericRes { var current swarm.GenericResource @@ -95,7 +95,7 @@ func buildGenericResourceMap(genericRes []swarm.GenericResource) (map[string]swa } func buildGenericResourceList(genericRes map[string]swarm.GenericResource) []swarm.GenericResource { - var l []swarm.GenericResource + l := make([]swarm.GenericResource, 0, len(genericRes)) for _, res := range genericRes { l = append(l, res) diff --git a/cli/command/service/opts.go b/cli/command/service/opts.go index c47ca82055..67c19fefd1 100644 --- a/cli/command/service/opts.go +++ b/cli/command/service/opts.go @@ -378,8 +378,9 @@ func resolveNetworkID(ctx context.Context, apiClient client.NetworkAPIClient, ne } func convertNetworks(networks opts.NetworkOpt) []swarm.NetworkAttachmentConfig { - var netAttach []swarm.NetworkAttachmentConfig - for _, net := range networks.Value() { + nws := networks.Value() + netAttach := make([]swarm.NetworkAttachmentConfig, 0, len(nws)) + for _, net := range nws { netAttach = append(netAttach, swarm.NetworkAttachmentConfig{ Target: net.Target, Aliases: net.Aliases, diff --git a/cli/command/service/update.go b/cli/command/service/update.go index c087224ba4..938edfc405 100644 --- a/cli/command/service/update.go +++ b/cli/command/service/update.go @@ -727,8 +727,10 @@ func updateUlimits(flags *pflag.FlagSet, ulimits []*units.Ulimit) []*units.Ulimi newUlimits[ulimit.Name] = ulimit } } - - var limits []*units.Ulimit + if len(newUlimits) == 0 { + return nil + } + limits := make([]*units.Ulimit, 0, len(newUlimits)) for _, ulimit := range newUlimits { limits = append(limits, ulimit) } @@ -1307,7 +1309,7 @@ func updateNetworks(ctx context.Context, apiClient client.NetworkAPIClient, flag } existingNetworks := make(map[string]struct{}) - var newNetworks []swarm.NetworkAttachmentConfig + var newNetworks []swarm.NetworkAttachmentConfig //nolint:prealloc for _, network := range specNetworks { if _, exists := idsToRemove[network.Target]; exists { continue @@ -1503,10 +1505,13 @@ func updateCapabilities(flags *pflag.FlagSet, containerSpec *swarm.ContainerSpec } func capsList(caps map[string]bool) []string { + if len(caps) == 0 { + return nil + } if caps[opts.AllCapabilities] { return []string{opts.AllCapabilities} } - var out []string + out := make([]string, 0, len(caps)) for c := range caps { out = append(out, c) } diff --git a/cli/command/stack/loader/loader.go b/cli/command/stack/loader/loader.go index 39810d8832..39df5d05f7 100644 --- a/cli/command/stack/loader/loader.go +++ b/cli/command/stack/loader/loader.go @@ -61,7 +61,7 @@ func getDictsFrom(configFiles []composetypes.ConfigFile) []map[string]interface{ } func propertyWarnings(properties map[string]string) string { - var msgs []string + msgs := make([]string, 0, len(properties)) for name, description := range properties { msgs = append(msgs, fmt.Sprintf("%s: %s", name, description)) } @@ -129,7 +129,7 @@ func buildEnvironment(env []string) (map[string]string, error) { } func loadConfigFiles(filenames []string, stdin io.Reader) ([]composetypes.ConfigFile, error) { - var configFiles []composetypes.ConfigFile + configFiles := make([]composetypes.ConfigFile, 0, len(filenames)) for _, filename := range filenames { configFile, err := loadConfigFile(filename, stdin) diff --git a/cli/command/stack/swarm/list.go b/cli/command/stack/swarm/list.go index 271cffdd00..42fd7f414e 100644 --- a/cli/command/stack/swarm/list.go +++ b/cli/command/stack/swarm/list.go @@ -36,7 +36,7 @@ func GetStacks(dockerCli command.Cli) ([]*formatter.Stack, error) { ztack.Services++ } } - var stacks []*formatter.Stack + stacks := make([]*formatter.Stack, 0, len(m)) for _, stack := range m { stacks = append(stacks, stack) } diff --git a/cli/command/swarm/init.go b/cli/command/swarm/init.go index 443e9055d7..1325779099 100644 --- a/cli/command/swarm/init.go +++ b/cli/command/swarm/init.go @@ -66,11 +66,10 @@ func newInitCommand(dockerCli command.Cli) *cobra.Command { } func runInit(dockerCli command.Cli, flags *pflag.FlagSet, opts initOptions) error { - var defaultAddrPool []string - client := dockerCli.Client() ctx := context.Background() + defaultAddrPool := make([]string, 0, len(opts.defaultAddrPools)) for _, p := range opts.defaultAddrPools { defaultAddrPool = append(defaultAddrPool, p.String()) } diff --git a/cli/command/system/events_test.go b/cli/command/system/events_test.go index f1853876aa..a3947b6573 100644 --- a/cli/command/system/events_test.go +++ b/cli/command/system/events_test.go @@ -16,7 +16,7 @@ import ( ) func TestEventsFormat(t *testing.T) { - var evts []events.Message + var evts []events.Message //nolint:prealloc for i, action := range []events.Action{events.ActionCreate, events.ActionStart, events.ActionAttach, events.ActionDie} { evts = append(evts, events.Message{ Status: string(action), diff --git a/cli/command/trust/common_test.go b/cli/command/trust/common_test.go index 11a0bc86c3..13f24f5022 100644 --- a/cli/command/trust/common_test.go +++ b/cli/command/trust/common_test.go @@ -20,7 +20,7 @@ func TestMatchReleasedSignaturesSortOrder(t *testing.T) { rows := matchReleasedSignatures(targets) - var targetNames []string + targetNames := make([]string, 0, len(rows)) for _, r := range rows { targetNames = append(targetNames, r.SignedTag) } diff --git a/cli/compose/convert/service.go b/cli/compose/convert/service.go index eb5e5066d4..2302245a01 100644 --- a/cli/compose/convert/service.go +++ b/cli/compose/convert/service.go @@ -710,7 +710,7 @@ func convertUlimits(origUlimits map[string]*composetypes.UlimitsConfig) []*units } } } - var ulimits []*units.Ulimit + ulimits := make([]*units.Ulimit, 0, len(newUlimits)) for _, ulimit := range newUlimits { ulimits = append(ulimits, ulimit) } diff --git a/cli/compose/convert/volume.go b/cli/compose/convert/volume.go index 257ddcd98d..387362203f 100644 --- a/cli/compose/convert/volume.go +++ b/cli/compose/convert/volume.go @@ -12,14 +12,13 @@ type volumes map[string]composetypes.VolumeConfig // Volumes from compose-file types to engine api types func Volumes(serviceVolumes []composetypes.ServiceVolumeConfig, stackVolumes volumes, namespace Namespace) ([]mount.Mount, error) { - var mounts []mount.Mount - + mounts := make([]mount.Mount, 0, len(serviceVolumes)) for _, volumeConfig := range serviceVolumes { - mount, err := convertVolumeToMount(volumeConfig, stackVolumes, namespace) + mnt, err := convertVolumeToMount(volumeConfig, stackVolumes, namespace) if err != nil { return nil, err } - mounts = append(mounts, mount) + mounts = append(mounts, mnt) } return mounts, nil } diff --git a/cli/compose/loader/loader.go b/cli/compose/loader/loader.go index a9b8f1f1f9..3ac728b3e6 100644 --- a/cli/compose/loader/loader.go +++ b/cli/compose/loader/loader.go @@ -220,7 +220,7 @@ func GetUnsupportedProperties(configDicts ...map[string]interface{}) []string { } func sortedKeys(set map[string]bool) []string { - var keys []string + keys := make([]string, 0, len(set)) for key := range set { keys = append(keys, key) } @@ -394,7 +394,7 @@ func formatInvalidKeyError(keyPrefix string, key interface{}) error { // LoadServices produces a ServiceConfig map from a compose file Dict // the servicesDict is not validated if directly used. Use Load() to enable validation func LoadServices(servicesDict map[string]interface{}, workingDir string, lookupEnv template.Mapping) ([]types.ServiceConfig, error) { - var services []types.ServiceConfig + services := make([]types.ServiceConfig, 0, len(servicesDict)) for name, serviceDef := range servicesDict { serviceConfig, err := LoadService(name, serviceDef.(map[string]interface{}), workingDir, lookupEnv) diff --git a/cli/context/store/metadatastore.go b/cli/context/store/metadatastore.go index 62c3f82a6a..d004875696 100644 --- a/cli/context/store/metadatastore.go +++ b/cli/context/store/metadatastore.go @@ -109,7 +109,7 @@ func (s *metadataStore) list() ([]Metadata, error) { } return nil, err } - var res []Metadata + res := make([]Metadata, 0, len(ctxDirs)) for _, dir := range ctxDirs { c, err := s.getByID(contextdir(dir)) if err != nil { diff --git a/cli/context/store/store.go b/cli/context/store/store.go index 7101252303..ceea2edd1d 100644 --- a/cli/context/store/store.go +++ b/cli/context/store/store.go @@ -125,7 +125,7 @@ func Names(s Lister) ([]string, error) { if err != nil { return nil, err } - var names []string + names := make([]string, 0, len(list)) for _, item := range list { names = append(names, item.Name) } diff --git a/cli/manifest/types/types.go b/cli/manifest/types/types.go index da7419259d..e098928de9 100644 --- a/cli/manifest/types/types.go +++ b/cli/manifest/types/types.go @@ -55,14 +55,18 @@ func PlatformSpecFromOCI(p *ocispec.Platform) *manifestlist.PlatformSpec { // Blobs returns the digests for all the blobs referenced by this manifest func (i ImageManifest) Blobs() []digest.Digest { - digests := []digest.Digest{} + var digests []digest.Digest switch { case i.SchemaV2Manifest != nil: - for _, descriptor := range i.SchemaV2Manifest.References() { + refs := i.SchemaV2Manifest.References() + digests = make([]digest.Digest, 0, len(refs)) + for _, descriptor := range refs { digests = append(digests, descriptor.Digest) } case i.OCIManifest != nil: - for _, descriptor := range i.OCIManifest.References() { + refs := i.OCIManifest.References() + digests = make([]digest.Digest, 0, len(refs)) + for _, descriptor := range refs { digests = append(digests, descriptor.Digest) } } diff --git a/opts/throttledevice.go b/opts/throttledevice.go index 789acf60fc..bdf454eb27 100644 --- a/opts/throttledevice.go +++ b/opts/throttledevice.go @@ -62,9 +62,8 @@ type ThrottledeviceOpt struct { // NewThrottledeviceOpt creates a new ThrottledeviceOpt func NewThrottledeviceOpt(validator ValidatorThrottleFctType) ThrottledeviceOpt { - values := []*blkiodev.ThrottleDevice{} return ThrottledeviceOpt{ - values: values, + values: []*blkiodev.ThrottleDevice{}, validator: validator, } } @@ -85,7 +84,7 @@ func (opt *ThrottledeviceOpt) Set(val string) error { // String returns ThrottledeviceOpt values as a string. func (opt *ThrottledeviceOpt) String() string { - var out []string + out := make([]string, 0, len(opt.values)) for _, v := range opt.values { out = append(out, v.String()) } @@ -95,7 +94,9 @@ func (opt *ThrottledeviceOpt) String() string { // GetList returns a slice of pointers to ThrottleDevices. func (opt *ThrottledeviceOpt) GetList() []*blkiodev.ThrottleDevice { - return append([]*blkiodev.ThrottleDevice{}, opt.values...) + out := make([]*blkiodev.ThrottleDevice, 0, len(opt.values)) + copy(out, opt.values) + return out } // Type returns the option type diff --git a/opts/ulimit.go b/opts/ulimit.go index 4667cc2544..5176b999a5 100644 --- a/opts/ulimit.go +++ b/opts/ulimit.go @@ -34,7 +34,7 @@ func (o *UlimitOpt) Set(val string) error { // String returns Ulimit values as a string. Values are sorted by name. func (o *UlimitOpt) String() string { - var out []string + out := make([]string, 0, len(*o.values)) for _, v := range *o.values { out = append(out, v.String()) } @@ -44,7 +44,7 @@ func (o *UlimitOpt) String() string { // GetList returns a slice of pointers to Ulimits. Values are sorted by name. func (o *UlimitOpt) GetList() []*units.Ulimit { - var ulimits []*units.Ulimit + ulimits := make([]*units.Ulimit, 0, len(*o.values)) for _, v := range *o.values { ulimits = append(ulimits, v) } diff --git a/opts/weightdevice.go b/opts/weightdevice.go index 3077e3da7f..ee377fc33a 100644 --- a/opts/weightdevice.go +++ b/opts/weightdevice.go @@ -65,7 +65,7 @@ func (opt *WeightdeviceOpt) Set(val string) error { // String returns WeightdeviceOpt values as a string. func (opt *WeightdeviceOpt) String() string { - var out []string + out := make([]string, 0, len(opt.values)) for _, v := range opt.values { out = append(out, v.String()) } From 888df09879e849aff26014bd4986dd633ebea523 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Mon, 20 Nov 2023 13:30:05 +0100 Subject: [PATCH 04/19] linting: address assorted issues found by gocritic internal/test/builders/config.go:36:15: captLocal: `ID' should not be capitalized (gocritic) func ConfigID(ID string) func(config *swarm.Config) { ^ internal/test/builders/secret.go:45:15: captLocal: `ID' should not be capitalized (gocritic) func SecretID(ID string) func(secret *swarm.Secret) { ^ internal/test/builders/service.go:21:16: captLocal: `ID' should not be capitalized (gocritic) func ServiceID(ID string) func(*swarm.Service) { ^ cli/command/image/formatter_history.go:100:15: wrapperFunc: use strings.ReplaceAll method in `strings.Replace(c.h.CreatedBy, "\t", " ", -1)` (gocritic) createdBy := strings.Replace(c.h.CreatedBy, "\t", " ", -1) ^ e2e/image/push_test.go:246:34: badCall: suspicious Join on 1 argument (gocritic) assert.NilError(t, os.RemoveAll(filepath.Join(dir.Join("trust")))) ^ e2e/image/push_test.go:313:34: badCall: suspicious Join on 1 argument (gocritic) assert.NilError(t, os.RemoveAll(filepath.Join(dir.Join("trust")))) ^ cli/config/configfile/file_test.go:185:2: assignOp: replace `c.GetAllCallCount = c.GetAllCallCount + 1` with `c.GetAllCallCount++` (gocritic) c.GetAllCallCount = c.GetAllCallCount + 1 ^ cli/command/context/inspect_test.go:20:58: wrapperFunc: use strings.ReplaceAll method in `strings.Replace(si.MetadataPath, `\`, `\\`, -1)` (gocritic) expected = strings.Replace(expected, "", strings.Replace(si.MetadataPath, `\`, `\\`, -1), 1) ^ cli/command/context/inspect_test.go:21:53: wrapperFunc: use strings.ReplaceAll method in `strings.Replace(si.TLSPath, `\`, `\\`, -1)` (gocritic) expected = strings.Replace(expected, "", strings.Replace(si.TLSPath, `\`, `\\`, -1), 1) ^ cli/command/container/formatter_stats.go:119:46: captLocal: `Stats' should not be capitalized (gocritic) func statsFormatWrite(ctx formatter.Context, Stats []StatsEntry, osType string, trunc bool) error { ^ cli/command/container/stats_helpers.go:209:4: assignOp: replace `blkRead = blkRead + bioEntry.Value` with `blkRead += bioEntry.Value` (gocritic) blkRead = blkRead + bioEntry.Value ^ cli/command/container/stats_helpers.go:211:4: assignOp: replace `blkWrite = blkWrite + bioEntry.Value` with `blkWrite += bioEntry.Value` (gocritic) blkWrite = blkWrite + bioEntry.Value ^ cli/command/registry/formatter_search.go:67:10: wrapperFunc: use strings.ReplaceAll method in `strings.Replace(c.s.Description, "\n", " ", -1)` (gocritic) desc := strings.Replace(c.s.Description, "\n", " ", -1) ^ cli/command/registry/formatter_search.go:68:9: wrapperFunc: use strings.ReplaceAll method in `strings.Replace(desc, "\r", " ", -1)` (gocritic) desc = strings.Replace(desc, "\r", " ", -1) ^ cli/command/service/list_test.go:164:5: assignOp: replace `tc.doc = tc.doc + " with quiet"` with `tc.doc += " with quiet"` (gocritic) tc.doc = tc.doc + " with quiet" ^ cli/command/service/progress/progress.go:274:11: wrapperFunc: use strings.ReplaceAll method in `strings.Replace(errMsg, "\n", " ", -1)` (gocritic) errMsg = strings.Replace(errMsg, "\n", " ", -1) ^ cli/manifest/store/store.go:153:9: wrapperFunc: use strings.ReplaceAll method in `strings.Replace(fileName, "/", "_", -1)` (gocritic) return strings.Replace(fileName, "/", "_", -1) ^ cli/manifest/store/store.go:152:14: wrapperFunc: use strings.ReplaceAll method in `strings.Replace(ref, ":", "-", -1)` (gocritic) fileName := strings.Replace(ref, ":", "-", -1) ^ cli/command/plugin/formatter.go:79:10: wrapperFunc: use strings.ReplaceAll method in `strings.Replace(c.p.Config.Description, "\n", "", -1)` (gocritic) desc := strings.Replace(c.p.Config.Description, "\n", "", -1) ^ cli/command/plugin/formatter.go:80:9: wrapperFunc: use strings.ReplaceAll method in `strings.Replace(desc, "\r", "", -1)` (gocritic) desc = strings.Replace(desc, "\r", "", -1) ^ cli/compose/convert/service.go:642:23: captLocal: `DNS' should not be capitalized (gocritic) func convertDNSConfig(DNS []string, DNSSearch []string) *swarm.DNSConfig { ^ Signed-off-by: Sebastiaan van Stijn --- cli/command/container/formatter_stats.go | 4 ++-- cli/command/container/stats_helpers.go | 4 ++-- cli/command/context/inspect_test.go | 4 ++-- cli/command/image/formatter_history.go | 2 +- cli/command/plugin/formatter.go | 4 ++-- cli/command/registry/formatter_search.go | 4 ++-- cli/command/service/list_test.go | 2 +- cli/command/service/progress/progress.go | 2 +- cli/compose/convert/service.go | 8 ++++---- cli/config/configfile/file_test.go | 2 +- cli/manifest/store/store.go | 4 ++-- e2e/image/push_test.go | 5 ++--- internal/test/builders/config.go | 4 ++-- internal/test/builders/secret.go | 4 ++-- internal/test/builders/service.go | 4 ++-- opts/hosts_test.go | 2 +- opts/opts_test.go | 6 ++---- 17 files changed, 31 insertions(+), 34 deletions(-) diff --git a/cli/command/container/formatter_stats.go b/cli/command/container/formatter_stats.go index c079c913ff..5b46fe2650 100644 --- a/cli/command/container/formatter_stats.go +++ b/cli/command/container/formatter_stats.go @@ -116,9 +116,9 @@ func NewStats(container string) *Stats { } // statsFormatWrite renders the context for a list of containers statistics -func statsFormatWrite(ctx formatter.Context, Stats []StatsEntry, osType string, trunc bool) error { +func statsFormatWrite(ctx formatter.Context, stats []StatsEntry, osType string, trunc bool) error { render := func(format func(subContext formatter.SubContext) error) error { - for _, cstats := range Stats { + for _, cstats := range stats { statsCtx := &statsContext{ s: cstats, os: osType, diff --git a/cli/command/container/stats_helpers.go b/cli/command/container/stats_helpers.go index 5ea7f665dc..938a3d83cd 100644 --- a/cli/command/container/stats_helpers.go +++ b/cli/command/container/stats_helpers.go @@ -206,9 +206,9 @@ func calculateBlockIO(blkio types.BlkioStats) (uint64, uint64) { } switch bioEntry.Op[0] { case 'r', 'R': - blkRead = blkRead + bioEntry.Value + blkRead += bioEntry.Value case 'w', 'W': - blkWrite = blkWrite + bioEntry.Value + blkWrite += bioEntry.Value } } return blkRead, blkWrite diff --git a/cli/command/context/inspect_test.go b/cli/command/context/inspect_test.go index 396a267d74..703898ed53 100644 --- a/cli/command/context/inspect_test.go +++ b/cli/command/context/inspect_test.go @@ -17,7 +17,7 @@ func TestInspect(t *testing.T) { })) expected := string(golden.Get(t, "inspect.golden")) si := cli.ContextStore().GetStorageInfo("current") - expected = strings.Replace(expected, "", strings.Replace(si.MetadataPath, `\`, `\\`, -1), 1) - expected = strings.Replace(expected, "", strings.Replace(si.TLSPath, `\`, `\\`, -1), 1) + expected = strings.Replace(expected, "", strings.ReplaceAll(si.MetadataPath, `\`, `\\`), 1) + expected = strings.Replace(expected, "", strings.ReplaceAll(si.TLSPath, `\`, `\\`), 1) assert.Equal(t, cli.OutBuffer().String(), expected) } diff --git a/cli/command/image/formatter_history.go b/cli/command/image/formatter_history.go index 4e826cb641..a36ab42576 100644 --- a/cli/command/image/formatter_history.go +++ b/cli/command/image/formatter_history.go @@ -97,7 +97,7 @@ func (c *historyContext) CreatedSince() string { } func (c *historyContext) CreatedBy() string { - createdBy := strings.Replace(c.h.CreatedBy, "\t", " ", -1) + createdBy := strings.ReplaceAll(c.h.CreatedBy, "\t", " ") if c.trunc { return formatter.Ellipsis(createdBy, 45) } diff --git a/cli/command/plugin/formatter.go b/cli/command/plugin/formatter.go index 438bf95171..c5c0c9c4e4 100644 --- a/cli/command/plugin/formatter.go +++ b/cli/command/plugin/formatter.go @@ -76,8 +76,8 @@ func (c *pluginContext) Name() string { } func (c *pluginContext) Description() string { - desc := strings.Replace(c.p.Config.Description, "\n", "", -1) - desc = strings.Replace(desc, "\r", "", -1) + desc := strings.ReplaceAll(c.p.Config.Description, "\n", "") + desc = strings.ReplaceAll(desc, "\r", "") if c.trunc { desc = formatter.Ellipsis(desc, 45) } diff --git a/cli/command/registry/formatter_search.go b/cli/command/registry/formatter_search.go index 7d3f55b4d4..ec11298968 100644 --- a/cli/command/registry/formatter_search.go +++ b/cli/command/registry/formatter_search.go @@ -64,8 +64,8 @@ func (c *searchContext) Name() string { } func (c *searchContext) Description() string { - desc := strings.Replace(c.s.Description, "\n", " ", -1) - desc = strings.Replace(desc, "\r", " ", -1) + desc := strings.ReplaceAll(c.s.Description, "\n", " ") + desc = strings.ReplaceAll(desc, "\r", " ") if c.trunc { desc = formatter.Ellipsis(desc, 45) } diff --git a/cli/command/service/list_test.go b/cli/command/service/list_test.go index 6a50210ec5..28952e5c0a 100644 --- a/cli/command/service/list_test.go +++ b/cli/command/service/list_test.go @@ -161,7 +161,7 @@ func TestServiceListServiceStatus(t *testing.T) { for _, tc := range tests { if quiet { tc.withQuiet = quiet - tc.doc = tc.doc + " with quiet" + tc.doc += " with quiet" } matrix = append(matrix, tc) } diff --git a/cli/command/service/progress/progress.go b/cli/command/service/progress/progress.go index d6f049f91b..61f347b8fb 100644 --- a/cli/command/service/progress/progress.go +++ b/cli/command/service/progress/progress.go @@ -271,7 +271,7 @@ func writeOverallProgress(progressOut progress.Output, numerator, denominator in func truncError(errMsg string) string { // Remove newlines from the error, which corrupt the output. - errMsg = strings.Replace(errMsg, "\n", " ", -1) + errMsg = strings.ReplaceAll(errMsg, "\n", " ") // Limit the length to 75 characters, so that even on narrow terminals // this will not overflow to the next line. diff --git a/cli/compose/convert/service.go b/cli/compose/convert/service.go index 2302245a01..e835380bff 100644 --- a/cli/compose/convert/service.go +++ b/cli/compose/convert/service.go @@ -639,11 +639,11 @@ func convertDeployMode(mode string, replicas *uint64) (swarm.ServiceMode, error) return serviceMode, nil } -func convertDNSConfig(DNS []string, DNSSearch []string) *swarm.DNSConfig { - if DNS != nil || DNSSearch != nil { +func convertDNSConfig(dns []string, dnsSearch []string) *swarm.DNSConfig { + if dns != nil || dnsSearch != nil { return &swarm.DNSConfig{ - Nameservers: DNS, - Search: DNSSearch, + Nameservers: dns, + Search: dnsSearch, } } return nil diff --git a/cli/config/configfile/file_test.go b/cli/config/configfile/file_test.go index 74a0317d5e..51aac67964 100644 --- a/cli/config/configfile/file_test.go +++ b/cli/config/configfile/file_test.go @@ -182,7 +182,7 @@ func (c *mockNativeStore) Get(registryHostname string) (types.AuthConfig, error) } func (c *mockNativeStore) GetAll() (map[string]types.AuthConfig, error) { - c.GetAllCallCount = c.GetAllCallCount + 1 + c.GetAllCallCount++ return c.authConfigs, nil } diff --git a/cli/manifest/store/store.go b/cli/manifest/store/store.go index 02c635674b..dbf7730632 100644 --- a/cli/manifest/store/store.go +++ b/cli/manifest/store/store.go @@ -149,8 +149,8 @@ func manifestToFilename(root, manifestList, manifest string) string { } func makeFilesafeName(ref string) string { - fileName := strings.Replace(ref, ":", "-", -1) - return strings.Replace(fileName, "/", "_", -1) + fileName := strings.ReplaceAll(ref, ":", "-") + return strings.ReplaceAll(fileName, "/", "_") } type notFoundError struct { diff --git a/e2e/image/push_test.go b/e2e/image/push_test.go index 9098aa0478..1774bd82ea 100644 --- a/e2e/image/push_test.go +++ b/e2e/image/push_test.go @@ -3,7 +3,6 @@ package image import ( "fmt" "os" - "path/filepath" "strings" "testing" @@ -243,7 +242,7 @@ func TestPushWithContentTrustSignsAllFirstLevelRolesWeHaveKeysFor(t *testing.T) targetsInRole = notaryListTargetsInRole(t, notaryDir, homeDir, baseRef, "targets") assert.Assert(t, targetsInRole["latest"] != "targets", "%v", targetsInRole) - assert.NilError(t, os.RemoveAll(filepath.Join(dir.Join("trust")))) + assert.NilError(t, os.RemoveAll(dir.Join("trust"))) // Try to pull, should fail because non of these are the release role // FIXME(vdemeester) should be unit test result = icmd.RunCmd(icmd.Command("docker", "pull", targetRef), @@ -310,7 +309,7 @@ func TestPushWithContentTrustSignsForRolesWithKeysAndValidPaths(t *testing.T) { targetsInRole = notaryListTargetsInRole(t, notaryDir, homeDir, baseRef, "targets") assert.Assert(t, targetsInRole["latest"] != "targets", "%v", targetsInRole) - assert.NilError(t, os.RemoveAll(filepath.Join(dir.Join("trust")))) + assert.NilError(t, os.RemoveAll(dir.Join("trust"))) // Try to pull, should fail because non of these are the release role // FIXME(vdemeester) should be unit test result = icmd.RunCmd(icmd.Command("docker", "pull", targetRef), diff --git a/internal/test/builders/config.go b/internal/test/builders/config.go index be48c30397..53aeb43e29 100644 --- a/internal/test/builders/config.go +++ b/internal/test/builders/config.go @@ -33,9 +33,9 @@ func ConfigName(name string) func(config *swarm.Config) { } // ConfigID sets the config's ID -func ConfigID(ID string) func(config *swarm.Config) { +func ConfigID(id string) func(config *swarm.Config) { return func(config *swarm.Config) { - config.ID = ID + config.ID = id } } diff --git a/internal/test/builders/secret.go b/internal/test/builders/secret.go index 3cd5f7872a..500193cab6 100644 --- a/internal/test/builders/secret.go +++ b/internal/test/builders/secret.go @@ -42,9 +42,9 @@ func SecretDriver(driver string) func(secret *swarm.Secret) { } // SecretID sets the secret's ID -func SecretID(ID string) func(secret *swarm.Secret) { +func SecretID(id string) func(secret *swarm.Secret) { return func(secret *swarm.Secret) { - secret.ID = ID + secret.ID = id } } diff --git a/internal/test/builders/service.go b/internal/test/builders/service.go index 4a6b50baa6..6548806769 100644 --- a/internal/test/builders/service.go +++ b/internal/test/builders/service.go @@ -18,9 +18,9 @@ func Service(builders ...func(*swarm.Service)) *swarm.Service { } // ServiceID sets the service ID -func ServiceID(ID string) func(*swarm.Service) { +func ServiceID(id string) func(*swarm.Service) { return func(service *swarm.Service) { - service.ID = ID + service.ID = id } } diff --git a/opts/hosts_test.go b/opts/hosts_test.go index 9d38d164be..f1b2ca6b12 100644 --- a/opts/hosts_test.go +++ b/opts/hosts_test.go @@ -57,7 +57,7 @@ func TestParseDockerDaemonHost(t *testing.T) { "udp://127.0.0.1": "invalid bind address format: udp://127.0.0.1", "udp://127.0.0.1:2375": "invalid bind address format: udp://127.0.0.1:2375", "tcp://unix:///run/docker.sock": "invalid proto, expected tcp: unix:///run/docker.sock", - " tcp://:7777/path ": "invalid bind address format: tcp://:7777/path ", + " tcp://:7777/path ": "invalid bind address format: tcp://:7777/path ", //nolint:gocritic // ignore mapKey: suspucious whitespace "": "invalid bind address format: ", } valids := map[string]string{ diff --git a/opts/opts_test.go b/opts/opts_test.go index 98b97003a8..2868b04f4f 100644 --- a/opts/opts_test.go +++ b/opts/opts_test.go @@ -428,10 +428,8 @@ func TestValidateLink(t *testing.T) { for link, expectedError := range invalid { if _, err := ValidateLink(link); err == nil { t.Fatalf("ValidateLink(`%q`) should have failed validation", link) - } else { - if !strings.Contains(err.Error(), expectedError) { - t.Fatalf("ValidateLink(`%q`) error should contain %q", link, expectedError) - } + } else if !strings.Contains(err.Error(), expectedError) { + t.Fatalf("ValidateLink(`%q`) error should contain %q", link, expectedError) } } } From a2c9f3c6ce661e56d01a69e82da0fc8ed8dfb713 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Mon, 20 Nov 2023 13:54:53 +0100 Subject: [PATCH 05/19] linting: address else/if/elseif statements found by gocritic cli/command/formatter/tabwriter/tabwriter.go:579:10: elseif: can replace 'else {if cond {}}' with 'else if cond {}' (gocritic) } else { ^ cli/connhelper/connhelper.go:43:2: singleCaseSwitch: should rewrite switch statement to if statement (gocritic) switch scheme := u.Scheme; scheme { ^ cli/compose/loader/loader.go:666:10: elseif: can replace 'else {if cond {}}' with 'else if cond {}' (gocritic) } else { ^ opts/hosts_test.go:173:10: elseif: can replace 'else {if cond {}}' with 'else if cond {}' (gocritic) } else { ^ cli-plugins/manager/candidate_test.go:78:4: ifElseChain: rewrite if-else to switch statement (gocritic) if tc.err != "" { ^ cli/command/checkpoint/formatter.go:15:2: singleCaseSwitch: should rewrite switch statement to if statement (gocritic) switch source { ^ cli/command/image/formatter_history.go:25:2: singleCaseSwitch: should rewrite switch statement to if statement (gocritic) switch source { ^ cli/command/service/scale.go:107:2: ifElseChain: rewrite if-else to switch statement (gocritic) if serviceMode.Replicated != nil { ^ cli/command/service/update.go:804:9: elseif: can replace 'else {if cond {}}' with 'else if cond {}' (gocritic) } else { ^ cli/command/service/update.go:222:2: ifElseChain: rewrite if-else to switch statement (gocritic) if sendAuth { ^ cli/command/container/formatter_diff.go:17:2: singleCaseSwitch: should rewrite switch statement to if statement (gocritic) switch source { ^ cli/command/container/start.go:79:2: ifElseChain: rewrite if-else to switch statement (gocritic) if opts.Attach || opts.OpenStdin { ^ cli/command/container/utils.go:84:11: elseif: can replace 'else {if cond {}}' with 'else if cond {}' (gocritic) } else { ^ cli/command/container/exec_test.go:200:11: elseif: can replace 'else {if cond {}}' with 'else if cond {}' (gocritic) } else { ^ cli/command/container/logs_test.go:52:11: elseif: can replace 'else {if cond {}}' with 'else if cond {}' (gocritic) } else { ^ cli/command/container/opts_test.go:1014:10: elseif: can replace 'else {if cond {}}' with 'else if cond {}' (gocritic) } else { ^ cli/command/system/info.go:297:7: singleCaseSwitch: should rewrite switch statement to if statement (gocritic) switch o.Key { ^ cli/command/system/version.go:164:4: singleCaseSwitch: should rewrite switch statement to if statement (gocritic) switch component.Name { ^ cli/command/system/info_test.go:478:4: ifElseChain: rewrite if-else to switch statement (gocritic) if tc.expectedOut != "" { ^ Signed-off-by: Sebastiaan van Stijn --- cli-plugins/manager/candidate_test.go | 7 ++++--- cli/command/checkpoint/formatter.go | 3 +-- cli/command/container/exec_test.go | 6 ++---- cli/command/container/formatter_diff.go | 3 +-- cli/command/container/logs_test.go | 6 ++---- cli/command/container/opts_test.go | 6 ++---- cli/command/container/start.go | 11 +++++------ cli/command/container/utils.go | 18 ++++++++---------- cli/command/formatter/tabwriter/tabwriter.go | 18 ++++++++---------- cli/command/image/formatter_history.go | 3 +-- cli/command/service/scale.go | 7 ++++--- cli/command/service/update.go | 9 +++++---- cli/command/system/info.go | 3 +-- cli/command/system/info_test.go | 7 ++++--- cli/command/system/version.go | 3 +-- cli/compose/loader/loader.go | 6 ++---- cli/connhelper/connhelper.go | 3 +-- opts/hosts_test.go | 6 ++---- 18 files changed, 54 insertions(+), 71 deletions(-) diff --git a/cli-plugins/manager/candidate_test.go b/cli-plugins/manager/candidate_test.go index 0ec7beda64..acf52e54ff 100644 --- a/cli-plugins/manager/candidate_test.go +++ b/cli-plugins/manager/candidate_test.go @@ -75,13 +75,14 @@ func TestValidateCandidate(t *testing.T) { } { t.Run(tc.name, func(t *testing.T) { p, err := newPlugin(tc.c, fakeroot.Commands()) - if tc.err != "" { + switch { + case tc.err != "": assert.ErrorContains(t, err, tc.err) - } else if tc.invalid != "" { + case tc.invalid != "": assert.NilError(t, err) assert.Assert(t, cmp.ErrorType(p.Err, reflect.TypeOf(&pluginError{}))) assert.ErrorContains(t, p.Err, tc.invalid) - } else { + default: assert.NilError(t, err) assert.Equal(t, NamePrefix+p.Name, goodPluginName) assert.Equal(t, p.SchemaVersion, "0.1.0") diff --git a/cli/command/checkpoint/formatter.go b/cli/command/checkpoint/formatter.go index e7d252100f..47ee77635b 100644 --- a/cli/command/checkpoint/formatter.go +++ b/cli/command/checkpoint/formatter.go @@ -12,8 +12,7 @@ const ( // NewFormat returns a format for use with a checkpoint Context func NewFormat(source string) formatter.Format { - switch source { - case formatter.TableFormatKey: + if source == formatter.TableFormatKey { return defaultCheckpointFormat } return formatter.Format(source) diff --git a/cli/command/container/exec_test.go b/cli/command/container/exec_test.go index e1ff1e61b4..2d79590ab8 100644 --- a/cli/command/container/exec_test.go +++ b/cli/command/container/exec_test.go @@ -197,10 +197,8 @@ func TestRunExec(t *testing.T) { err := RunExec(context.Background(), cli, "thecontainer", testcase.options) if testcase.expectedError != "" { assert.ErrorContains(t, err, testcase.expectedError) - } else { - if !assert.Check(t, err) { - return - } + } else if !assert.Check(t, err) { + return } assert.Check(t, is.Equal(testcase.expectedOut, cli.OutBuffer().String())) assert.Check(t, is.Equal(testcase.expectedErr, cli.ErrBuffer().String())) diff --git a/cli/command/container/formatter_diff.go b/cli/command/container/formatter_diff.go index 8baf11bfa0..822e1eef51 100644 --- a/cli/command/container/formatter_diff.go +++ b/cli/command/container/formatter_diff.go @@ -14,8 +14,7 @@ const ( // NewDiffFormat returns a format for use with a diff Context func NewDiffFormat(source string) formatter.Format { - switch source { - case formatter.TableFormatKey: + if source == formatter.TableFormatKey { return defaultDiffTableFormat } return formatter.Format(source) diff --git a/cli/command/container/logs_test.go b/cli/command/container/logs_test.go index d615badd96..a12fbde37e 100644 --- a/cli/command/container/logs_test.go +++ b/cli/command/container/logs_test.go @@ -49,10 +49,8 @@ func TestRunLogs(t *testing.T) { err := runLogs(cli, testcase.options) if testcase.expectedError != "" { assert.ErrorContains(t, err, testcase.expectedError) - } else { - if !assert.Check(t, err) { - return - } + } else if !assert.Check(t, err) { + return } assert.Check(t, is.Equal(testcase.expectedOut, cli.OutBuffer().String())) assert.Check(t, is.Equal(testcase.expectedErr, cli.ErrBuffer().String())) diff --git a/cli/command/container/opts_test.go b/cli/command/container/opts_test.go index a665c81169..89fa2d5838 100644 --- a/cli/command/container/opts_test.go +++ b/cli/command/container/opts_test.go @@ -1011,10 +1011,8 @@ func TestValidateDevice(t *testing.T) { for path, expectedError := range invalid { if _, err := validateDevice(path, runtime.GOOS); err == nil { t.Fatalf("ValidateDevice(`%q`) should have failed validation", path) - } else { - if err.Error() != expectedError { - t.Fatalf("ValidateDevice(`%q`) error should contain %q, got %q", path, expectedError, err.Error()) - } + } else if err.Error() != expectedError { + t.Fatalf("ValidateDevice(`%q`) error should contain %q, got %q", path, expectedError, err.Error()) } } } diff --git a/cli/command/container/start.go b/cli/command/container/start.go index f4a6421f5c..f750e36b5d 100644 --- a/cli/command/container/start.go +++ b/cli/command/container/start.go @@ -76,7 +76,8 @@ func RunStart(dockerCli command.Cli, opts *StartOptions) error { ctx, cancelFun := context.WithCancel(context.Background()) defer cancelFun() - if opts.Attach || opts.OpenStdin { + switch { + case opts.Attach || opts.OpenStdin: // We're going to attach to a container. // 1. Ensure we only have one container. if len(opts.Containers) > 1 { @@ -180,7 +181,8 @@ func RunStart(dockerCli command.Cli, opts *StartOptions) error { if status := <-statusChan; status != 0 { return cli.StatusError{StatusCode: status} } - } else if opts.Checkpoint != "" { + return nil + case opts.Checkpoint != "": if len(opts.Containers) > 1 { return errors.New("you cannot restore multiple containers at once") } @@ -189,14 +191,11 @@ func RunStart(dockerCli command.Cli, opts *StartOptions) error { CheckpointID: opts.Checkpoint, CheckpointDir: opts.CheckpointDir, }) - - } else { + default: // We're not going to attach to anything. // Start as many containers as we want. return startContainersWithoutAttachments(ctx, dockerCli, opts.Containers) } - - return nil } func startContainersWithoutAttachments(ctx context.Context, dockerCli command.Cli, containers []string) error { diff --git a/cli/command/container/utils.go b/cli/command/container/utils.go index bbe9724f96..8a94a182cd 100644 --- a/cli/command/container/utils.go +++ b/cli/command/container/utils.go @@ -81,18 +81,16 @@ func legacyWaitExitOrRemoved(ctx context.Context, apiClient client.APIClient, co } if !waitRemove { stopProcessing = true - } else { + } else if versions.LessThan(apiClient.ClientVersion(), "1.25") { // If we are talking to an older daemon, `AutoRemove` is not supported. // We need to fall back to the old behavior, which is client-side removal - if versions.LessThan(apiClient.ClientVersion(), "1.25") { - go func() { - removeErr = apiClient.ContainerRemove(ctx, containerID, container.RemoveOptions{RemoveVolumes: true}) - if removeErr != nil { - logrus.Errorf("error removing container: %v", removeErr) - cancel() // cancel the event Q - } - }() - } + go func() { + removeErr = apiClient.ContainerRemove(ctx, containerID, container.RemoveOptions{RemoveVolumes: true}) + if removeErr != nil { + logrus.Errorf("error removing container: %v", removeErr) + cancel() // cancel the event Q + } + }() } case "detach": exitCode = 0 diff --git a/cli/command/formatter/tabwriter/tabwriter.go b/cli/command/formatter/tabwriter/tabwriter.go index b5f6793ac4..079be60c83 100644 --- a/cli/command/formatter/tabwriter/tabwriter.go +++ b/cli/command/formatter/tabwriter/tabwriter.go @@ -576,18 +576,16 @@ func (b *Writer) Write(buf []byte) (n int, err error) { b.startEscape(ch) } } - } else { + } else if ch == b.endChar { // inside escape - if ch == b.endChar { - // end of tag/entity - j := i + 1 - if ch == Escape && b.flags&StripEscape != 0 { - j = i // strip Escape - } - b.append(buf[n:j]) - n = i + 1 // ch consumed - b.endEscape() + // end of tag/entity + j := i + 1 + if ch == Escape && b.flags&StripEscape != 0 { + j = i // strip Escape } + b.append(buf[n:j]) + n = i + 1 // ch consumed + b.endEscape() } } diff --git a/cli/command/image/formatter_history.go b/cli/command/image/formatter_history.go index a36ab42576..08b7febe3b 100644 --- a/cli/command/image/formatter_history.go +++ b/cli/command/image/formatter_history.go @@ -22,8 +22,7 @@ const ( // NewHistoryFormat returns a format for rendering an HistoryContext func NewHistoryFormat(source string, quiet bool, human bool) formatter.Format { - switch source { - case formatter.TableFormatKey: + if source == formatter.TableFormatKey { switch { case quiet: return formatter.DefaultQuietFormat diff --git a/cli/command/service/scale.go b/cli/command/service/scale.go index f2625445eb..bdc53ae401 100644 --- a/cli/command/service/scale.go +++ b/cli/command/service/scale.go @@ -104,11 +104,12 @@ func runServiceScale(ctx context.Context, dockerCli command.Cli, serviceID strin } serviceMode := &service.Spec.Mode - if serviceMode.Replicated != nil { + switch { + case serviceMode.Replicated != nil: serviceMode.Replicated.Replicas = &scale - } else if serviceMode.ReplicatedJob != nil { + case serviceMode.ReplicatedJob != nil: serviceMode.ReplicatedJob.TotalCompletions = &scale - } else { + default: return errors.Errorf("scale can only be used with replicated or replicated-job mode") } diff --git a/cli/command/service/update.go b/cli/command/service/update.go index 938edfc405..c4672493aa 100644 --- a/cli/command/service/update.go +++ b/cli/command/service/update.go @@ -219,7 +219,8 @@ func runUpdate(dockerCli command.Cli, flags *pflag.FlagSet, options *serviceOpti if err != nil { return err } - if sendAuth { + switch { + case sendAuth: // Retrieve encoded auth token from the image reference // This would be the old image if it didn't change in this update image := spec.TaskTemplate.ContainerSpec.Image @@ -228,9 +229,9 @@ func runUpdate(dockerCli command.Cli, flags *pflag.FlagSet, options *serviceOpti return err } updateOpts.EncodedRegistryAuth = encodedAuth - } else if clientSideRollback { + case clientSideRollback: updateOpts.RegistryAuthFrom = types.RegistryAuthFromPreviousSpec - } else { + default: updateOpts.RegistryAuthFrom = types.RegistryAuthFromSpec } @@ -801,7 +802,7 @@ func getUpdatedConfigs(apiClient client.ConfigAPIClient, flags *pflag.FlagSet, s if flags.Changed(flagCredentialSpec) { credSpec := flags.Lookup(flagCredentialSpec).Value.(*credentialSpecOpt).Value() credSpecConfigName = credSpec.Config - } else { + } else { //nolint:gocritic // ignore elseif: can replace 'else {if cond {}}' with 'else if cond {}' // if the credential spec flag has not changed, then check if there // already is a credentialSpec. if there is one, and it's for a Config, // then it's from the old object, and its value is the config ID. we diff --git a/cli/command/system/info.go b/cli/command/system/info.go index 6de1fcecd3..25bca56daf 100644 --- a/cli/command/system/info.go +++ b/cli/command/system/info.go @@ -294,8 +294,7 @@ func prettyPrintServerInfo(streams command.Streams, info *info) []error { for _, so := range kvs { fprintln(output, " "+so.Name) for _, o := range so.Options { - switch o.Key { - case "profile": + if o.Key == "profile" { fprintln(output, " Profile:", o.Value) } } diff --git a/cli/command/system/info_test.go b/cli/command/system/info_test.go index aa8fa4c33e..af26d3199b 100644 --- a/cli/command/system/info_test.go +++ b/cli/command/system/info_test.go @@ -475,12 +475,13 @@ func TestFormatInfo(t *testing.T) { ClientInfo: &clientInfo{Debug: true}, } err := formatInfo(cli.Out(), info, tc.template) - if tc.expectedOut != "" { + switch { + case tc.expectedOut != "": assert.NilError(t, err) assert.Equal(t, cli.OutBuffer().String(), tc.expectedOut) - } else if tc.expectedError != "" { + case tc.expectedError != "": assert.Error(t, err, tc.expectedError) - } else { + default: t.Fatal("test expected to neither pass nor fail") } }) diff --git a/cli/command/system/version.go b/cli/command/system/version.go index a84b93fe34..4cb34a0273 100644 --- a/cli/command/system/version.go +++ b/cli/command/system/version.go @@ -161,8 +161,7 @@ func runVersion(dockerCli command.Cli, opts *versionOptions) error { vd.Server = &sv foundEngine := false for _, component := range sv.Components { - switch component.Name { - case "Engine": + if component.Name == "Engine" { foundEngine = true buildTime, ok := component.Details["BuildTime"] if ok { diff --git a/cli/compose/loader/loader.go b/cli/compose/loader/loader.go index 3ac728b3e6..c5edd5c51f 100644 --- a/cli/compose/loader/loader.go +++ b/cli/compose/loader/loader.go @@ -663,10 +663,8 @@ func loadFileObjectConfig(name string, objType string, obj types.FileObjectConfi } obj.Name = obj.External.Name obj.External.Name = "" - } else { - if obj.Name == "" { - obj.Name = name - } + } else if obj.Name == "" { + obj.Name = name } // if not "external: true" case obj.Driver != "": diff --git a/cli/connhelper/connhelper.go b/cli/connhelper/connhelper.go index b98d97c25d..1797abaed4 100644 --- a/cli/connhelper/connhelper.go +++ b/cli/connhelper/connhelper.go @@ -40,8 +40,7 @@ func getConnectionHelper(daemonURL string, sshFlags []string) (*ConnectionHelper if err != nil { return nil, err } - switch scheme := u.Scheme; scheme { - case "ssh": + if u.Scheme == "ssh" { sp, err := ssh.ParseURL(daemonURL) if err != nil { return nil, errors.Wrap(err, "ssh host connection is not valid") diff --git a/opts/hosts_test.go b/opts/hosts_test.go index f1b2ca6b12..4da5f5625c 100644 --- a/opts/hosts_test.go +++ b/opts/hosts_test.go @@ -170,10 +170,8 @@ func TestValidateExtraHosts(t *testing.T) { for extraHost, expectedError := range invalid { if _, err := ValidateExtraHost(extraHost); err == nil { t.Fatalf("ValidateExtraHost(`%q`) should have failed validation", extraHost) - } else { - if !strings.Contains(err.Error(), expectedError) { - t.Fatalf("ValidateExtraHost(`%q`) error should contain %q", extraHost, expectedError) - } + } else if !strings.Contains(err.Error(), expectedError) { + t.Fatalf("ValidateExtraHost(`%q`) error should contain %q", extraHost, expectedError) } } } From 3f0c189e48c39ec7caed8d2cd00900000920e9dd Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Mon, 20 Nov 2023 14:26:41 +0100 Subject: [PATCH 06/19] linting: address slice-append issues found by gocritic cli/command/trust/inspect.go:74:33: appendAssign: append result not assigned to the same slice (gocritic) signatureRows[idx].Signers = append(sig.Signers, releasedRoleName) ^ cli/command/task/print.go:92:7: appendAssign: append result not assigned to the same slice (gocritic) t := append(tasks[:0:0], tasks...) ^ Signed-off-by: Sebastiaan van Stijn --- cli/command/task/print.go | 3 ++- cli/command/trust/inspect.go | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/cli/command/task/print.go b/cli/command/task/print.go index da9645b72c..4c9b362a2f 100644 --- a/cli/command/task/print.go +++ b/cli/command/task/print.go @@ -89,7 +89,8 @@ func Print(ctx context.Context, dockerCli command.Cli, tasks []swarm.Task, resol // Task-names are not unique in cases where "tasks" contains previous/rotated tasks. func generateTaskNames(ctx context.Context, tasks []swarm.Task, resolver *idresolver.IDResolver) ([]swarm.Task, error) { // Use a copy of the tasks list, to not modify the original slice - t := append(tasks[:0:0], tasks...) + // see https://github.com/go101/go101/wiki/How-to-efficiently-clone-a-slice%3F + t := append(tasks[:0:0], tasks...) //nolint:gocritic // ignore appendAssign: append result not assigned to the same slice for i, task := range t { serviceName, err := resolver.Resolve(ctx, swarm.Service{}, task.ServiceID) diff --git a/cli/command/trust/inspect.go b/cli/command/trust/inspect.go index d7370bd09d..980fb321c4 100644 --- a/cli/command/trust/inspect.go +++ b/cli/command/trust/inspect.go @@ -71,7 +71,7 @@ func getRepoTrustInfo(cli command.Cli, remote string) ([]byte, error) { // process the signatures to include repo admin if signed by the base targets role for idx, sig := range signatureRows { if len(sig.Signers) == 0 { - signatureRows[idx].Signers = append(sig.Signers, releasedRoleName) + signatureRows[idx].Signers = []string{releasedRoleName} } } From 9d7e21be2148d601db022246333256ef5cd636e1 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Mon, 20 Nov 2023 10:50:49 +0100 Subject: [PATCH 07/19] cli/command/manifest: rename vars that collided with import Signed-off-by: Sebastiaan van Stijn --- cli/command/manifest/inspect_test.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/cli/command/manifest/inspect_test.go b/cli/command/manifest/inspect_test.go index 6f5fd1c00c..6468400a1e 100644 --- a/cli/command/manifest/inspect_test.go +++ b/cli/command/manifest/inspect_test.go @@ -61,10 +61,10 @@ func fullImageManifest(t *testing.T, ref reference.Named) types.ImageManifest { } func TestInspectCommandLocalManifestNotFound(t *testing.T) { - store := store.NewStore(t.TempDir()) + refStore := store.NewStore(t.TempDir()) cli := test.NewFakeCli(nil) - cli.SetManifestStore(store) + cli.SetManifestStore(refStore) cmd := newInspectCommand(cli) cmd.SetOut(io.Discard) @@ -74,10 +74,10 @@ func TestInspectCommandLocalManifestNotFound(t *testing.T) { } func TestInspectCommandNotFound(t *testing.T) { - store := store.NewStore(t.TempDir()) + refStore := store.NewStore(t.TempDir()) cli := test.NewFakeCli(nil) - cli.SetManifestStore(store) + cli.SetManifestStore(refStore) cli.SetRegistryClient(&fakeRegistryClient{ getManifestFunc: func(_ context.Context, _ reference.Named) (types.ImageManifest, error) { return types.ImageManifest{}, errors.New("missing") @@ -95,13 +95,13 @@ func TestInspectCommandNotFound(t *testing.T) { } func TestInspectCommandLocalManifest(t *testing.T) { - store := store.NewStore(t.TempDir()) + refStore := store.NewStore(t.TempDir()) cli := test.NewFakeCli(nil) - cli.SetManifestStore(store) + cli.SetManifestStore(refStore) namedRef := ref(t, "alpine:3.0") imageManifest := fullImageManifest(t, namedRef) - err := store.Save(ref(t, "list:v1"), namedRef, imageManifest) + err := refStore.Save(ref(t, "list:v1"), namedRef, imageManifest) assert.NilError(t, err) cmd := newInspectCommand(cli) @@ -113,10 +113,10 @@ func TestInspectCommandLocalManifest(t *testing.T) { } func TestInspectcommandRemoteManifest(t *testing.T) { - store := store.NewStore(t.TempDir()) + refStore := store.NewStore(t.TempDir()) cli := test.NewFakeCli(nil) - cli.SetManifestStore(store) + cli.SetManifestStore(refStore) cli.SetRegistryClient(&fakeRegistryClient{ getManifestFunc: func(_ context.Context, ref reference.Named) (types.ImageManifest, error) { return fullImageManifest(t, ref), nil From 8e98c765f8f0efafced454276a4aa93dd8e6f750 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Mon, 20 Nov 2023 13:10:24 +0100 Subject: [PATCH 08/19] cli/command/system: fix deprecated comments (gocritic) cli/command/system/info.go:470:1: deprecatedComment: use `Deprecated: ` (note the casing) instead of `DEPRECATED: ` (gocritic) // DEPRECATED: warnings are now generated by the daemon, and returned in ^ cli/command/system/info.go:492:1: deprecatedComment: use `Deprecated: ` (note the casing) instead of `DEPRECATED: ` (gocritic) // DEPRECATED: warnings are now generated by the daemon, and returned in ^ Signed-off-by: Sebastiaan van Stijn --- cli/command/system/info.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cli/command/system/info.go b/cli/command/system/info.go index 25bca56daf..6259eab333 100644 --- a/cli/command/system/info.go +++ b/cli/command/system/info.go @@ -466,7 +466,8 @@ func printServerWarnings(stdErr io.Writer, info *info) { // printSecurityOptionsWarnings prints warnings based on the security options // returned by the daemon. -// DEPRECATED: warnings are now generated by the daemon, and returned in +// +// Deprecated: warnings are now generated by the daemon, and returned in // info.Warnings. This function is used to provide backward compatibility with // daemons that do not provide these warnings. No new warnings should be added // here. @@ -488,7 +489,8 @@ func printSecurityOptionsWarnings(stdErr io.Writer, info system.Info) { } // printServerWarningsLegacy generates warnings based on information returned by the daemon. -// DEPRECATED: warnings are now generated by the daemon, and returned in +// +// Deprecated: warnings are now generated by the daemon, and returned in // info.Warnings. This function is used to provide backward compatibility with // daemons that do not provide these warnings. No new warnings should be added // here. From 8661552e7a8c5e551887397d72edf87de55c47a6 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Mon, 20 Nov 2023 11:10:29 +0100 Subject: [PATCH 09/19] golangci-lint: enable thelper linter Signed-off-by: Sebastiaan van Stijn --- .golangci.yml | 1 + cli/command/cli_options_test.go | 1 + cli/command/context/create_test.go | 1 + .../formatter/tabwriter/tabwriter_test.go | 4 + cli/command/image/build/context_test.go | 4 + cli/command/manifest/inspect_test.go | 2 + cli/command/service/inspect_test.go | 1 + cli/command/trust/key_load_test.go | 156 +++++++++--------- cli/config/config_test.go | 1 + cli/required_test.go | 42 +++-- e2e/cli-plugins/util_test.go | 1 + e2e/container/attach_test.go | 20 +-- e2e/container/kill_test.go | 20 +-- e2e/container/run_test.go | 1 + e2e/image/push_test.go | 8 + e2e/plugin/trust_test.go | 1 + e2e/stack/remove_test.go | 2 + e2e/trust/revoke_test.go | 2 + e2e/trust/sign_test.go | 1 + internal/test/strings.go | 1 + opts/port_test.go | 1 + 21 files changed, 147 insertions(+), 124 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 5553fb5337..bef425b96d 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -16,6 +16,7 @@ linters: - nakedret - revive - staticcheck + - thelper - typecheck - unconvert - unparam diff --git a/cli/command/cli_options_test.go b/cli/command/cli_options_test.go index 4ed0f8f90e..45ac1d8a57 100644 --- a/cli/command/cli_options_test.go +++ b/cli/command/cli_options_test.go @@ -8,6 +8,7 @@ import ( ) func contentTrustEnabled(t *testing.T) bool { + t.Helper() var cli DockerCli assert.NilError(t, WithContentTrustFromEnv()(&cli)) return cli.contentTrust diff --git a/cli/command/context/create_test.go b/cli/command/context/create_test.go index e962f5a680..a887c978bd 100644 --- a/cli/command/context/create_test.go +++ b/cli/command/context/create_test.go @@ -104,6 +104,7 @@ func TestCreate(t *testing.T) { } func assertContextCreateLogging(t *testing.T, cli *test.FakeCli, n string) { + t.Helper() assert.Equal(t, n+"\n", cli.OutBuffer().String()) assert.Equal(t, fmt.Sprintf("Successfully created context %q\n", n), cli.ErrBuffer().String()) } diff --git a/cli/command/formatter/tabwriter/tabwriter_test.go b/cli/command/formatter/tabwriter/tabwriter_test.go index 03530c2508..45669b36d8 100644 --- a/cli/command/formatter/tabwriter/tabwriter_test.go +++ b/cli/command/formatter/tabwriter/tabwriter_test.go @@ -36,6 +36,7 @@ func (b *buffer) Write(buf []byte) (written int, err error) { func (b *buffer) String() string { return string(b.a) } func write(t *testing.T, testname string, w *Writer, src string) { + t.Helper() written, err := io.WriteString(w, src) if err != nil { t.Errorf("--- test: %s\n--- src:\n%q\n--- write error: %v\n", testname, src, err) @@ -46,6 +47,7 @@ func write(t *testing.T, testname string, w *Writer, src string) { } func verify(t *testing.T, testname string, w *Writer, b *buffer, src, expected string) { + t.Helper() err := w.Flush() if err != nil { t.Errorf("--- test: %s\n--- src:\n%q\n--- flush error: %v\n", testname, src, err) @@ -58,6 +60,7 @@ func verify(t *testing.T, testname string, w *Writer, b *buffer, src, expected s } func check(t *testing.T, testname string, minwidth, tabwidth, padding int, padchar byte, flags uint, src, expected string) { + t.Helper() var b buffer b.init(1000) @@ -622,6 +625,7 @@ func (panicWriter) Write([]byte) (int, error) { } func wantPanicString(t *testing.T, want string) { + t.Helper() if e := recover(); e != nil { got, ok := e.(string) switch { diff --git a/cli/command/image/build/context_test.go b/cli/command/image/build/context_test.go index 63cfaa0e12..071a0f30ce 100644 --- a/cli/command/image/build/context_test.go +++ b/cli/command/image/build/context_test.go @@ -23,16 +23,19 @@ func prepareEmpty(_ *testing.T) string { } func prepareNoFiles(t *testing.T) string { + t.Helper() return createTestTempDir(t) } func prepareOneFile(t *testing.T) string { + t.Helper() contextDir := createTestTempDir(t) createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents) return contextDir } func testValidateContextDirectory(t *testing.T, prepare func(t *testing.T) string, excludes []string) { + t.Helper() contextDir := prepare(t) err := ValidateContextDirectory(contextDir, excludes) assert.NilError(t, err) @@ -250,6 +253,7 @@ func createTestTempFile(t *testing.T, dir, filename, contents string) string { // This function is meant to be executed as a deferred call. // When an error occurs, it terminates the test. func chdir(t *testing.T, dir string) { + t.Helper() workingDirectory, err := os.Getwd() assert.NilError(t, err) assert.NilError(t, os.Chdir(dir)) diff --git a/cli/command/manifest/inspect_test.go b/cli/command/manifest/inspect_test.go index 6468400a1e..af4e17af3c 100644 --- a/cli/command/manifest/inspect_test.go +++ b/cli/command/manifest/inspect_test.go @@ -20,12 +20,14 @@ import ( ) func ref(t *testing.T, name string) reference.Named { + t.Helper() named, err := reference.ParseNamed("example.com/" + name) assert.NilError(t, err) return named } func fullImageManifest(t *testing.T, ref reference.Named) types.ImageManifest { + t.Helper() man, err := schema2.FromStruct(schema2.Manifest{ Versioned: schema2.SchemaVersion, Config: distribution.Descriptor{ diff --git a/cli/command/service/inspect_test.go b/cli/command/service/inspect_test.go index 15f9209278..04c2bdec6b 100644 --- a/cli/command/service/inspect_test.go +++ b/cli/command/service/inspect_test.go @@ -17,6 +17,7 @@ import ( ) func formatServiceInspect(t *testing.T, format formatter.Format, now time.Time) string { + t.Helper() b := new(bytes.Buffer) endpointSpec := &swarm.EndpointSpec{ diff --git a/cli/command/trust/key_load_test.go b/cli/command/trust/key_load_test.go index fd791a9bb6..74f2f91dc3 100644 --- a/cli/command/trust/key_load_test.go +++ b/cli/command/trust/key_load_test.go @@ -114,101 +114,93 @@ var testKeys = map[string][]byte{ func TestLoadKeyFromPath(t *testing.T) { skip.If(t, runtime.GOOS == "windows") for keyID, keyBytes := range testKeys { - keyID, keyBytes := keyID, keyBytes + privKeyID, privKeyFixture := keyID, keyBytes t.Run(fmt.Sprintf("load-key-id-%s-from-path", keyID), func(t *testing.T) { - testLoadKeyFromPath(t, keyID, keyBytes) + privKeyFilepath := filepath.Join(t.TempDir(), "privkey.pem") + assert.NilError(t, os.WriteFile(privKeyFilepath, privKeyFixture, notary.PrivNoExecPerms)) + + keyStorageDir := t.TempDir() + + const passwd = "password" + cannedPasswordRetriever := passphrase.ConstantRetriever(passwd) + keyFileStore, err := storage.NewPrivateKeyFileStorage(keyStorageDir, notary.KeyExtension) + assert.NilError(t, err) + privKeyImporters := []trustmanager.Importer{keyFileStore} + + // get the privKeyBytes + privKeyBytes, err := getPrivKeyBytesFromPath(privKeyFilepath) + assert.NilError(t, err) + + // import the key to our keyStorageDir + assert.Check(t, loadPrivKeyBytesToStore(privKeyBytes, privKeyImporters, privKeyFilepath, "signer-name", cannedPasswordRetriever)) + + // check that the appropriate ~//private/.key file exists + expectedImportKeyPath := filepath.Join(keyStorageDir, notary.PrivDir, privKeyID+"."+notary.KeyExtension) + _, err = os.Stat(expectedImportKeyPath) + assert.NilError(t, err) + + // verify the key content + from, _ := os.OpenFile(expectedImportKeyPath, os.O_RDONLY, notary.PrivExecPerms) + defer from.Close() + fromBytes, _ := io.ReadAll(from) + keyPEM, _ := pem.Decode(fromBytes) + assert.Check(t, is.Equal("signer-name", keyPEM.Headers["role"])) + // the default GUN is empty + assert.Check(t, is.Equal("", keyPEM.Headers["gun"])) + // assert encrypted header + assert.Check(t, is.Equal("ENCRYPTED PRIVATE KEY", keyPEM.Type)) + + decryptedKey, err := tufutils.ParsePKCS8ToTufKey(keyPEM.Bytes, []byte(passwd)) + assert.NilError(t, err) + fixturePEM, _ := pem.Decode(privKeyFixture) + assert.Check(t, is.DeepEqual(fixturePEM.Bytes, decryptedKey.Private())) }) } } -func testLoadKeyFromPath(t *testing.T, privKeyID string, privKeyFixture []byte) { - privKeyFilepath := filepath.Join(t.TempDir(), "privkey.pem") - assert.NilError(t, os.WriteFile(privKeyFilepath, privKeyFixture, notary.PrivNoExecPerms)) - - keyStorageDir := t.TempDir() - - const passwd = "password" - cannedPasswordRetriever := passphrase.ConstantRetriever(passwd) - keyFileStore, err := storage.NewPrivateKeyFileStorage(keyStorageDir, notary.KeyExtension) - assert.NilError(t, err) - privKeyImporters := []trustmanager.Importer{keyFileStore} - - // get the privKeyBytes - privKeyBytes, err := getPrivKeyBytesFromPath(privKeyFilepath) - assert.NilError(t, err) - - // import the key to our keyStorageDir - assert.Check(t, loadPrivKeyBytesToStore(privKeyBytes, privKeyImporters, privKeyFilepath, "signer-name", cannedPasswordRetriever)) - - // check that the appropriate ~//private/.key file exists - expectedImportKeyPath := filepath.Join(keyStorageDir, notary.PrivDir, privKeyID+"."+notary.KeyExtension) - _, err = os.Stat(expectedImportKeyPath) - assert.NilError(t, err) - - // verify the key content - from, _ := os.OpenFile(expectedImportKeyPath, os.O_RDONLY, notary.PrivExecPerms) - defer from.Close() - fromBytes, _ := io.ReadAll(from) - keyPEM, _ := pem.Decode(fromBytes) - assert.Check(t, is.Equal("signer-name", keyPEM.Headers["role"])) - // the default GUN is empty - assert.Check(t, is.Equal("", keyPEM.Headers["gun"])) - // assert encrypted header - assert.Check(t, is.Equal("ENCRYPTED PRIVATE KEY", keyPEM.Type)) - - decryptedKey, err := tufutils.ParsePKCS8ToTufKey(keyPEM.Bytes, []byte(passwd)) - assert.NilError(t, err) - fixturePEM, _ := pem.Decode(privKeyFixture) - assert.Check(t, is.DeepEqual(fixturePEM.Bytes, decryptedKey.Private())) -} - func TestLoadKeyTooPermissive(t *testing.T) { skip.If(t, runtime.GOOS == "windows") for keyID, keyBytes := range testKeys { - keyID, keyBytes := keyID, keyBytes + keyID, privKeyFixture := keyID, keyBytes t.Run(fmt.Sprintf("load-key-id-%s-too-permissive", keyID), func(t *testing.T) { - testLoadKeyTooPermissive(t, keyBytes) + privKeyDir := t.TempDir() + privKeyFilepath := filepath.Join(privKeyDir, "privkey477.pem") + assert.NilError(t, os.WriteFile(privKeyFilepath, privKeyFixture, 0o477)) + + // import the key to our keyStorageDir + _, err := getPrivKeyBytesFromPath(privKeyFilepath) + expected := fmt.Sprintf("private key file %s must not be readable or writable by others", privKeyFilepath) + assert.Error(t, err, expected) + + privKeyFilepath = filepath.Join(privKeyDir, "privkey667.pem") + assert.NilError(t, os.WriteFile(privKeyFilepath, privKeyFixture, 0o677)) + + _, err = getPrivKeyBytesFromPath(privKeyFilepath) + expected = fmt.Sprintf("private key file %s must not be readable or writable by others", privKeyFilepath) + assert.Error(t, err, expected) + + privKeyFilepath = filepath.Join(privKeyDir, "privkey777.pem") + assert.NilError(t, os.WriteFile(privKeyFilepath, privKeyFixture, 0o777)) + + _, err = getPrivKeyBytesFromPath(privKeyFilepath) + expected = fmt.Sprintf("private key file %s must not be readable or writable by others", privKeyFilepath) + assert.Error(t, err, expected) + + privKeyFilepath = filepath.Join(privKeyDir, "privkey400.pem") + assert.NilError(t, os.WriteFile(privKeyFilepath, privKeyFixture, 0o400)) + + _, err = getPrivKeyBytesFromPath(privKeyFilepath) + assert.NilError(t, err) + + privKeyFilepath = filepath.Join(privKeyDir, "privkey600.pem") + assert.NilError(t, os.WriteFile(privKeyFilepath, privKeyFixture, 0o600)) + + _, err = getPrivKeyBytesFromPath(privKeyFilepath) + assert.NilError(t, err) }) } } -func testLoadKeyTooPermissive(t *testing.T, privKeyFixture []byte) { - privKeyDir := t.TempDir() - privKeyFilepath := filepath.Join(privKeyDir, "privkey477.pem") - assert.NilError(t, os.WriteFile(privKeyFilepath, privKeyFixture, 0o477)) - - // import the key to our keyStorageDir - _, err := getPrivKeyBytesFromPath(privKeyFilepath) - expected := fmt.Sprintf("private key file %s must not be readable or writable by others", privKeyFilepath) - assert.Error(t, err, expected) - - privKeyFilepath = filepath.Join(privKeyDir, "privkey667.pem") - assert.NilError(t, os.WriteFile(privKeyFilepath, privKeyFixture, 0o677)) - - _, err = getPrivKeyBytesFromPath(privKeyFilepath) - expected = fmt.Sprintf("private key file %s must not be readable or writable by others", privKeyFilepath) - assert.Error(t, err, expected) - - privKeyFilepath = filepath.Join(privKeyDir, "privkey777.pem") - assert.NilError(t, os.WriteFile(privKeyFilepath, privKeyFixture, 0o777)) - - _, err = getPrivKeyBytesFromPath(privKeyFilepath) - expected = fmt.Sprintf("private key file %s must not be readable or writable by others", privKeyFilepath) - assert.Error(t, err, expected) - - privKeyFilepath = filepath.Join(privKeyDir, "privkey400.pem") - assert.NilError(t, os.WriteFile(privKeyFilepath, privKeyFixture, 0o400)) - - _, err = getPrivKeyBytesFromPath(privKeyFilepath) - assert.NilError(t, err) - - privKeyFilepath = filepath.Join(privKeyDir, "privkey600.pem") - assert.NilError(t, os.WriteFile(privKeyFilepath, privKeyFixture, 0o600)) - - _, err = getPrivKeyBytesFromPath(privKeyFilepath) - assert.NilError(t, err) -} - var pubKeyFixture = []byte(`-----BEGIN PUBLIC KEY----- MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEUIH9AYtrcDFzZrFJBdJZkn21d+4c H3nzy2O6Q/ct4BjOBKa+WCdRtPo78bA+C/7t81ADQO8Jqaj59W50rwoqDQ== diff --git a/cli/config/config_test.go b/cli/config/config_test.go index 0efd675b38..b513a21522 100644 --- a/cli/config/config_test.go +++ b/cli/config/config_test.go @@ -15,6 +15,7 @@ import ( ) func setupConfigDir(t *testing.T) string { + t.Helper() tmpdir := t.TempDir() oldDir := Dir() SetDir(tmpdir) diff --git a/cli/required_test.go b/cli/required_test.go index 41d1ac0236..eadc8645c4 100644 --- a/cli/required_test.go +++ b/cli/required_test.go @@ -21,7 +21,11 @@ func TestRequiresNoArgs(t *testing.T) { expectedError: "accepts no arguments.", }, } - runTestCases(t, testCases) + for _, tc := range testCases { + cmd := newDummyCommand(tc.validateFunc) + cmd.SetArgs(tc.args) + assert.ErrorContains(t, cmd.Execute(), tc.expectedError) + } } func TestRequiresMinArgs(t *testing.T) { @@ -40,7 +44,11 @@ func TestRequiresMinArgs(t *testing.T) { expectedError: "at least 2 arguments.", }, } - runTestCases(t, testCases) + for _, tc := range testCases { + cmd := newDummyCommand(tc.validateFunc) + cmd.SetArgs(tc.args) + assert.ErrorContains(t, cmd.Execute(), tc.expectedError) + } } func TestRequiresMaxArgs(t *testing.T) { @@ -60,7 +68,11 @@ func TestRequiresMaxArgs(t *testing.T) { expectedError: "at most 2 arguments.", }, } - runTestCases(t, testCases) + for _, tc := range testCases { + cmd := newDummyCommand(tc.validateFunc) + cmd.SetArgs(tc.args) + assert.ErrorContains(t, cmd.Execute(), tc.expectedError) + } } func TestRequiresRangeArgs(t *testing.T) { @@ -88,7 +100,11 @@ func TestRequiresRangeArgs(t *testing.T) { expectedError: "at least 1 ", }, } - runTestCases(t, testCases) + for _, tc := range testCases { + cmd := newDummyCommand(tc.validateFunc) + cmd.SetArgs(tc.args) + assert.ErrorContains(t, cmd.Execute(), tc.expectedError) + } } func TestExactArgs(t *testing.T) { @@ -106,7 +122,11 @@ func TestExactArgs(t *testing.T) { expectedError: "exactly 2 arguments.", }, } - runTestCases(t, testCases) + for _, tc := range testCases { + cmd := newDummyCommand(tc.validateFunc) + cmd.SetArgs(tc.args) + assert.ErrorContains(t, cmd.Execute(), tc.expectedError) + } } type testCase struct { @@ -115,17 +135,6 @@ type testCase struct { expectedError string } -func runTestCases(t *testing.T, testCases []testCase) { - for _, tc := range testCases { - cmd := newDummyCommand(tc.validateFunc) - cmd.SetArgs(tc.args) - cmd.SetOut(io.Discard) - - err := cmd.Execute() - assert.ErrorContains(t, err, tc.expectedError) - } -} - func newDummyCommand(validationFunc cobra.PositionalArgs) *cobra.Command { cmd := &cobra.Command{ Use: "dummy", @@ -134,5 +143,6 @@ func newDummyCommand(validationFunc cobra.PositionalArgs) *cobra.Command { return errors.New("no error") }, } + cmd.SetOut(io.Discard) return cmd } diff --git a/e2e/cli-plugins/util_test.go b/e2e/cli-plugins/util_test.go index c2a4406a46..2f8e0f34e7 100644 --- a/e2e/cli-plugins/util_test.go +++ b/e2e/cli-plugins/util_test.go @@ -13,6 +13,7 @@ import ( ) func prepare(t *testing.T) (func(args ...string) icmd.Cmd, *configfile.ConfigFile, func()) { + t.Helper() cfg := fs.NewDir(t, "plugin-test", fs.WithFile("config.json", fmt.Sprintf(`{"cliPluginsExtraDirs": [%q]}`, os.Getenv("DOCKER_CLI_E2E_PLUGINS_EXTRA_DIRS"))), ) diff --git a/e2e/container/attach_test.go b/e2e/container/attach_test.go index 68517b3613..9b2ee9cdb8 100644 --- a/e2e/container/attach_test.go +++ b/e2e/container/attach_test.go @@ -10,20 +10,14 @@ import ( ) func TestAttachExitCode(t *testing.T) { - containerID := runBackgroundContainsWithExitCode(t, 21) - - result := icmd.RunCmd( - icmd.Command("docker", "attach", containerID), - withStdinNewline) - - result.Assert(t, icmd.Expected{ExitCode: 21}) -} - -func runBackgroundContainsWithExitCode(t *testing.T, exitcode int) string { - result := icmd.RunCommand("docker", "run", "-d", "-i", "--rm", fixtures.AlpineImage, - "sh", "-c", fmt.Sprintf("read; exit %d", exitcode)) + const exitCode = 21 + result := icmd.RunCommand("docker", "run", "-d", "-i", "--rm", fixtures.AlpineImage, "sh", "-c", fmt.Sprintf("read; exit %d", exitCode)) result.Assert(t, icmd.Success) - return strings.TrimSpace(result.Stdout()) + + containerID := strings.TrimSpace(result.Stdout()) + + result = icmd.RunCmd(icmd.Command("docker", "attach", containerID), withStdinNewline) + result.Assert(t, icmd.Expected{ExitCode: exitCode}) } func withStdinNewline(cmd *icmd.Cmd) { diff --git a/e2e/container/kill_test.go b/e2e/container/kill_test.go index 2f3a35784f..d4deecc18f 100644 --- a/e2e/container/kill_test.go +++ b/e2e/container/kill_test.go @@ -11,33 +11,27 @@ import ( ) func TestKillContainer(t *testing.T) { - containerID := runBackgroundTop(t) + result := icmd.RunCommand("docker", "run", "-d", fixtures.AlpineImage, "top") + result.Assert(t, icmd.Success) + + containerID := strings.TrimSpace(result.Stdout()) // Kill with SIGTERM should kill the process - result := icmd.RunCmd( - icmd.Command("docker", "kill", "-s", "SIGTERM", containerID), - ) + result = icmd.RunCmd(icmd.Command("docker", "kill", "-s", "SIGTERM", containerID)) result.Assert(t, icmd.Success) poll.WaitOn(t, containerStatus(t, containerID, "exited"), poll.WithDelay(100*time.Millisecond), poll.WithTimeout(5*time.Second)) // Kill on a stop container should return an error - result = icmd.RunCmd( - icmd.Command("docker", "kill", containerID), - ) + result = icmd.RunCmd(icmd.Command("docker", "kill", containerID)) result.Assert(t, icmd.Expected{ ExitCode: 1, Err: "is not running", }) } -func runBackgroundTop(t *testing.T) string { - result := icmd.RunCommand("docker", "run", "-d", fixtures.AlpineImage, "top") - result.Assert(t, icmd.Success) - return strings.TrimSpace(result.Stdout()) -} - func containerStatus(t *testing.T, containerID, status string) func(poll.LogT) poll.Result { + t.Helper() return func(poll.LogT) poll.Result { result := icmd.RunCommand("docker", "inspect", "-f", "{{ .State.Status }}", containerID) result.Assert(t, icmd.Success) diff --git a/e2e/container/run_test.go b/e2e/container/run_test.go index 3b0414ffab..3f110156ed 100644 --- a/e2e/container/run_test.go +++ b/e2e/container/run_test.go @@ -132,6 +132,7 @@ func TestTrustedRunFromBadTrustServer(t *testing.T) { // TODO: create this with registry API instead of engine API func createRemoteImage(t *testing.T) string { + t.Helper() image := registryPrefix + "/alpine:test-run-pulls" icmd.RunCommand("docker", "pull", fixtures.AlpineImage).Assert(t, icmd.Success) icmd.RunCommand("docker", "tag", fixtures.AlpineImage, image).Assert(t, icmd.Success) diff --git a/e2e/image/push_test.go b/e2e/image/push_test.go index 1774bd82ea..4069692197 100644 --- a/e2e/image/push_test.go +++ b/e2e/image/push_test.go @@ -323,6 +323,7 @@ func TestPushWithContentTrustSignsForRolesWithKeysAndValidPaths(t *testing.T) { } func createImage(t *testing.T, repo string, tags ...string) string { + t.Helper() icmd.RunCommand("docker", "pull", fixtures.AlpineImage).Assert(t, icmd.Success) for _, tag := range tags { @@ -345,6 +346,7 @@ func withNotaryPassphrase(pwd string) func(*icmd.Cmd) { } func notaryImportPrivateKey(t *testing.T, notaryDir, homeDir *fs.Dir, baseRef, role, privkey string) { + t.Helper() icmd.RunCmd( icmd.Command(notary, "-c", notaryDir.Join("client-config.json"), "key", "import", privkey, "-g", baseRef, "-r", role), withNotaryPassphrase("foo"), @@ -353,6 +355,7 @@ func notaryImportPrivateKey(t *testing.T, notaryDir, homeDir *fs.Dir, baseRef, r } func notaryPublish(t *testing.T, notaryDir, homeDir *fs.Dir, baseRef string) { + t.Helper() icmd.RunCmd( icmd.Command(notary, "-c", notaryDir.Join("client-config.json"), "publish", baseRef), withNotaryPassphrase("foo"), @@ -361,6 +364,7 @@ func notaryPublish(t *testing.T, notaryDir, homeDir *fs.Dir, baseRef string) { } func notaryAddDelegation(t *testing.T, notaryDir, homeDir *fs.Dir, baseRef, role, pubkey string, paths ...string) { + t.Helper() pathsArg := "--all-paths" if len(paths) > 0 { pathsArg = "--paths=" + strings.Join(paths, ",") @@ -373,6 +377,7 @@ func notaryAddDelegation(t *testing.T, notaryDir, homeDir *fs.Dir, baseRef, role } func notaryInit(t *testing.T, notaryDir, homeDir *fs.Dir, baseRef string) { + t.Helper() icmd.RunCmd( icmd.Command(notary, "-c", notaryDir.Join("client-config.json"), "init", baseRef), withNotaryPassphrase("foo"), @@ -381,6 +386,7 @@ func notaryInit(t *testing.T, notaryDir, homeDir *fs.Dir, baseRef string) { } func notaryListTargetsInRole(t *testing.T, notaryDir, homeDir *fs.Dir, baseRef, role string) map[string]string { + t.Helper() result := icmd.RunCmd( icmd.Command(notary, "-c", notaryDir.Join("client-config.json"), "list", baseRef, "-r", role), fixtures.WithHome(homeDir.Path()), @@ -413,6 +419,7 @@ func notaryListTargetsInRole(t *testing.T, notaryDir, homeDir *fs.Dir, baseRef, } func setupNotaryConfig(t *testing.T, dockerConfigDir fs.Dir) *fs.Dir { + t.Helper() return fs.NewDir(t, "notary_test", fs.WithMode(0o700), fs.WithFile("client-config.json", fmt.Sprintf(` { @@ -425,5 +432,6 @@ func setupNotaryConfig(t *testing.T, dockerConfigDir fs.Dir) *fs.Dir { } func copyPrivateKey(t *testing.T, dir, source string) { + t.Helper() icmd.RunCommand("/bin/cp", source, dir).Assert(t, icmd.Success) } diff --git a/e2e/plugin/trust_test.go b/e2e/plugin/trust_test.go index b89bdfb99a..38bdcc5e45 100644 --- a/e2e/plugin/trust_test.go +++ b/e2e/plugin/trust_test.go @@ -72,6 +72,7 @@ func TestInstallWithContentTrustUntrusted(t *testing.T) { } func preparePluginDir(t *testing.T) *fs.Dir { + t.Helper() p := &types.PluginConfig{ Interface: types.PluginConfigInterface{ Socket: "basic.sock", diff --git a/e2e/stack/remove_test.go b/e2e/stack/remove_test.go index 329c6ad254..e3636ee87c 100644 --- a/e2e/stack/remove_test.go +++ b/e2e/stack/remove_test.go @@ -22,6 +22,7 @@ func TestRemove(t *testing.T) { } func deployFullStack(t *testing.T, stackname string) { + t.Helper() // TODO: this stack should have full options not minimal options result := icmd.RunCommand("docker", "stack", "deploy", "--compose-file=./testdata/full-stack.yml", stackname) @@ -31,6 +32,7 @@ func deployFullStack(t *testing.T, stackname string) { } func cleanupFullStack(t *testing.T, stackname string) { + t.Helper() // FIXME(vdemeester) we shouldn't have to do that. it is hiding a race on docker stack rm poll.WaitOn(t, stackRm(stackname), pollSettings) poll.WaitOn(t, taskCount(stackname, 0), pollSettings) diff --git a/e2e/trust/revoke_test.go b/e2e/trust/revoke_test.go index fe0f44de04..b903ece562 100644 --- a/e2e/trust/revoke_test.go +++ b/e2e/trust/revoke_test.go @@ -47,6 +47,7 @@ func TestRevokeRepo(t *testing.T) { } func setupTrustedImagesForRevoke(t *testing.T, dir fs.Dir) { + t.Helper() icmd.RunCmd(icmd.Command("docker", "pull", fixtures.AlpineImage)).Assert(t, icmd.Success) icmd.RunCommand("docker", "tag", fixtures.AlpineImage, revokeImage).Assert(t, icmd.Success) icmd.RunCmd( @@ -56,6 +57,7 @@ func setupTrustedImagesForRevoke(t *testing.T, dir fs.Dir) { } func setupTrustedImagesForRevokeRepo(t *testing.T, dir fs.Dir) { + t.Helper() icmd.RunCmd(icmd.Command("docker", "pull", fixtures.AlpineImage)).Assert(t, icmd.Success) icmd.RunCommand("docker", "tag", fixtures.AlpineImage, fmt.Sprintf("%s:v1", revokeRepo)).Assert(t, icmd.Success) icmd.RunCmd( diff --git a/e2e/trust/sign_test.go b/e2e/trust/sign_test.go index 087620f895..81a09f78df 100644 --- a/e2e/trust/sign_test.go +++ b/e2e/trust/sign_test.go @@ -54,6 +54,7 @@ func TestSignWithLocalFlag(t *testing.T) { } func setupTrustedImageForOverwrite(t *testing.T, dir fs.Dir) { + t.Helper() icmd.RunCmd(icmd.Command("docker", "pull", fixtures.AlpineImage)).Assert(t, icmd.Success) icmd.RunCommand("docker", "tag", fixtures.AlpineImage, localImage).Assert(t, icmd.Success) result := icmd.RunCmd( diff --git a/internal/test/strings.go b/internal/test/strings.go index ccbfbbccdd..2c9ca22d8c 100644 --- a/internal/test/strings.go +++ b/internal/test/strings.go @@ -10,6 +10,7 @@ import ( // CompareMultipleValues compares comma-separated values, whatever the order is func CompareMultipleValues(t *testing.T, value, expected string) { + t.Helper() // comma-separated values means probably a map input, which won't // be guaranteed to have the same order as our expected value // We'll create maps and use reflect.DeepEquals to check instead: diff --git a/opts/port_test.go b/opts/port_test.go index 99192d9312..a64e6e57ec 100644 --- a/opts/port_test.go +++ b/opts/port_test.go @@ -361,6 +361,7 @@ func TestConvertPortToPortConfigWithIP(t *testing.T) { } func assertContains(t *testing.T, portConfigs []swarm.PortConfig, expected swarm.PortConfig) { + t.Helper() contains := false for _, portConfig := range portConfigs { if portConfig == expected { From 606cbd60a198bf682479783c37c1a3dbd1e96167 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Mon, 20 Nov 2023 11:15:36 +0100 Subject: [PATCH 10/19] golangci-lint: enable predeclared linter cli/command/utils.go:190:35: param new has same name as predeclared identifier (predeclared) func StringSliceReplaceAt(s, old, new []string, requireIndex int) ([]string, bool) { ^ Signed-off-by: Sebastiaan van Stijn --- .golangci.yml | 1 + cli/command/utils.go | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index bef425b96d..8afc71aedf 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -14,6 +14,7 @@ linters: - megacheck - misspell - nakedret + - predeclared - revive - staticcheck - thelper diff --git a/cli/command/utils.go b/cli/command/utils.go index 91b9fc1891..d55d5dc28a 100644 --- a/cli/command/utils.go +++ b/cli/command/utils.go @@ -184,17 +184,17 @@ func stringSliceIndex(s, subs []string) int { return -1 } -// StringSliceReplaceAt replaces the sub-slice old, with the sub-slice new, in the string +// StringSliceReplaceAt replaces the sub-slice find, with the sub-slice replace, in the string // slice s, returning a new slice and a boolean indicating if the replacement happened. // requireIdx is the index at which old needs to be found at (or -1 to disregard that). -func StringSliceReplaceAt(s, old, new []string, requireIndex int) ([]string, bool) { - idx := stringSliceIndex(s, old) +func StringSliceReplaceAt(s, find, replace []string, requireIndex int) ([]string, bool) { + idx := stringSliceIndex(s, find) if (requireIndex != -1 && requireIndex != idx) || idx == -1 { return s, false } out := append([]string{}, s[:idx]...) - out = append(out, new...) - out = append(out, s[idx+len(old):]...) + out = append(out, replace...) + out = append(out, s[idx+len(find):]...) return out, true } From 2d61f70f00e25ee3387893e73fca50416d589bf7 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Mon, 20 Nov 2023 13:04:09 +0100 Subject: [PATCH 11/19] golangci-lint: govet: enable shadow check Signed-off-by: Sebastiaan van Stijn --- .golangci.yml | 11 +++- cli/command/container/opts_test.go | 2 +- cli/command/manifest/push.go | 4 +- cli/command/manifest/push_test.go | 6 +-- cli/command/service/progress/progress_test.go | 54 +++++++++---------- cli/command/system/info.go | 16 +++--- cli/command/system/info_test.go | 28 +++++----- cli/command/trust/key_load_test.go | 20 +++---- cli/compose/template/template.go | 14 +++-- 9 files changed, 81 insertions(+), 74 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 8afc71aedf..7eef20b8cb 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -42,7 +42,10 @@ linters-settings: gocyclo: min-complexity: 16 govet: - check-shadowing: false + check-shadowing: true + settings: + shadow: + strict: true lll: line-length: 200 nakedret: @@ -128,6 +131,12 @@ issues: - errcheck - gosec + # Allow "err" and "ok" vars to shadow existing declarations, otherwise we get too many false positives. + - text: '^shadow: declaration of "(err|ok)" shadows declaration' + linters: + - govet + + # Maximum issues count per one linter. Set to 0 to disable. Default is 50. max-issues-per-linter: 0 diff --git a/cli/command/container/opts_test.go b/cli/command/container/opts_test.go index 89fa2d5838..28c109e6fb 100644 --- a/cli/command/container/opts_test.go +++ b/cli/command/container/opts_test.go @@ -198,7 +198,7 @@ func TestParseWithVolumes(t *testing.T) { t.Fatalf("Error parsing volume flags, %q should not mount-bind anything. Received %v", tryit, hostConfig.Binds) } else if _, exists := config.Volumes[arr[0]]; !exists { t.Fatalf("Error parsing volume flags, %s is missing from volumes. Received %v", arr[0], config.Volumes) - } else if _, exists := config.Volumes[arr[1]]; !exists { + } else if _, exists := config.Volumes[arr[1]]; !exists { //nolint:govet // ignore shadow-check t.Fatalf("Error parsing volume flags, %s is missing from volumes. Received %v", arr[1], config.Volumes) } diff --git a/cli/command/manifest/push.go b/cli/command/manifest/push.go index 34c57e749a..303f124b4e 100644 --- a/cli/command/manifest/push.go +++ b/cli/command/manifest/push.go @@ -77,13 +77,13 @@ func runPush(dockerCli command.Cli, opts pushOpts) error { return errors.Errorf("%s not found", targetRef) } - pushRequest, err := buildPushRequest(manifests, targetRef, opts.insecure) + req, err := buildPushRequest(manifests, targetRef, opts.insecure) if err != nil { return err } ctx := context.Background() - if err := pushList(ctx, dockerCli, pushRequest); err != nil { + if err := pushList(ctx, dockerCli, req); err != nil { return err } if opts.purge { diff --git a/cli/command/manifest/push_test.go b/cli/command/manifest/push_test.go index fab826435f..2276cf7e43 100644 --- a/cli/command/manifest/push_test.go +++ b/cli/command/manifest/push_test.go @@ -49,17 +49,17 @@ func TestManifestPushErrors(t *testing.T) { } func TestManifestPush(t *testing.T) { - store := store.NewStore(t.TempDir()) + manifestStore := store.NewStore(t.TempDir()) registry := newFakeRegistryClient() cli := test.NewFakeCli(nil) - cli.SetManifestStore(store) + cli.SetManifestStore(manifestStore) cli.SetRegistryClient(registry) namedRef := ref(t, "alpine:3.0") imageManifest := fullImageManifest(t, namedRef) - err := store.Save(ref(t, "list:v1"), namedRef, imageManifest) + err := manifestStore.Save(ref(t, "list:v1"), namedRef, imageManifest) assert.NilError(t, err) cmd := newPushListCommand(cli) diff --git a/cli/command/service/progress/progress_test.go b/cli/command/service/progress/progress_test.go index 64cbde99cb..19ba07a9e8 100644 --- a/cli/command/service/progress/progress_test.go +++ b/cli/command/service/progress/progress_test.go @@ -70,7 +70,7 @@ func TestReplicatedProgressUpdaterOneReplica(t *testing.T) { } p := &mockProgress{} - updaterTester := updaterTester{ + ut := updaterTester{ t: t, updater: &replicatedProgressUpdater{ progressOut: p, @@ -82,7 +82,7 @@ func TestReplicatedProgressUpdaterOneReplica(t *testing.T) { tasks := []swarm.Task{} - updaterTester.testUpdater(tasks, false, + ut.testUpdater(tasks, false, []progress.Progress{ {ID: "overall progress", Action: "0 out of 1 tasks"}, {ID: "1/1", Action: " "}, @@ -97,14 +97,14 @@ func TestReplicatedProgressUpdaterOneReplica(t *testing.T) { DesiredState: swarm.TaskStateShutdown, Status: swarm.TaskStatus{State: swarm.TaskStateNew}, }) - updaterTester.testUpdater(tasks, false, + ut.testUpdater(tasks, false, []progress.Progress{ {ID: "overall progress", Action: "0 out of 1 tasks"}, }) // Task with valid DesiredState and State updates progress bar tasks[0].DesiredState = swarm.TaskStateRunning - updaterTester.testUpdater(tasks, false, + ut.testUpdater(tasks, false, []progress.Progress{ {ID: "1/1", Action: "new ", Current: 1, Total: 9, HideCounts: true}, {ID: "overall progress", Action: "0 out of 1 tasks"}, @@ -113,7 +113,7 @@ func TestReplicatedProgressUpdaterOneReplica(t *testing.T) { // If the task exposes an error, we should show that instead of the // progress bar. tasks[0].Status.Err = "something is wrong" - updaterTester.testUpdater(tasks, false, + ut.testUpdater(tasks, false, []progress.Progress{ {ID: "1/1", Action: "something is wrong"}, {ID: "overall progress", Action: "0 out of 1 tasks"}, @@ -122,7 +122,7 @@ func TestReplicatedProgressUpdaterOneReplica(t *testing.T) { // When the task reaches running, update should return true tasks[0].Status.Err = "" tasks[0].Status.State = swarm.TaskStateRunning - updaterTester.testUpdater(tasks, true, + ut.testUpdater(tasks, true, []progress.Progress{ {ID: "1/1", Action: "running ", Current: 9, Total: 9, HideCounts: true}, {ID: "overall progress", Action: "1 out of 1 tasks"}, @@ -131,7 +131,7 @@ func TestReplicatedProgressUpdaterOneReplica(t *testing.T) { // If the task fails, update should return false again tasks[0].Status.Err = "task failed" tasks[0].Status.State = swarm.TaskStateFailed - updaterTester.testUpdater(tasks, false, + ut.testUpdater(tasks, false, []progress.Progress{ {ID: "1/1", Action: "task failed"}, {ID: "overall progress", Action: "0 out of 1 tasks"}, @@ -147,7 +147,7 @@ func TestReplicatedProgressUpdaterOneReplica(t *testing.T) { DesiredState: swarm.TaskStateRunning, Status: swarm.TaskStatus{State: swarm.TaskStateRunning}, }) - updaterTester.testUpdater(tasks, true, + ut.testUpdater(tasks, true, []progress.Progress{ {ID: "1/1", Action: "running ", Current: 9, Total: 9, HideCounts: true}, {ID: "overall progress", Action: "1 out of 1 tasks"}, @@ -162,7 +162,7 @@ func TestReplicatedProgressUpdaterOneReplica(t *testing.T) { DesiredState: swarm.TaskStateRunning, Status: swarm.TaskStatus{State: swarm.TaskStatePreparing}, }) - updaterTester.testUpdater(tasks, false, + ut.testUpdater(tasks, false, []progress.Progress{ {ID: "1/1", Action: "preparing", Current: 6, Total: 9, HideCounts: true}, {ID: "overall progress", Action: "0 out of 1 tasks"}, @@ -183,7 +183,7 @@ func TestReplicatedProgressUpdaterManyReplicas(t *testing.T) { } p := &mockProgress{} - updaterTester := updaterTester{ + ut := updaterTester{ t: t, updater: &replicatedProgressUpdater{ progressOut: p, @@ -196,7 +196,7 @@ func TestReplicatedProgressUpdaterManyReplicas(t *testing.T) { tasks := []swarm.Task{} // No per-task progress bars because there are too many replicas - updaterTester.testUpdater(tasks, false, + ut.testUpdater(tasks, false, []progress.Progress{ {ID: "overall progress", Action: fmt.Sprintf("0 out of %d tasks", replicas)}, {ID: "overall progress", Action: fmt.Sprintf("0 out of %d tasks", replicas)}, @@ -215,13 +215,13 @@ func TestReplicatedProgressUpdaterManyReplicas(t *testing.T) { if i%2 == 1 { tasks[i].NodeID = "b" } - updaterTester.testUpdater(tasks, false, + ut.testUpdater(tasks, false, []progress.Progress{ {ID: "overall progress", Action: fmt.Sprintf("%d out of %d tasks", i, replicas)}, }) tasks[i].Status.State = swarm.TaskStateRunning - updaterTester.testUpdater(tasks, uint64(i) == replicas-1, + ut.testUpdater(tasks, uint64(i) == replicas-1, []progress.Progress{ {ID: "overall progress", Action: fmt.Sprintf("%d out of %d tasks", i+1, replicas)}, }) @@ -238,7 +238,7 @@ func TestGlobalProgressUpdaterOneNode(t *testing.T) { } p := &mockProgress{} - updaterTester := updaterTester{ + ut := updaterTester{ t: t, updater: &globalProgressUpdater{ progressOut: p, @@ -250,7 +250,7 @@ func TestGlobalProgressUpdaterOneNode(t *testing.T) { tasks := []swarm.Task{} - updaterTester.testUpdater(tasks, false, + ut.testUpdater(tasks, false, []progress.Progress{ {ID: "overall progress", Action: "waiting for new tasks"}, }) @@ -263,7 +263,7 @@ func TestGlobalProgressUpdaterOneNode(t *testing.T) { DesiredState: swarm.TaskStateShutdown, Status: swarm.TaskStatus{State: swarm.TaskStateNew}, }) - updaterTester.testUpdater(tasks, false, + ut.testUpdater(tasks, false, []progress.Progress{ {ID: "overall progress", Action: "0 out of 1 tasks"}, {ID: "overall progress", Action: "0 out of 1 tasks"}, @@ -271,7 +271,7 @@ func TestGlobalProgressUpdaterOneNode(t *testing.T) { // Task with valid DesiredState and State updates progress bar tasks[0].DesiredState = swarm.TaskStateRunning - updaterTester.testUpdater(tasks, false, + ut.testUpdater(tasks, false, []progress.Progress{ {ID: "a", Action: "new ", Current: 1, Total: 9, HideCounts: true}, {ID: "overall progress", Action: "0 out of 1 tasks"}, @@ -280,7 +280,7 @@ func TestGlobalProgressUpdaterOneNode(t *testing.T) { // If the task exposes an error, we should show that instead of the // progress bar. tasks[0].Status.Err = "something is wrong" - updaterTester.testUpdater(tasks, false, + ut.testUpdater(tasks, false, []progress.Progress{ {ID: "a", Action: "something is wrong"}, {ID: "overall progress", Action: "0 out of 1 tasks"}, @@ -289,7 +289,7 @@ func TestGlobalProgressUpdaterOneNode(t *testing.T) { // When the task reaches running, update should return true tasks[0].Status.Err = "" tasks[0].Status.State = swarm.TaskStateRunning - updaterTester.testUpdater(tasks, true, + ut.testUpdater(tasks, true, []progress.Progress{ {ID: "a", Action: "running ", Current: 9, Total: 9, HideCounts: true}, {ID: "overall progress", Action: "1 out of 1 tasks"}, @@ -298,7 +298,7 @@ func TestGlobalProgressUpdaterOneNode(t *testing.T) { // If the task fails, update should return false again tasks[0].Status.Err = "task failed" tasks[0].Status.State = swarm.TaskStateFailed - updaterTester.testUpdater(tasks, false, + ut.testUpdater(tasks, false, []progress.Progress{ {ID: "a", Action: "task failed"}, {ID: "overall progress", Action: "0 out of 1 tasks"}, @@ -314,7 +314,7 @@ func TestGlobalProgressUpdaterOneNode(t *testing.T) { DesiredState: swarm.TaskStateRunning, Status: swarm.TaskStatus{State: swarm.TaskStateRunning}, }) - updaterTester.testUpdater(tasks, true, + ut.testUpdater(tasks, true, []progress.Progress{ {ID: "a", Action: "running ", Current: 9, Total: 9, HideCounts: true}, {ID: "overall progress", Action: "1 out of 1 tasks"}, @@ -329,7 +329,7 @@ func TestGlobalProgressUpdaterOneNode(t *testing.T) { DesiredState: swarm.TaskStateRunning, Status: swarm.TaskStatus{State: swarm.TaskStatePreparing}, }) - updaterTester.testUpdater(tasks, false, + ut.testUpdater(tasks, false, []progress.Progress{ {ID: "a", Action: "preparing", Current: 6, Total: 9, HideCounts: true}, {ID: "overall progress", Action: "0 out of 1 tasks"}, @@ -348,7 +348,7 @@ func TestGlobalProgressUpdaterManyNodes(t *testing.T) { } p := &mockProgress{} - updaterTester := updaterTester{ + ut := updaterTester{ t: t, updater: &globalProgressUpdater{ progressOut: p, @@ -359,12 +359,12 @@ func TestGlobalProgressUpdaterManyNodes(t *testing.T) { } for i := 0; i != nodes; i++ { - updaterTester.activeNodes[strconv.Itoa(i)] = struct{}{} + ut.activeNodes[strconv.Itoa(i)] = struct{}{} } tasks := []swarm.Task{} - updaterTester.testUpdater(tasks, false, + ut.testUpdater(tasks, false, []progress.Progress{ {ID: "overall progress", Action: "waiting for new tasks"}, }) @@ -379,7 +379,7 @@ func TestGlobalProgressUpdaterManyNodes(t *testing.T) { }) } - updaterTester.testUpdater(tasks, false, + ut.testUpdater(tasks, false, []progress.Progress{ {ID: "overall progress", Action: fmt.Sprintf("0 out of %d tasks", nodes)}, {ID: "overall progress", Action: fmt.Sprintf("0 out of %d tasks", nodes)}, @@ -387,7 +387,7 @@ func TestGlobalProgressUpdaterManyNodes(t *testing.T) { for i := 0; i != nodes; i++ { tasks[i].Status.State = swarm.TaskStateRunning - updaterTester.testUpdater(tasks, i == nodes-1, + ut.testUpdater(tasks, i == nodes-1, []progress.Progress{ {ID: "overall progress", Action: fmt.Sprintf("%d out of %d tasks", i+1, nodes)}, }) diff --git a/cli/command/system/info.go b/cli/command/system/info.go index 6259eab333..d560c058ee 100644 --- a/cli/command/system/info.go +++ b/cli/command/system/info.go @@ -35,7 +35,7 @@ type clientInfo struct { Warnings []string } -type info struct { +type dockerInfo struct { // This field should/could be ServerInfo but is anonymous to // preserve backwards compatibility in the JSON rendering // which has ServerInfo immediately within the top-level @@ -48,7 +48,7 @@ type info struct { ClientErrors []string `json:",omitempty"` } -func (i *info) clientPlatform() string { +func (i *dockerInfo) clientPlatform() string { if i.ClientInfo != nil && i.ClientInfo.Platform != nil { return i.ClientInfo.Platform.Name } @@ -78,7 +78,7 @@ func NewInfoCommand(dockerCli command.Cli) *cobra.Command { } func runInfo(cmd *cobra.Command, dockerCli command.Cli, opts *infoOptions) error { - info := info{ + info := dockerInfo{ ClientInfo: &clientInfo{ // Don't pass a dockerCLI to newClientVersion(), because we currently // don't include negotiated API version, and want to avoid making an @@ -129,7 +129,7 @@ var placeHolders = regexp.MustCompile(`\.[a-zA-Z]`) // If only client-side information is used in the template, we can skip // connecting to the daemon. This allows (e.g.) to only get cli-plugin // information, without also making a (potentially expensive) API call. -func needsServerInfo(template string, info info) bool { +func needsServerInfo(template string, info dockerInfo) bool { if len(template) == 0 || placeHolders.FindString(template) == "" { // The template is empty, or does not contain formatting fields // (e.g. `table` or `raw` or `{{ json .}}`). Assume we need server-side @@ -160,7 +160,7 @@ func needsServerInfo(template string, info info) bool { return err != nil } -func prettyPrintInfo(streams command.Streams, info info) error { +func prettyPrintInfo(streams command.Streams, info dockerInfo) error { // Only append the platform info if it's not empty, to prevent printing a trailing space. if p := info.clientPlatform(); p != "" { fprintln(streams.Out(), "Client:", p) @@ -215,7 +215,7 @@ func prettyPrintClientInfo(streams command.Streams, info clientInfo) { } //nolint:gocyclo -func prettyPrintServerInfo(streams command.Streams, info *info) []error { +func prettyPrintServerInfo(streams command.Streams, info *dockerInfo) []error { var errs []error output := streams.Out() @@ -452,7 +452,7 @@ func printSwarmInfo(output io.Writer, info system.Info) { } } -func printServerWarnings(stdErr io.Writer, info *info) { +func printServerWarnings(stdErr io.Writer, info *dockerInfo) { if versions.LessThan(info.ClientInfo.APIVersion, "1.42") { printSecurityOptionsWarnings(stdErr, *info.Info) } @@ -530,7 +530,7 @@ func printServerWarningsLegacy(stdErr io.Writer, info system.Info) { } } -func formatInfo(output io.Writer, info info, format string) error { +func formatInfo(output io.Writer, info dockerInfo, format string) error { if format == formatter.JSONFormatKey { format = formatter.JSONFormat } diff --git a/cli/command/system/info_test.go b/cli/command/system/info_test.go index af26d3199b..6744f3b5cf 100644 --- a/cli/command/system/info_test.go +++ b/cli/command/system/info_test.go @@ -267,7 +267,7 @@ func TestPrettyPrintInfo(t *testing.T) { for _, tc := range []struct { doc string - dockerInfo info + dockerInfo dockerInfo prettyGolden string warningsGolden string @@ -276,7 +276,7 @@ func TestPrettyPrintInfo(t *testing.T) { }{ { doc: "info without swarm", - dockerInfo: info{ + dockerInfo: dockerInfo{ Info: &sampleInfoNoSwarm, ClientInfo: &clientInfo{ clientVersion: clientVersion{ @@ -292,7 +292,7 @@ func TestPrettyPrintInfo(t *testing.T) { }, { doc: "info with plugins", - dockerInfo: info{ + dockerInfo: dockerInfo{ Info: &sampleInfoNoSwarm, ClientInfo: &clientInfo{ clientVersion: clientVersion{Context: "default"}, @@ -305,7 +305,7 @@ func TestPrettyPrintInfo(t *testing.T) { }, { doc: "info with nil labels", - dockerInfo: info{ + dockerInfo: dockerInfo{ Info: &sampleInfoLabelsNil, ClientInfo: &clientInfo{clientVersion: clientVersion{Context: "default"}}, }, @@ -313,7 +313,7 @@ func TestPrettyPrintInfo(t *testing.T) { }, { doc: "info with empty labels", - dockerInfo: info{ + dockerInfo: dockerInfo{ Info: &sampleInfoLabelsEmpty, ClientInfo: &clientInfo{clientVersion: clientVersion{Context: "default"}}, }, @@ -321,7 +321,7 @@ func TestPrettyPrintInfo(t *testing.T) { }, { doc: "info with swarm", - dockerInfo: info{ + dockerInfo: dockerInfo{ Info: &infoWithSwarm, ClientInfo: &clientInfo{ clientVersion: clientVersion{Context: "default"}, @@ -333,7 +333,7 @@ func TestPrettyPrintInfo(t *testing.T) { }, { doc: "info with legacy warnings", - dockerInfo: info{ + dockerInfo: dockerInfo{ Info: &infoWithWarningsLinux, ClientInfo: &clientInfo{ clientVersion: clientVersion{ @@ -350,7 +350,7 @@ func TestPrettyPrintInfo(t *testing.T) { }, { doc: "info with daemon warnings", - dockerInfo: info{ + dockerInfo: dockerInfo{ Info: &sampleInfoDaemonWarnings, ClientInfo: &clientInfo{ clientVersion: clientVersion{ @@ -367,7 +367,7 @@ func TestPrettyPrintInfo(t *testing.T) { }, { doc: "errors for both", - dockerInfo: info{ + dockerInfo: dockerInfo{ ServerErrors: []string{"a server error occurred"}, ClientErrors: []string{"a client error occurred"}, }, @@ -378,7 +378,7 @@ func TestPrettyPrintInfo(t *testing.T) { }, { doc: "bad security info", - dockerInfo: info{ + dockerInfo: dockerInfo{ Info: &sampleInfoBadSecurity, ServerErrors: []string{"a server error occurred"}, ClientInfo: &clientInfo{Debug: false}, @@ -424,7 +424,7 @@ func BenchmarkPrettyPrintInfo(b *testing.B) { infoWithSwarm := sampleInfoNoSwarm infoWithSwarm.Swarm = sampleSwarmInfo - dockerInfo := info{ + info := dockerInfo{ Info: &infoWithSwarm, ClientInfo: &clientInfo{ clientVersion: clientVersion{ @@ -439,7 +439,7 @@ func BenchmarkPrettyPrintInfo(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { - _ = prettyPrintInfo(cli, dockerInfo) + _ = prettyPrintInfo(cli, info) cli.ResetOutputBuffers() } } @@ -470,7 +470,7 @@ func TestFormatInfo(t *testing.T) { tc := tc t.Run(tc.doc, func(t *testing.T) { cli := test.NewFakeCli(&fakeClient{}) - info := info{ + info := dockerInfo{ Info: &sampleInfoNoSwarm, ClientInfo: &clientInfo{Debug: true}, } @@ -531,7 +531,7 @@ func TestNeedsServerInfo(t *testing.T) { }, } - inf := info{ClientInfo: &clientInfo{}} + inf := dockerInfo{ClientInfo: &clientInfo{}} for _, tc := range tests { tc := tc t.Run(tc.doc, func(t *testing.T) { diff --git a/cli/command/trust/key_load_test.go b/cli/command/trust/key_load_test.go index 74f2f91dc3..fae5b858cf 100644 --- a/cli/command/trust/key_load_test.go +++ b/cli/command/trust/key_load_test.go @@ -114,10 +114,10 @@ var testKeys = map[string][]byte{ func TestLoadKeyFromPath(t *testing.T) { skip.If(t, runtime.GOOS == "windows") for keyID, keyBytes := range testKeys { - privKeyID, privKeyFixture := keyID, keyBytes + keyID, keyBytes := keyID, keyBytes t.Run(fmt.Sprintf("load-key-id-%s-from-path", keyID), func(t *testing.T) { privKeyFilepath := filepath.Join(t.TempDir(), "privkey.pem") - assert.NilError(t, os.WriteFile(privKeyFilepath, privKeyFixture, notary.PrivNoExecPerms)) + assert.NilError(t, os.WriteFile(privKeyFilepath, keyBytes, notary.PrivNoExecPerms)) keyStorageDir := t.TempDir() @@ -135,7 +135,7 @@ func TestLoadKeyFromPath(t *testing.T) { assert.Check(t, loadPrivKeyBytesToStore(privKeyBytes, privKeyImporters, privKeyFilepath, "signer-name", cannedPasswordRetriever)) // check that the appropriate ~//private/.key file exists - expectedImportKeyPath := filepath.Join(keyStorageDir, notary.PrivDir, privKeyID+"."+notary.KeyExtension) + expectedImportKeyPath := filepath.Join(keyStorageDir, notary.PrivDir, keyID+"."+notary.KeyExtension) _, err = os.Stat(expectedImportKeyPath) assert.NilError(t, err) @@ -152,7 +152,7 @@ func TestLoadKeyFromPath(t *testing.T) { decryptedKey, err := tufutils.ParsePKCS8ToTufKey(keyPEM.Bytes, []byte(passwd)) assert.NilError(t, err) - fixturePEM, _ := pem.Decode(privKeyFixture) + fixturePEM, _ := pem.Decode(keyBytes) assert.Check(t, is.DeepEqual(fixturePEM.Bytes, decryptedKey.Private())) }) } @@ -161,11 +161,11 @@ func TestLoadKeyFromPath(t *testing.T) { func TestLoadKeyTooPermissive(t *testing.T) { skip.If(t, runtime.GOOS == "windows") for keyID, keyBytes := range testKeys { - keyID, privKeyFixture := keyID, keyBytes + keyID, keyBytes := keyID, keyBytes t.Run(fmt.Sprintf("load-key-id-%s-too-permissive", keyID), func(t *testing.T) { privKeyDir := t.TempDir() privKeyFilepath := filepath.Join(privKeyDir, "privkey477.pem") - assert.NilError(t, os.WriteFile(privKeyFilepath, privKeyFixture, 0o477)) + assert.NilError(t, os.WriteFile(privKeyFilepath, keyBytes, 0o477)) // import the key to our keyStorageDir _, err := getPrivKeyBytesFromPath(privKeyFilepath) @@ -173,27 +173,27 @@ func TestLoadKeyTooPermissive(t *testing.T) { assert.Error(t, err, expected) privKeyFilepath = filepath.Join(privKeyDir, "privkey667.pem") - assert.NilError(t, os.WriteFile(privKeyFilepath, privKeyFixture, 0o677)) + assert.NilError(t, os.WriteFile(privKeyFilepath, keyBytes, 0o677)) _, err = getPrivKeyBytesFromPath(privKeyFilepath) expected = fmt.Sprintf("private key file %s must not be readable or writable by others", privKeyFilepath) assert.Error(t, err, expected) privKeyFilepath = filepath.Join(privKeyDir, "privkey777.pem") - assert.NilError(t, os.WriteFile(privKeyFilepath, privKeyFixture, 0o777)) + assert.NilError(t, os.WriteFile(privKeyFilepath, keyBytes, 0o777)) _, err = getPrivKeyBytesFromPath(privKeyFilepath) expected = fmt.Sprintf("private key file %s must not be readable or writable by others", privKeyFilepath) assert.Error(t, err, expected) privKeyFilepath = filepath.Join(privKeyDir, "privkey400.pem") - assert.NilError(t, os.WriteFile(privKeyFilepath, privKeyFixture, 0o400)) + assert.NilError(t, os.WriteFile(privKeyFilepath, keyBytes, 0o400)) _, err = getPrivKeyBytesFromPath(privKeyFilepath) assert.NilError(t, err) privKeyFilepath = filepath.Join(privKeyDir, "privkey600.pem") - assert.NilError(t, os.WriteFile(privKeyFilepath, privKeyFixture, 0o600)) + assert.NilError(t, os.WriteFile(privKeyFilepath, keyBytes, 0o600)) _, err = getPrivKeyBytesFromPath(privKeyFilepath) assert.NilError(t, err) diff --git a/cli/compose/template/template.go b/cli/compose/template/template.go index f8e507a90b..23f059c9d4 100644 --- a/cli/compose/template/template.go +++ b/cli/compose/template/template.go @@ -6,17 +6,15 @@ import ( "strings" ) -var ( - delimiter = "\\$" - substitution = "[_a-z][_a-z0-9]*(?::?[-?][^}]*)?" +const ( + delimiter = "\\$" + subst = "[_a-z][_a-z0-9]*(?::?[-?][^}]*)?" ) -var patternString = fmt.Sprintf( +var defaultPattern = regexp.MustCompile(fmt.Sprintf( "%s(?i:(?P%s)|(?P%s)|{(?P%s)}|(?P))", - delimiter, delimiter, substitution, substitution, -) - -var defaultPattern = regexp.MustCompile(patternString) + delimiter, delimiter, subst, subst, +)) // DefaultSubstituteFuncs contains the default SubstituteFunc used by the docker cli var DefaultSubstituteFuncs = []SubstituteFunc{ From 7e9d2c78c65e80697480982047a567aa4c50a907 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Mon, 20 Nov 2023 14:41:32 +0100 Subject: [PATCH 12/19] golangci-lint: enable dupword linter Signed-off-by: Sebastiaan van Stijn --- .golangci.yml | 1 + cli/command/container/formatter_stats.go | 2 +- cli/command/defaultcontextstore.go | 2 ++ cli/command/formatter/image_test.go | 8 ++++---- cli/command/formatter/tabwriter/tabwriter.go | 2 +- cli/command/image/formatter_history_test.go | 2 ++ cli/command/service/parse.go | 2 +- cli/command/service/update.go | 2 +- cli/command/service/update_test.go | 2 +- cli/trust/trust.go | 4 ++-- 10 files changed, 16 insertions(+), 11 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 7eef20b8cb..4b97b1d118 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -3,6 +3,7 @@ linters: - bodyclose - depguard - dogsled + - dupword # Detects duplicate words. - gocyclo - gofumpt - goimports diff --git a/cli/command/container/formatter_stats.go b/cli/command/container/formatter_stats.go index 5b46fe2650..dafcb4303b 100644 --- a/cli/command/container/formatter_stats.go +++ b/cli/command/container/formatter_stats.go @@ -24,7 +24,7 @@ const ( pidsHeader = "PIDS" // Used only on Linux ) -// StatsEntry represents represents the statistics data collected from a container +// StatsEntry represents the statistics data collected from a container type StatsEntry struct { Container string Name string diff --git a/cli/command/defaultcontextstore.go b/cli/command/defaultcontextstore.go index 203900e2fc..3e136a174c 100644 --- a/cli/command/defaultcontextstore.go +++ b/cli/command/defaultcontextstore.go @@ -44,6 +44,8 @@ type EndpointDefaultResolver interface { // the lack of a default (e.g. because the config file which // would contain it is missing). If there is no default then // returns nil, nil, nil. + // + //nolint:dupword // ignore "Duplicate words (nil,) found" ResolveDefault() (interface{}, *store.EndpointTLSData, error) } diff --git a/cli/command/formatter/image_test.go b/cli/command/formatter/image_test.go index 36a17f147f..d2388fd6c9 100644 --- a/cli/command/formatter/image_test.go +++ b/cli/command/formatter/image_test.go @@ -148,7 +148,7 @@ image tag2 imageID2 N/A 0B Format: NewImageFormat("table {{.Repository}}", false, false), }, }, - "REPOSITORY\nimage\nimage\n\n", + "REPOSITORY\nimage\nimage\n\n", //nolint:dupword // ignore "Duplicate words (image) found" }, { ImageContext{ @@ -169,7 +169,7 @@ image Format: NewImageFormat("table {{.Repository}}", true, false), }, }, - "REPOSITORY\nimage\nimage\n\n", + "REPOSITORY\nimage\nimage\n\n", //nolint:dupword // ignore "Duplicate words (image) found" }, { ImageContext{ @@ -284,7 +284,7 @@ image_id: imageID3 Format: NewImageFormat("{{.Repository}}", false, false), }, }, - "image\nimage\n\n", + "image\nimage\n\n", //nolint:dupword // ignore "Duplicate words (image) found" }, { ImageContext{ @@ -293,7 +293,7 @@ image_id: imageID3 }, Digest: true, }, - "image\nimage\n\n", + "image\nimage\n\n", //nolint:dupword // ignore "Duplicate words (image) found" }, } diff --git a/cli/command/formatter/tabwriter/tabwriter.go b/cli/command/formatter/tabwriter/tabwriter.go index 079be60c83..fac1b96c58 100644 --- a/cli/command/formatter/tabwriter/tabwriter.go +++ b/cli/command/formatter/tabwriter/tabwriter.go @@ -202,7 +202,7 @@ const ( // // minwidth minimal cell width including any padding // tabwidth width of tab characters (equivalent number of spaces) -// padding padding added to a cell before computing its width +// padding the padding added to a cell before computing its width // padchar ASCII char used for padding // if padchar == '\t', the Writer will assume that the // width of a '\t' in the formatted output is tabwidth, diff --git a/cli/command/image/formatter_history_test.go b/cli/command/image/formatter_history_test.go index 0a8e367a86..b85aac43aa 100644 --- a/cli/command/image/formatter_history_test.go +++ b/cli/command/image/formatter_history_test.go @@ -213,6 +213,7 @@ func TestHistoryContext_Table(t *testing.T) { {ID: "imageID6", Created: oldDate, CreatedBy: "/bin/bash echo", Size: int64(182964289), Comment: "Hi", Tags: []string{"image:tag2"}}, } + //nolint:dupword // ignore "Duplicate words (CREATED) found" const expectedNoTrunc = `IMAGE CREATED CREATED BY SIZE COMMENT imageID1 24 hours ago /bin/bash ls && npm i && npm run test && karma -c karma.conf.js start && npm start && more commands here && the list goes on 183MB Hi imageID2 24 hours ago /bin/bash echo 183MB Hi @@ -221,6 +222,7 @@ imageID4 24 hours ago /bin/bash grep imageID5 N/A /bin/bash echo 183MB Hi imageID6 17 years ago /bin/bash echo 183MB Hi ` + //nolint:dupword // ignore "Duplicate words (CREATED) found" const expectedTrunc = `IMAGE CREATED CREATED BY SIZE COMMENT imageID1 24 hours ago /bin/bash ls && npm i && npm run test && kar… 183MB Hi imageID2 24 hours ago /bin/bash echo 183MB Hi diff --git a/cli/command/service/parse.go b/cli/command/service/parse.go index 25677d3841..56265e9545 100644 --- a/cli/command/service/parse.go +++ b/cli/command/service/parse.go @@ -71,7 +71,7 @@ func ParseConfigs(client client.ConfigAPIClient, requestedConfigs []*swarmtypes. } // the configRefs map has two purposes: it prevents duplication of config - // target filenames, and it it used to get all configs so we can resolve + // target filenames. It is used to get all configs, so we can resolve // their IDs. unfortunately, there are other targets for ConfigReferences, // besides just a File; specifically, the Runtime target, which is used for // CredentialSpecs. Therefore, we need to have a list of ConfigReferences diff --git a/cli/command/service/update.go b/cli/command/service/update.go index c4672493aa..5ed39d909b 100644 --- a/cli/command/service/update.go +++ b/cli/command/service/update.go @@ -1365,7 +1365,7 @@ func updateCredSpecConfig(flags *pflag.FlagSet, containerSpec *swarm.ContainerSp // otherwise, set the credential spec to be the parsed value credSpec := credSpecOpt.Value.(*credentialSpecOpt).Value() - // if this is a Config credential spec, we we still need to replace the + // if this is a Config credential spec, we still need to replace the // value of credSpec.Config with the config ID instead of Name. if credSpec.Config != "" { for _, config := range containerSpec.Configs { diff --git a/cli/command/service/update_test.go b/cli/command/service/update_test.go index fc30e7be56..db884b84fb 100644 --- a/cli/command/service/update_test.go +++ b/cli/command/service/update_test.go @@ -1056,7 +1056,7 @@ func TestUpdateGetUpdatedConfigs(t *testing.T) { }, } // cannedConfigRefs is the same thing, but with config references instead - // instead of ID, however, it just maps an arbitrary string value. this is + // of ID, however, it just maps an arbitrary string value. this is // so we could have multiple config refs using the same config cannedConfigRefs := map[string]*swarm.ConfigReference{ "fooRef": { diff --git a/cli/trust/trust.go b/cli/trust/trust.go index f248164438..575d48f6de 100644 --- a/cli/trust/trust.go +++ b/cli/trust/trust.go @@ -262,8 +262,8 @@ func GetSignableRoles(repo client.Repository, target *client.Target) ([]data.Rol return signableRoles, nil } - // there are delegation roles, find every delegation role we have a key for, and - // attempt to sign into into all those roles. + // there are delegation roles, find every delegation role we have a key for, + // and attempt to sign in to all those roles. for _, delegationRole := range allDelegationRoles { // We do not support signing any delegation role that isn't a direct child of the targets role. // Also don't bother checking the keys if we can't add the target From 8bbdb93cf9d2011c535b91e3dbf9d18d00b9d739 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Mon, 20 Nov 2023 14:53:40 +0100 Subject: [PATCH 13/19] golangci-lint: enable nilerr linter cli/command/idresolver/idresolver.go:33:4: error is not nil (line 31) but it returns nil (nilerr) return id, nil ^ cli/command/idresolver/idresolver.go:45:4: error is not nil (line 43) but it returns nil (nilerr) return id, nil ^ Signed-off-by: Sebastiaan van Stijn --- .golangci.yml | 1 + cli/command/idresolver/idresolver.go | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 4b97b1d118..b7b597804a 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -15,6 +15,7 @@ linters: - megacheck - misspell - nakedret + - nilerr # Detects code that returns nil even if it checks that the error is not nil. - predeclared - revive - staticcheck diff --git a/cli/command/idresolver/idresolver.go b/cli/command/idresolver/idresolver.go index 4bc2e4acab..cae4bb7339 100644 --- a/cli/command/idresolver/idresolver.go +++ b/cli/command/idresolver/idresolver.go @@ -30,7 +30,8 @@ func (r *IDResolver) get(ctx context.Context, t interface{}, id string) (string, case swarm.Node: node, _, err := r.client.NodeInspectWithRaw(ctx, id) if err != nil { - return id, nil + // TODO(thaJeztah): should error-handling be more specific, or is it ok to ignore any error? + return id, nil //nolint:nilerr // ignore nil-error being returned, as this is a best-effort. } if node.Spec.Annotations.Name != "" { return node.Spec.Annotations.Name, nil @@ -42,7 +43,8 @@ func (r *IDResolver) get(ctx context.Context, t interface{}, id string) (string, case swarm.Service: service, _, err := r.client.ServiceInspectWithRaw(ctx, id, types.ServiceInspectOptions{}) if err != nil { - return id, nil + // TODO(thaJeztah): should error-handling be more specific, or is it ok to ignore any error? + return id, nil //nolint:nilerr // ignore nil-error being returned, as this is a best-effort. } return service.Spec.Annotations.Name, nil default: From 391668f57ab792c13555a10be6cfdae4a8e9b15c Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Mon, 20 Nov 2023 16:18:19 +0100 Subject: [PATCH 14/19] golangci-lint: enable perfsprint linter cli/compose/types/types.go:568:17: fmt.Sprintf can be replaced with faster strconv.FormatBool (perfsprint) return []byte(fmt.Sprintf("%v", e.External)), nil ^ cli/command/formatter/buildcache.go:174:9: fmt.Sprintf can be replaced with faster strconv.Itoa (perfsprint) return fmt.Sprintf("%d", c.v.UsageCount) ^ cli/command/formatter/buildcache.go:178:9: fmt.Sprintf can be replaced with faster strconv.FormatBool (perfsprint) return fmt.Sprintf("%t", c.v.InUse) ^ cli/command/formatter/buildcache.go:182:9: fmt.Sprintf can be replaced with faster strconv.FormatBool (perfsprint) return fmt.Sprintf("%t", c.v.Shared) ^ cli/command/formatter/image.go:259:9: fmt.Sprintf can be replaced with faster strconv.FormatInt (perfsprint) return fmt.Sprintf("%d", c.i.Containers) ^ cli/command/formatter/tabwriter/tabwriter_test.go:698:9: fmt.Sprintf can be replaced with faster strconv.Itoa (perfsprint) b.Run(fmt.Sprintf("%d", x), func(b *testing.B) { ^ cli/command/formatter/tabwriter/tabwriter_test.go:720:9: fmt.Sprintf can be replaced with faster strconv.Itoa (perfsprint) b.Run(fmt.Sprintf("%d", h), func(b *testing.B) { ^ cli/command/image/prune.go:62:31: fmt.Sprintf can be replaced with faster strconv.FormatBool (perfsprint) pruneFilters.Add("dangling", fmt.Sprintf("%v", !options.all)) ^ cli/command/network/formatter.go:92:9: fmt.Sprintf can be replaced with faster strconv.FormatBool (perfsprint) return fmt.Sprintf("%v", c.n.EnableIPv6) ^ cli/command/network/formatter.go:96:9: fmt.Sprintf can be replaced with faster strconv.FormatBool (perfsprint) return fmt.Sprintf("%v", c.n.Internal) ^ cli/command/service/formatter.go:745:9: fmt.Sprintf can be replaced with faster strconv.FormatUint (perfsprint) pub = fmt.Sprintf("%d", pr.pStart) ^ cli/command/service/formatter.go:750:9: fmt.Sprintf can be replaced with faster strconv.FormatUint (perfsprint) tgt = fmt.Sprintf("%d", pr.tStart) ^ cli/command/service/opts.go:49:10: fmt.Sprintf can be replaced with faster strconv.FormatUint (perfsprint) return fmt.Sprintf("%v", *i.value) ^ cli/compose/loader/loader.go:720:36: fmt.Sprint can be replaced with faster strconv.Itoa (perfsprint) v, err := toServicePortConfigs(fmt.Sprint(value)) ^ Signed-off-by: Sebastiaan van Stijn --- .golangci.yml | 1 + cli/command/formatter/buildcache.go | 8 ++++---- cli/command/formatter/image.go | 4 ++-- cli/command/formatter/tabwriter/tabwriter_test.go | 5 +++-- cli/command/image/prune.go | 3 ++- cli/command/network/formatter.go | 6 +++--- cli/command/service/formatter.go | 5 +++-- cli/command/service/opts.go | 2 +- cli/compose/loader/loader.go | 3 ++- cli/compose/types/types.go | 3 ++- 10 files changed, 23 insertions(+), 17 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index b7b597804a..c5b9e4696c 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -16,6 +16,7 @@ linters: - misspell - nakedret - nilerr # Detects code that returns nil even if it checks that the error is not nil. + - perfsprint # Detects fmt.Sprintf uses that can be replaced with a faster alternative. - predeclared - revive - staticcheck diff --git a/cli/command/formatter/buildcache.go b/cli/command/formatter/buildcache.go index f6fbe72d3e..71f80c0c17 100644 --- a/cli/command/formatter/buildcache.go +++ b/cli/command/formatter/buildcache.go @@ -1,8 +1,8 @@ package formatter import ( - "fmt" "sort" + "strconv" "strings" "time" @@ -171,13 +171,13 @@ func (c *buildCacheContext) LastUsedSince() string { } func (c *buildCacheContext) UsageCount() string { - return fmt.Sprintf("%d", c.v.UsageCount) + return strconv.Itoa(c.v.UsageCount) } func (c *buildCacheContext) InUse() string { - return fmt.Sprintf("%t", c.v.InUse) + return strconv.FormatBool(c.v.InUse) } func (c *buildCacheContext) Shared() string { - return fmt.Sprintf("%t", c.v.Shared) + return strconv.FormatBool(c.v.Shared) } diff --git a/cli/command/formatter/image.go b/cli/command/formatter/image.go index c7eeb1e39c..b2075674ba 100644 --- a/cli/command/formatter/image.go +++ b/cli/command/formatter/image.go @@ -1,7 +1,7 @@ package formatter import ( - "fmt" + "strconv" "time" "github.com/distribution/reference" @@ -256,7 +256,7 @@ func (c *imageContext) Containers() string { if c.i.Containers == -1 { return "N/A" } - return fmt.Sprintf("%d", c.i.Containers) + return strconv.FormatInt(c.i.Containers, 10) } // VirtualSize shows the virtual size of the image and all of its parent diff --git a/cli/command/formatter/tabwriter/tabwriter_test.go b/cli/command/formatter/tabwriter/tabwriter_test.go index 45669b36d8..5f61d87aae 100644 --- a/cli/command/formatter/tabwriter/tabwriter_test.go +++ b/cli/command/formatter/tabwriter/tabwriter_test.go @@ -8,6 +8,7 @@ import ( "bytes" "fmt" "io" + "strconv" "testing" ) @@ -695,7 +696,7 @@ func BenchmarkPyramid(b *testing.B) { for _, x := range [...]int{10, 100, 1000} { // Build a line with x cells. line := bytes.Repeat([]byte("a\t"), x) - b.Run(fmt.Sprintf("%d", x), func(b *testing.B) { + b.Run(strconv.Itoa(x), func(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { w := NewWriter(io.Discard, 4, 4, 1, ' ', 0) // no particular reason for these settings @@ -717,7 +718,7 @@ func BenchmarkRagged(b *testing.B) { lines[i] = bytes.Repeat([]byte("a\t"), w) } for _, h := range [...]int{10, 100, 1000} { - b.Run(fmt.Sprintf("%d", h), func(b *testing.B) { + b.Run(strconv.Itoa(h), func(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { w := NewWriter(io.Discard, 4, 4, 1, ' ', 0) // no particular reason for these settings diff --git a/cli/command/image/prune.go b/cli/command/image/prune.go index c94c1be596..e3bf349910 100644 --- a/cli/command/image/prune.go +++ b/cli/command/image/prune.go @@ -3,6 +3,7 @@ package image import ( "context" "fmt" + "strconv" "strings" "github.com/docker/cli/cli" @@ -59,7 +60,7 @@ Are you sure you want to continue?` func runPrune(dockerCli command.Cli, options pruneOptions) (spaceReclaimed uint64, output string, err error) { pruneFilters := options.filter.Value().Clone() - pruneFilters.Add("dangling", fmt.Sprintf("%v", !options.all)) + pruneFilters.Add("dangling", strconv.FormatBool(!options.all)) pruneFilters = command.PruneFilters(dockerCli, pruneFilters) warning := danglingWarning diff --git a/cli/command/network/formatter.go b/cli/command/network/formatter.go index 604095a9d4..5e8765df6f 100644 --- a/cli/command/network/formatter.go +++ b/cli/command/network/formatter.go @@ -1,7 +1,7 @@ package network import ( - "fmt" + "strconv" "strings" "github.com/docker/cli/cli/command/formatter" @@ -89,11 +89,11 @@ func (c *networkContext) Scope() string { } func (c *networkContext) IPv6() string { - return fmt.Sprintf("%v", c.n.EnableIPv6) + return strconv.FormatBool(c.n.EnableIPv6) } func (c *networkContext) Internal() string { - return fmt.Sprintf("%v", c.n.Internal) + return strconv.FormatBool(c.n.Internal) } func (c *networkContext) Labels() string { diff --git a/cli/command/service/formatter.go b/cli/command/service/formatter.go index 91b6a3f830..0dc02d3522 100644 --- a/cli/command/service/formatter.go +++ b/cli/command/service/formatter.go @@ -3,6 +3,7 @@ package service import ( "fmt" "sort" + "strconv" "strings" "time" @@ -742,12 +743,12 @@ func (pr portRange) String() string { if pr.pEnd > pr.pStart { pub = fmt.Sprintf("%d-%d", pr.pStart, pr.pEnd) } else { - pub = fmt.Sprintf("%d", pr.pStart) + pub = strconv.FormatUint(uint64(pr.pStart), 10) } if pr.tEnd > pr.tStart { tgt = fmt.Sprintf("%d-%d", pr.tStart, pr.tEnd) } else { - tgt = fmt.Sprintf("%d", pr.tStart) + tgt = strconv.FormatUint(uint64(pr.tStart), 10) } return fmt.Sprintf("*:%s->%s/%s", pub, tgt, pr.protocol) } diff --git a/cli/command/service/opts.go b/cli/command/service/opts.go index 67c19fefd1..d36afa5ef1 100644 --- a/cli/command/service/opts.go +++ b/cli/command/service/opts.go @@ -46,7 +46,7 @@ func (i *Uint64Opt) Type() string { // String returns a string repr of this option func (i *Uint64Opt) String() string { if i.value != nil { - return fmt.Sprintf("%v", *i.value) + return strconv.FormatUint(*i.value, 10) } return "" } diff --git a/cli/compose/loader/loader.go b/cli/compose/loader/loader.go index c5edd5c51f..a507181960 100644 --- a/cli/compose/loader/loader.go +++ b/cli/compose/loader/loader.go @@ -6,6 +6,7 @@ import ( "path/filepath" "reflect" "sort" + "strconv" "strings" "time" @@ -717,7 +718,7 @@ var transformServicePort TransformerFunc = func(data interface{}) (interface{}, for _, entry := range entries { switch value := entry.(type) { case int: - v, err := toServicePortConfigs(fmt.Sprint(value)) + v, err := toServicePortConfigs(strconv.Itoa(value)) if err != nil { return data, err } diff --git a/cli/compose/types/types.go b/cli/compose/types/types.go index 964e5f5e33..f606f9ea8a 100644 --- a/cli/compose/types/types.go +++ b/cli/compose/types/types.go @@ -3,6 +3,7 @@ package types import ( "encoding/json" "fmt" + "strconv" "time" ) @@ -565,7 +566,7 @@ func (e External) MarshalYAML() (interface{}, error) { // MarshalJSON makes External implement json.Marshaller func (e External) MarshalJSON() ([]byte, error) { if e.Name == "" { - return []byte(fmt.Sprintf("%v", e.External)), nil + return []byte(strconv.FormatBool(e.External)), nil } return []byte(fmt.Sprintf(`{"name": %q}`, e.Name)), nil } From 8e9aec69048134799e46b03463f9a0d5906fc11b Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Mon, 20 Nov 2023 17:38:50 +0100 Subject: [PATCH 15/19] golangci-lint: revive: enable import-shadowing Signed-off-by: Sebastiaan van Stijn --- .golangci.yml | 7 + cli/command/cli.go | 6 +- cli/command/container/attach.go | 34 ++--- cli/command/container/client_test.go | 48 +++---- cli/command/container/create.go | 30 ++-- cli/command/container/create_test.go | 12 +- cli/command/container/exec_test.go | 4 +- cli/command/container/list.go | 44 +++--- cli/command/container/run.go | 12 +- cli/command/container/run_test.go | 12 +- cli/command/container/tty.go | 6 +- cli/command/container/utils.go | 2 +- cli/command/context/create.go | 14 +- cli/command/context/create_test.go | 4 +- cli/command/context/update.go | 8 +- cli/command/formatter/image.go | 22 +-- cli/command/idresolver/idresolver.go | 4 +- cli/command/image/build_test.go | 8 +- cli/command/image/client_test.go | 12 +- cli/command/image/pull.go | 12 +- cli/command/image/trust.go | 16 +-- cli/command/manifest/annotate_test.go | 6 +- cli/command/manifest/create_test.go | 20 +-- cli/command/manifest/rm_test.go | 16 +-- cli/command/network/connect.go | 4 +- cli/command/service/formatter.go | 6 +- cli/command/service/list.go | 22 +-- cli/command/service/logs.go | 6 +- cli/command/service/opts.go | 174 +++++++++++------------ cli/command/service/parse.go | 8 +- cli/command/service/progress/progress.go | 12 +- cli/command/service/ps.go | 20 +-- cli/command/stack/client_test.go | 4 +- cli/command/stack/config.go | 4 +- cli/command/stack/swarm/client_test.go | 4 +- cli/command/swarm/client_test.go | 4 +- cli/command/swarm/opts.go | 42 +++--- cli/command/system/info_test.go | 2 +- cli/command/trust/inspect.go | 14 +- cli/command/trust/revoke.go | 16 +-- cli/command/trust/sign.go | 33 ++--- cli/command/trust/signer_add.go | 24 ++-- cli/command/trust/signer_remove.go | 20 +-- cli/compose/convert/service.go | 23 ++- cli/compose/convert/service_test.go | 8 +- cli/compose/convert/volume_test.go | 40 +++--- cli/compose/loader/loader.go | 30 ++-- cli/compose/schema/schema.go | 22 +-- cli/context/store/store.go | 4 +- cmd/docker/docker.go | 6 +- internal/test/builders/swarm.go | 10 +- internal/test/builders/volume.go | 20 +-- internal/test/cli.go | 20 +-- 53 files changed, 482 insertions(+), 479 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index c5b9e4696c..c306a9c29e 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -55,6 +55,13 @@ linters-settings: command: nakedret pattern: ^(?P.*?\\.go):(?P\\d+)\\s*(?P.*)$ + revive: + rules: + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#import-shadowing + - name: import-shadowing + severity: warning + disabled: false + issues: # The default exclusion rules are a bit too permissive, so copying the relevant ones below exclude-use-default: false diff --git a/cli/command/cli.go b/cli/command/cli.go index dfc22b701f..87b9b9d0db 100644 --- a/cli/command/cli.go +++ b/cli/command/cli.go @@ -394,7 +394,7 @@ func (cli *DockerCli) CurrentContext() string { // occur when trying to use it. // // Refer to [DockerCli.CurrentContext] above for further details. -func resolveContextName(opts *cliflags.ClientOptions, config *configfile.ConfigFile) string { +func resolveContextName(opts *cliflags.ClientOptions, cfg *configfile.ConfigFile) string { if opts != nil && opts.Context != "" { return opts.Context } @@ -407,9 +407,9 @@ func resolveContextName(opts *cliflags.ClientOptions, config *configfile.ConfigF if ctxName := os.Getenv(EnvOverrideContext); ctxName != "" { return ctxName } - if config != nil && config.CurrentContext != "" { + if cfg != nil && cfg.CurrentContext != "" { // We don't validate if this context exists: errors may occur when trying to use it. - return config.CurrentContext + return cfg.CurrentContext } return DefaultContextName } diff --git a/cli/command/container/attach.go b/cli/command/container/attach.go index 851ce880ed..0c4b963ee3 100644 --- a/cli/command/container/attach.go +++ b/cli/command/container/attach.go @@ -24,8 +24,8 @@ type AttachOptions struct { DetachKeys string } -func inspectContainerAndCheckState(ctx context.Context, cli client.APIClient, args string) (*types.ContainerJSON, error) { - c, err := cli.ContainerInspect(ctx, args) +func inspectContainerAndCheckState(ctx context.Context, apiClient client.APIClient, args string) (*types.ContainerJSON, error) { + c, err := apiClient.ContainerInspect(ctx, args) if err != nil { return nil, err } @@ -45,21 +45,21 @@ func inspectContainerAndCheckState(ctx context.Context, cli client.APIClient, ar // NewAttachCommand creates a new cobra.Command for `docker attach` func NewAttachCommand(dockerCli command.Cli) *cobra.Command { var opts AttachOptions - var container string + var ctr string cmd := &cobra.Command{ Use: "attach [OPTIONS] CONTAINER", Short: "Attach local standard input, output, and error streams to a running container", Args: cli.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - container = args[0] - return RunAttach(context.Background(), dockerCli, container, &opts) + ctr = args[0] + return RunAttach(context.Background(), dockerCli, ctr, &opts) }, Annotations: map[string]string{ "aliases": "docker container attach, docker attach", }, - ValidArgsFunction: completion.ContainerNames(dockerCli, false, func(container types.Container) bool { - return container.State != "paused" + ValidArgsFunction: completion.ContainerNames(dockerCli, false, func(ctr types.Container) bool { + return ctr.State != "paused" }), } @@ -71,8 +71,8 @@ func NewAttachCommand(dockerCli command.Cli) *cobra.Command { } // RunAttach executes an `attach` command -func RunAttach(ctx context.Context, dockerCli command.Cli, target string, opts *AttachOptions) error { - apiClient := dockerCli.Client() +func RunAttach(ctx context.Context, dockerCLI command.Cli, target string, opts *AttachOptions) error { + apiClient := dockerCLI.Client() // request channel to wait for client resultC, errC := apiClient.ContainerWait(ctx, target, "") @@ -82,11 +82,11 @@ func RunAttach(ctx context.Context, dockerCli command.Cli, target string, opts * return err } - if err := dockerCli.In().CheckTty(!opts.NoStdin, c.Config.Tty); err != nil { + if err := dockerCLI.In().CheckTty(!opts.NoStdin, c.Config.Tty); err != nil { return err } - detachKeys := dockerCli.ConfigFile().DetachKeys + detachKeys := dockerCLI.ConfigFile().DetachKeys if opts.DetachKeys != "" { detachKeys = opts.DetachKeys } @@ -101,7 +101,7 @@ func RunAttach(ctx context.Context, dockerCli command.Cli, target string, opts * var in io.ReadCloser if options.Stdin { - in = dockerCli.In() + in = dockerCLI.In() } if opts.Proxy && !c.Config.Tty { @@ -129,15 +129,15 @@ func RunAttach(ctx context.Context, dockerCli command.Cli, target string, opts * return err } - if c.Config.Tty && dockerCli.Out().IsTerminal() { - resizeTTY(ctx, dockerCli, target) + if c.Config.Tty && dockerCLI.Out().IsTerminal() { + resizeTTY(ctx, dockerCLI, target) } streamer := hijackedIOStreamer{ - streams: dockerCli, + streams: dockerCLI, inputStream: in, - outputStream: dockerCli.Out(), - errorStream: dockerCli.Err(), + outputStream: dockerCLI.Out(), + errorStream: dockerCLI.Err(), resp: resp, tty: c.Config.Tty, detachKeys: options.DetachKeys, diff --git a/cli/command/container/client_test.go b/cli/command/container/client_test.go index b650aece7d..68f56c70b5 100644 --- a/cli/command/container/client_test.go +++ b/cli/command/container/client_test.go @@ -16,24 +16,24 @@ type fakeClient struct { client.Client inspectFunc func(string) (types.ContainerJSON, error) execInspectFunc func(execID string) (types.ContainerExecInspect, error) - execCreateFunc func(container string, config types.ExecConfig) (types.IDResponse, error) + execCreateFunc func(containerID string, config types.ExecConfig) (types.IDResponse, error) createContainerFunc func(config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *specs.Platform, containerName string) (container.CreateResponse, error) - containerStartFunc func(container string, options container.StartOptions) error + containerStartFunc func(containerID string, options container.StartOptions) error imageCreateFunc func(parentReference string, options types.ImageCreateOptions) (io.ReadCloser, error) infoFunc func() (system.Info, error) - containerStatPathFunc func(container, path string) (types.ContainerPathStat, error) - containerCopyFromFunc func(container, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) + containerStatPathFunc func(containerID, path string) (types.ContainerPathStat, error) + containerCopyFromFunc func(containerID, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) logFunc func(string, container.LogsOptions) (io.ReadCloser, error) waitFunc func(string) (<-chan container.WaitResponse, <-chan error) containerListFunc func(container.ListOptions) ([]types.Container, error) containerExportFunc func(string) (io.ReadCloser, error) containerExecResizeFunc func(id string, options container.ResizeOptions) error - containerRemoveFunc func(ctx context.Context, container string, options container.RemoveOptions) error - containerKillFunc func(ctx context.Context, container, signal string) error + containerRemoveFunc func(ctx context.Context, containerID string, options container.RemoveOptions) error + containerKillFunc func(ctx context.Context, containerID, signal string) error Version string } @@ -51,9 +51,9 @@ func (f *fakeClient) ContainerInspect(_ context.Context, containerID string) (ty return types.ContainerJSON{}, nil } -func (f *fakeClient) ContainerExecCreate(_ context.Context, container string, config types.ExecConfig) (types.IDResponse, error) { +func (f *fakeClient) ContainerExecCreate(_ context.Context, containerID string, config types.ExecConfig) (types.IDResponse, error) { if f.execCreateFunc != nil { - return f.execCreateFunc(container, config) + return f.execCreateFunc(containerID, config) } return types.IDResponse{}, nil } @@ -83,9 +83,9 @@ func (f *fakeClient) ContainerCreate( return container.CreateResponse{}, nil } -func (f *fakeClient) ContainerRemove(ctx context.Context, container string, options container.RemoveOptions) error { +func (f *fakeClient) ContainerRemove(ctx context.Context, containerID string, options container.RemoveOptions) error { if f.containerRemoveFunc != nil { - return f.containerRemoveFunc(ctx, container, options) + return f.containerRemoveFunc(ctx, containerID, options) } return nil } @@ -104,23 +104,23 @@ func (f *fakeClient) Info(_ context.Context) (system.Info, error) { return system.Info{}, nil } -func (f *fakeClient) ContainerStatPath(_ context.Context, container, path string) (types.ContainerPathStat, error) { +func (f *fakeClient) ContainerStatPath(_ context.Context, containerID, path string) (types.ContainerPathStat, error) { if f.containerStatPathFunc != nil { - return f.containerStatPathFunc(container, path) + return f.containerStatPathFunc(containerID, path) } return types.ContainerPathStat{}, nil } -func (f *fakeClient) CopyFromContainer(_ context.Context, container, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) { +func (f *fakeClient) CopyFromContainer(_ context.Context, containerID, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) { if f.containerCopyFromFunc != nil { - return f.containerCopyFromFunc(container, srcPath) + return f.containerCopyFromFunc(containerID, srcPath) } return nil, types.ContainerPathStat{}, nil } -func (f *fakeClient) ContainerLogs(_ context.Context, container string, options container.LogsOptions) (io.ReadCloser, error) { +func (f *fakeClient) ContainerLogs(_ context.Context, containerID string, options container.LogsOptions) (io.ReadCloser, error) { if f.logFunc != nil { - return f.logFunc(container, options) + return f.logFunc(containerID, options) } return nil, nil } @@ -129,23 +129,23 @@ func (f *fakeClient) ClientVersion() string { return f.Version } -func (f *fakeClient) ContainerWait(_ context.Context, container string, _ container.WaitCondition) (<-chan container.WaitResponse, <-chan error) { +func (f *fakeClient) ContainerWait(_ context.Context, containerID string, _ container.WaitCondition) (<-chan container.WaitResponse, <-chan error) { if f.waitFunc != nil { - return f.waitFunc(container) + return f.waitFunc(containerID) } return nil, nil } -func (f *fakeClient) ContainerStart(_ context.Context, container string, options container.StartOptions) error { +func (f *fakeClient) ContainerStart(_ context.Context, containerID string, options container.StartOptions) error { if f.containerStartFunc != nil { - return f.containerStartFunc(container, options) + return f.containerStartFunc(containerID, options) } return nil } -func (f *fakeClient) ContainerExport(_ context.Context, container string) (io.ReadCloser, error) { +func (f *fakeClient) ContainerExport(_ context.Context, containerID string) (io.ReadCloser, error) { if f.containerExportFunc != nil { - return f.containerExportFunc(container) + return f.containerExportFunc(containerID) } return nil, nil } @@ -157,9 +157,9 @@ func (f *fakeClient) ContainerExecResize(_ context.Context, id string, options c return nil } -func (f *fakeClient) ContainerKill(ctx context.Context, container, signal string) error { +func (f *fakeClient) ContainerKill(ctx context.Context, containerID, signal string) error { if f.containerKillFunc != nil { - return f.containerKillFunc(ctx, container, signal) + return f.containerKillFunc(ctx, containerID, signal) } return nil } diff --git a/cli/command/container/create.go b/cli/command/container/create.go index 01078461a4..26b3170ac8 100644 --- a/cli/command/container/create.go +++ b/cli/command/container/create.go @@ -113,15 +113,15 @@ func runCreate(dockerCli command.Cli, flags *pflag.FlagSet, options *createOptio } // FIXME(thaJeztah): this is the only code-path that uses APIClient.ImageCreate. Rewrite this to use the regular "pull" code (or vice-versa). -func pullImage(ctx context.Context, dockerCli command.Cli, image string, opts *createOptions) error { - encodedAuth, err := command.RetrieveAuthTokenFromImage(dockerCli.ConfigFile(), image) +func pullImage(ctx context.Context, dockerCli command.Cli, img string, options *createOptions) error { + encodedAuth, err := command.RetrieveAuthTokenFromImage(dockerCli.ConfigFile(), img) if err != nil { return err } - responseBody, err := dockerCli.Client().ImageCreate(ctx, image, types.ImageCreateOptions{ + responseBody, err := dockerCli.Client().ImageCreate(ctx, img, types.ImageCreateOptions{ RegistryAuth: encodedAuth, - Platform: opts.platform, + Platform: options.platform, }) if err != nil { return err @@ -129,7 +129,7 @@ func pullImage(ctx context.Context, dockerCli command.Cli, image string, opts *c defer responseBody.Close() out := dockerCli.Err() - if opts.quiet { + if options.quiet { out = io.Discard } return jsonmessage.DisplayJSONMessagesToStream(responseBody, streams.NewOut(out), nil) @@ -185,7 +185,7 @@ func newCIDFile(path string) (*cidFile, error) { } //nolint:gocyclo -func createContainer(ctx context.Context, dockerCli command.Cli, containerCfg *containerConfig, opts *createOptions) (containerID string, err error) { +func createContainer(ctx context.Context, dockerCli command.Cli, containerCfg *containerConfig, options *createOptions) (containerID string, err error) { config := containerCfg.Config hostConfig := containerCfg.HostConfig networkingConfig := containerCfg.NetworkingConfig @@ -211,7 +211,7 @@ func createContainer(ctx context.Context, dockerCli command.Cli, containerCfg *c if named, ok := ref.(reference.Named); ok { namedRef = reference.TagNameOnly(named) - if taggedRef, ok := namedRef.(reference.NamedTagged); ok && !opts.untrusted { + if taggedRef, ok := namedRef.(reference.NamedTagged); ok && !options.untrusted { var err error trustedRef, err = image.TrustedReference(ctx, dockerCli, taggedRef) if err != nil { @@ -222,7 +222,7 @@ func createContainer(ctx context.Context, dockerCli command.Cli, containerCfg *c } pullAndTagImage := func() error { - if err := pullImage(ctx, dockerCli, config.Image, opts); err != nil { + if err := pullImage(ctx, dockerCli, config.Image, options); err != nil { return err } if taggedRef, ok := namedRef.(reference.NamedTagged); ok && trustedRef != nil { @@ -236,15 +236,15 @@ func createContainer(ctx context.Context, dockerCli command.Cli, containerCfg *c // create. It will produce an error if you try to set a platform on older API // versions, so check the API version here to maintain backwards // compatibility for CLI users. - if opts.platform != "" && versions.GreaterThanOrEqualTo(dockerCli.Client().ClientVersion(), "1.41") { - p, err := platforms.Parse(opts.platform) + if options.platform != "" && versions.GreaterThanOrEqualTo(dockerCli.Client().ClientVersion(), "1.41") { + p, err := platforms.Parse(options.platform) if err != nil { return "", errors.Wrap(err, "error parsing specified platform") } platform = &p } - if opts.pull == PullImageAlways { + if options.pull == PullImageAlways { if err := pullAndTagImage(); err != nil { return "", err } @@ -252,11 +252,11 @@ func createContainer(ctx context.Context, dockerCli command.Cli, containerCfg *c hostConfig.ConsoleSize[0], hostConfig.ConsoleSize[1] = dockerCli.Out().GetTtySize() - response, err := dockerCli.Client().ContainerCreate(ctx, config, hostConfig, networkingConfig, platform, opts.name) + response, err := dockerCli.Client().ContainerCreate(ctx, config, hostConfig, networkingConfig, platform, options.name) if err != nil { // Pull image if it does not exist locally and we have the PullImageMissing option. Default behavior. - if errdefs.IsNotFound(err) && namedRef != nil && opts.pull == PullImageMissing { - if !opts.quiet { + if errdefs.IsNotFound(err) && namedRef != nil && options.pull == PullImageMissing { + if !options.quiet { // we don't want to write to stdout anything apart from container.ID fmt.Fprintf(dockerCli.Err(), "Unable to find image '%s' locally\n", reference.FamiliarString(namedRef)) } @@ -266,7 +266,7 @@ func createContainer(ctx context.Context, dockerCli command.Cli, containerCfg *c } var retryErr error - response, retryErr = dockerCli.Client().ContainerCreate(ctx, config, hostConfig, networkingConfig, platform, opts.name) + response, retryErr = dockerCli.Client().ContainerCreate(ctx, config, hostConfig, networkingConfig, platform, options.name) if retryErr != nil { return "", retryErr } diff --git a/cli/command/container/create_test.go b/cli/command/container/create_test.go index 495e101166..2233532064 100644 --- a/cli/command/container/create_test.go +++ b/cli/command/container/create_test.go @@ -223,7 +223,7 @@ func TestNewCreateCommandWithContentTrustErrors(t *testing.T) { } for _, tc := range testCases { tc := tc - cli := test.NewFakeCli(&fakeClient{ + fakeCLI := test.NewFakeCli(&fakeClient{ createContainerFunc: func(config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, @@ -233,8 +233,8 @@ func TestNewCreateCommandWithContentTrustErrors(t *testing.T) { return container.CreateResponse{}, fmt.Errorf("shouldn't try to pull image") }, }, test.EnableContentTrust) - cli.SetNotaryClient(tc.notaryFunc) - cmd := NewCreateCommand(cli) + fakeCLI.SetNotaryClient(tc.notaryFunc) + cmd := NewCreateCommand(fakeCLI) cmd.SetOut(io.Discard) cmd.SetArgs(tc.args) err := cmd.Execute() @@ -323,7 +323,7 @@ func TestCreateContainerWithProxyConfig(t *testing.T) { } sort.Strings(expected) - cli := test.NewFakeCli(&fakeClient{ + fakeCLI := test.NewFakeCli(&fakeClient{ createContainerFunc: func(config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, @@ -335,7 +335,7 @@ func TestCreateContainerWithProxyConfig(t *testing.T) { return container.CreateResponse{}, nil }, }) - cli.SetConfigFile(&configfile.ConfigFile{ + fakeCLI.SetConfigFile(&configfile.ConfigFile{ Proxies: map[string]configfile.ProxyConfig{ "default": { HTTPProxy: "httpProxy", @@ -346,7 +346,7 @@ func TestCreateContainerWithProxyConfig(t *testing.T) { }, }, }) - cmd := NewCreateCommand(cli) + cmd := NewCreateCommand(fakeCLI) cmd.SetOut(io.Discard) cmd.SetArgs([]string{"image:tag"}) err := cmd.Execute() diff --git a/cli/command/container/exec_test.go b/cli/command/container/exec_test.go index 2d79590ab8..4bc52c9243 100644 --- a/cli/command/container/exec_test.go +++ b/cli/command/container/exec_test.go @@ -262,8 +262,8 @@ func TestNewExecCommandErrors(t *testing.T) { }, } for _, tc := range testCases { - cli := test.NewFakeCli(&fakeClient{inspectFunc: tc.containerInspectFunc}) - cmd := NewExecCommand(cli) + fakeCLI := test.NewFakeCli(&fakeClient{inspectFunc: tc.containerInspectFunc}) + cmd := NewExecCommand(fakeCLI) cmd.SetOut(io.Discard) cmd.SetArgs(tc.args) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) diff --git a/cli/command/container/list.go b/cli/command/container/list.go index 5f0f40be6f..21fa45a34b 100644 --- a/cli/command/container/list.go +++ b/cli/command/container/list.go @@ -29,7 +29,7 @@ type psOptions struct { } // NewPsCommand creates a new cobra.Command for `docker ps` -func NewPsCommand(dockerCli command.Cli) *cobra.Command { +func NewPsCommand(dockerCLI command.Cli) *cobra.Command { options := psOptions{filter: opts.NewFilterOpt()} cmd := &cobra.Command{ @@ -38,7 +38,7 @@ func NewPsCommand(dockerCli command.Cli) *cobra.Command { Args: cli.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { options.sizeChanged = cmd.Flags().Changed("size") - return runPs(dockerCli, &options) + return runPs(dockerCLI, &options) }, Annotations: map[string]string{ "category-top": "3", @@ -61,28 +61,28 @@ func NewPsCommand(dockerCli command.Cli) *cobra.Command { return cmd } -func newListCommand(dockerCli command.Cli) *cobra.Command { - cmd := *NewPsCommand(dockerCli) +func newListCommand(dockerCLI command.Cli) *cobra.Command { + cmd := *NewPsCommand(dockerCLI) cmd.Aliases = []string{"ps", "list"} cmd.Use = "ls [OPTIONS]" return &cmd } -func buildContainerListOptions(opts *psOptions) (*container.ListOptions, error) { - options := &container.ListOptions{ - All: opts.all, - Limit: opts.last, - Size: opts.size, - Filters: opts.filter.Value(), +func buildContainerListOptions(options *psOptions) (*container.ListOptions, error) { + listOptions := &container.ListOptions{ + All: options.all, + Limit: options.last, + Size: options.size, + Filters: options.filter.Value(), } - if opts.nLatest && opts.last == -1 { - options.Limit = 1 + if options.nLatest && options.last == -1 { + listOptions.Limit = 1 } // always validate template when `--format` is used, for consistency - if len(opts.format) > 0 { - tmpl, err := templates.NewParse("", opts.format) + if len(options.format) > 0 { + tmpl, err := templates.NewParse("", options.format) if err != nil { return nil, errors.Wrap(err, "failed to parse template") } @@ -97,7 +97,7 @@ func buildContainerListOptions(opts *psOptions) (*container.ListOptions, error) // if `size` was not explicitly set to false (with `--size=false`) // and `--quiet` is not set, request size if the template requires it - if !opts.quiet && !options.Size && !opts.sizeChanged { + if !options.quiet && !listOptions.Size && !options.sizeChanged { // The --size option isn't set, but .Size may be used in the template. // Parse and execute the given template to detect if the .Size field is // used. If it is, then automatically enable the --size option. See #24696 @@ -106,22 +106,22 @@ func buildContainerListOptions(opts *psOptions) (*container.ListOptions, error) // because calculating the size is a costly operation. if _, ok := optionsProcessor.FieldsUsed["Size"]; ok { - options.Size = true + listOptions.Size = true } } } - return options, nil + return listOptions, nil } -func runPs(dockerCli command.Cli, options *psOptions) error { +func runPs(dockerCLI command.Cli, options *psOptions) error { ctx := context.Background() if len(options.format) == 0 { // load custom psFormat from CLI config (if any) - options.format = dockerCli.ConfigFile().PsFormat + options.format = dockerCLI.ConfigFile().PsFormat } else if options.quiet { - _, _ = dockerCli.Err().Write([]byte("WARNING: Ignoring custom format, because both --format and --quiet are set.\n")) + _, _ = dockerCLI.Err().Write([]byte("WARNING: Ignoring custom format, because both --format and --quiet are set.\n")) } listOptions, err := buildContainerListOptions(options) @@ -129,13 +129,13 @@ func runPs(dockerCli command.Cli, options *psOptions) error { return err } - containers, err := dockerCli.Client().ContainerList(ctx, *listOptions) + containers, err := dockerCLI.Client().ContainerList(ctx, *listOptions) if err != nil { return err } containerCtx := formatter.Context{ - Output: dockerCli.Out(), + Output: dockerCLI.Out(), Format: formatter.NewContainerFormat(options.format, options.quiet, listOptions.Size), Trunc: !options.noTrunc, } diff --git a/cli/command/container/run.go b/cli/command/container/run.go index bbcb9efa9e..92e9b1ee33 100644 --- a/cli/command/container/run.go +++ b/cli/command/container/run.go @@ -118,14 +118,14 @@ func runRun(dockerCli command.Cli, flags *pflag.FlagSet, ropts *runOptions, copt } //nolint:gocyclo -func runContainer(dockerCli command.Cli, opts *runOptions, copts *containerOptions, containerCfg *containerConfig) error { +func runContainer(dockerCli command.Cli, runOpts *runOptions, copts *containerOptions, containerCfg *containerConfig) error { config := containerCfg.Config stdout, stderr := dockerCli.Out(), dockerCli.Err() apiClient := dockerCli.Client() config.ArgsEscaped = false - if !opts.detach { + if !runOpts.detach { if err := dockerCli.In().CheckTty(config.AttachStdin, config.Tty); err != nil { return err } @@ -143,12 +143,12 @@ func runContainer(dockerCli command.Cli, opts *runOptions, copts *containerOptio ctx, cancelFun := context.WithCancel(context.Background()) defer cancelFun() - containerID, err := createContainer(ctx, dockerCli, containerCfg, &opts.createOptions) + containerID, err := createContainer(ctx, dockerCli, containerCfg, &runOpts.createOptions) if err != nil { reportError(stderr, "run", err.Error(), true) return runStartContainerErr(err) } - if opts.sigProxy { + if runOpts.sigProxy { sigc := notifyAllSignals() go ForwardAllSignals(ctx, apiClient, containerID, sigc) defer signal.StopCatch(sigc) @@ -169,8 +169,8 @@ func runContainer(dockerCli command.Cli, opts *runOptions, copts *containerOptio attach := config.AttachStdin || config.AttachStdout || config.AttachStderr if attach { detachKeys := dockerCli.ConfigFile().DetachKeys - if opts.detachKeys != "" { - detachKeys = opts.detachKeys + if runOpts.detachKeys != "" { + detachKeys = runOpts.detachKeys } closeFn, err := attachContainer(ctx, dockerCli, containerID, &errCh, config, container.AttachOptions{ diff --git a/cli/command/container/run_test.go b/cli/command/container/run_test.go index 4f3acfa730..d901c20aa7 100644 --- a/cli/command/container/run_test.go +++ b/cli/command/container/run_test.go @@ -18,7 +18,7 @@ import ( ) func TestRunLabel(t *testing.T) { - cli := test.NewFakeCli(&fakeClient{ + fakeCLI := test.NewFakeCli(&fakeClient{ createContainerFunc: func(_ *container.Config, _ *container.HostConfig, _ *network.NetworkingConfig, _ *specs.Platform, _ string) (container.CreateResponse, error) { return container.CreateResponse{ ID: "id", @@ -26,7 +26,7 @@ func TestRunLabel(t *testing.T) { }, Version: "1.36", }) - cmd := NewRunCommand(cli) + cmd := NewRunCommand(fakeCLI) cmd.SetArgs([]string{"--detach=true", "--label", "foo", "busybox"}) assert.NilError(t, cmd.Execute()) } @@ -58,7 +58,7 @@ func TestRunCommandWithContentTrustErrors(t *testing.T) { }, } for _, tc := range testCases { - cli := test.NewFakeCli(&fakeClient{ + fakeCLI := test.NewFakeCli(&fakeClient{ createContainerFunc: func(config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, @@ -68,13 +68,13 @@ func TestRunCommandWithContentTrustErrors(t *testing.T) { return container.CreateResponse{}, fmt.Errorf("shouldn't try to pull image") }, }, test.EnableContentTrust) - cli.SetNotaryClient(tc.notaryFunc) - cmd := NewRunCommand(cli) + fakeCLI.SetNotaryClient(tc.notaryFunc) + cmd := NewRunCommand(fakeCLI) cmd.SetArgs(tc.args) cmd.SetOut(io.Discard) err := cmd.Execute() assert.Assert(t, err != nil) - assert.Assert(t, is.Contains(cli.ErrBuffer().String(), tc.expectedError)) + assert.Assert(t, is.Contains(fakeCLI.ErrBuffer().String(), tc.expectedError)) } } diff --git a/cli/command/container/tty.go b/cli/command/container/tty.go index a3fe9baf41..c2a5b4f8a5 100644 --- a/cli/command/container/tty.go +++ b/cli/command/container/tty.go @@ -16,7 +16,7 @@ import ( ) // resizeTtyTo resizes tty to specific height and width -func resizeTtyTo(ctx context.Context, client client.ContainerAPIClient, id string, height, width uint, isExec bool) error { +func resizeTtyTo(ctx context.Context, apiClient client.ContainerAPIClient, id string, height, width uint, isExec bool) error { if height == 0 && width == 0 { return nil } @@ -28,9 +28,9 @@ func resizeTtyTo(ctx context.Context, client client.ContainerAPIClient, id strin var err error if isExec { - err = client.ContainerExecResize(ctx, id, options) + err = apiClient.ContainerExecResize(ctx, id, options) } else { - err = client.ContainerResize(ctx, id, options) + err = apiClient.ContainerResize(ctx, id, options) } if err != nil { diff --git a/cli/command/container/utils.go b/cli/command/container/utils.go index 8a94a182cd..31b9df4aad 100644 --- a/cli/command/container/utils.go +++ b/cli/command/container/utils.go @@ -127,7 +127,7 @@ func legacyWaitExitOrRemoved(ctx context.Context, apiClient client.APIClient, co return statusChan } -func parallelOperation(ctx context.Context, containers []string, op func(ctx context.Context, container string) error) chan error { +func parallelOperation(ctx context.Context, containers []string, op func(ctx context.Context, containerID string) error) chan error { if len(containers) == 0 { return nil } diff --git a/cli/command/context/create.go b/cli/command/context/create.go index 2ff2ca8ef6..93560a4531 100644 --- a/cli/command/context/create.go +++ b/cli/command/context/create.go @@ -36,7 +36,7 @@ func longCreateDescription() string { return buf.String() } -func newCreateCommand(dockerCli command.Cli) *cobra.Command { +func newCreateCommand(dockerCLI command.Cli) *cobra.Command { opts := &CreateOptions{} cmd := &cobra.Command{ Use: "create [OPTIONS] CONTEXT", @@ -44,7 +44,7 @@ func newCreateCommand(dockerCli command.Cli) *cobra.Command { Args: cli.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { opts.Name = args[0] - return RunCreate(dockerCli, opts) + return RunCreate(dockerCLI, opts) }, Long: longCreateDescription(), ValidArgsFunction: completion.NoComplete, @@ -57,23 +57,23 @@ func newCreateCommand(dockerCli command.Cli) *cobra.Command { } // RunCreate creates a Docker context -func RunCreate(cli command.Cli, o *CreateOptions) error { - s := cli.ContextStore() +func RunCreate(dockerCLI command.Cli, o *CreateOptions) error { + s := dockerCLI.ContextStore() err := checkContextNameForCreation(s, o.Name) if err != nil { return err } switch { case o.From == "" && o.Docker == nil: - err = createFromExistingContext(s, cli.CurrentContext(), o) + err = createFromExistingContext(s, dockerCLI.CurrentContext(), o) case o.From != "": err = createFromExistingContext(s, o.From, o) default: err = createNewContext(s, o) } if err == nil { - fmt.Fprintln(cli.Out(), o.Name) - fmt.Fprintf(cli.Err(), "Successfully created context %q\n", o.Name) + fmt.Fprintln(dockerCLI.Out(), o.Name) + fmt.Fprintf(dockerCLI.Err(), "Successfully created context %q\n", o.Name) } return err } diff --git a/cli/command/context/create_test.go b/cli/command/context/create_test.go index a887c978bd..f27ad8aac6 100644 --- a/cli/command/context/create_test.go +++ b/cli/command/context/create_test.go @@ -19,7 +19,7 @@ func makeFakeCli(t *testing.T, opts ...func(*test.FakeCli)) *test.FakeCli { func() interface{} { return &command.DockerContext{} }, store.EndpointTypeGetter(docker.DockerEndpoint, func() interface{} { return &docker.EndpointMeta{} }), ) - store := &command.ContextStoreWithDefault{ + contextStore := &command.ContextStoreWithDefault{ Store: store.New(dir, storeConfig), Resolver: func() (*command.DefaultContext, error) { return &command.DefaultContext{ @@ -42,7 +42,7 @@ func makeFakeCli(t *testing.T, opts ...func(*test.FakeCli)) *test.FakeCli { for _, o := range opts { o(result) } - result.SetContextStore(store) + result.SetContextStore(contextStore) return result } diff --git a/cli/command/context/update.go b/cli/command/context/update.go index e039736dac..98eba7d1ec 100644 --- a/cli/command/context/update.go +++ b/cli/command/context/update.go @@ -52,11 +52,11 @@ func newUpdateCommand(dockerCli command.Cli) *cobra.Command { } // RunUpdate updates a Docker context -func RunUpdate(cli command.Cli, o *UpdateOptions) error { +func RunUpdate(dockerCLI command.Cli, o *UpdateOptions) error { if err := store.ValidateContextName(o.Name); err != nil { return err } - s := cli.ContextStore() + s := dockerCLI.ContextStore() c, err := s.GetMetadata(o.Name) if err != nil { return err @@ -93,8 +93,8 @@ func RunUpdate(cli command.Cli, o *UpdateOptions) error { } } - fmt.Fprintln(cli.Out(), o.Name) - fmt.Fprintf(cli.Err(), "Successfully updated context %q\n", o.Name) + fmt.Fprintln(dockerCLI.Out(), o.Name) + fmt.Fprintf(dockerCLI.Err(), "Successfully updated context %q\n", o.Name) return nil } diff --git a/cli/command/formatter/image.go b/cli/command/formatter/image.go index b2075674ba..da636891ad 100644 --- a/cli/command/formatter/image.go +++ b/cli/command/formatter/image.go @@ -26,11 +26,11 @@ type ImageContext struct { Digest bool } -func isDangling(image image.Summary) bool { - if len(image.RepoTags) == 0 && len(image.RepoDigests) == 0 { +func isDangling(img image.Summary) bool { + if len(img.RepoTags) == 0 && len(img.RepoDigests) == 0 { return true } - return len(image.RepoTags) == 1 && image.RepoTags[0] == ":" && len(image.RepoDigests) == 1 && image.RepoDigests[0] == "@" + return len(img.RepoTags) == 1 && img.RepoTags[0] == ":" && len(img.RepoDigests) == 1 && img.RepoDigests[0] == "@" } // NewImageFormat returns a format for rendering an ImageContext @@ -88,18 +88,18 @@ func needDigest(ctx ImageContext) bool { } func imageFormat(ctx ImageContext, images []image.Summary, format func(subContext SubContext) error) error { - for _, image := range images { + for _, img := range images { formatted := []*imageContext{} - if isDangling(image) { + if isDangling(img) { formatted = append(formatted, &imageContext{ trunc: ctx.Trunc, - i: image, + i: img, repo: "", tag: "", digest: "", }) } else { - formatted = imageFormatTaggedAndDigest(ctx, image) + formatted = imageFormatTaggedAndDigest(ctx, img) } for _, imageCtx := range formatted { if err := format(imageCtx); err != nil { @@ -110,12 +110,12 @@ func imageFormat(ctx ImageContext, images []image.Summary, format func(subContex return nil } -func imageFormatTaggedAndDigest(ctx ImageContext, image image.Summary) []*imageContext { +func imageFormatTaggedAndDigest(ctx ImageContext, img image.Summary) []*imageContext { repoTags := map[string][]string{} repoDigests := map[string][]string{} images := []*imageContext{} - for _, refString := range image.RepoTags { + for _, refString := range img.RepoTags { ref, err := reference.ParseNormalizedNamed(refString) if err != nil { continue @@ -125,7 +125,7 @@ func imageFormatTaggedAndDigest(ctx ImageContext, image image.Summary) []*imageC repoTags[familiarRef] = append(repoTags[familiarRef], nt.Tag()) } } - for _, refString := range image.RepoDigests { + for _, refString := range img.RepoDigests { ref, err := reference.ParseNormalizedNamed(refString) if err != nil { continue @@ -139,7 +139,7 @@ func imageFormatTaggedAndDigest(ctx ImageContext, image image.Summary) []*imageC addImage := func(repo, tag, digest string) { images = append(images, &imageContext{ trunc: ctx.Trunc, - i: image, + i: img, repo: repo, tag: tag, digest: digest, diff --git a/cli/command/idresolver/idresolver.go b/cli/command/idresolver/idresolver.go index cae4bb7339..8eb4f54bfb 100644 --- a/cli/command/idresolver/idresolver.go +++ b/cli/command/idresolver/idresolver.go @@ -17,9 +17,9 @@ type IDResolver struct { } // New creates a new IDResolver. -func New(client client.APIClient, noResolve bool) *IDResolver { +func New(apiClient client.APIClient, noResolve bool) *IDResolver { return &IDResolver{ - client: client, + client: apiClient, noResolve: noResolve, cache: make(map[string]string), } diff --git a/cli/command/image/build_test.go b/cli/command/image/build_test.go index a501913cc6..e7ae1aca41 100644 --- a/cli/command/image/build_test.go +++ b/cli/command/image/build_test.go @@ -25,8 +25,8 @@ func TestRunBuildDockerfileFromStdinWithCompress(t *testing.T) { t.Setenv("DOCKER_BUILDKIT", "0") buffer := new(bytes.Buffer) fakeBuild := newFakeBuild() - fakeImageBuild := func(ctx context.Context, context io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error) { - tee := io.TeeReader(context, buffer) + fakeImageBuild := func(ctx context.Context, buildContext io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error) { + tee := io.TeeReader(buildContext, buffer) gzipReader, err := gzip.NewReader(tee) assert.NilError(t, err) return fakeBuild.build(ctx, gzipReader, options) @@ -184,8 +184,8 @@ func newFakeBuild() *fakeBuild { return &fakeBuild{} } -func (f *fakeBuild) build(_ context.Context, context io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error) { - f.context = tar.NewReader(context) +func (f *fakeBuild) build(_ context.Context, buildContext io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error) { + f.context = tar.NewReader(buildContext) f.options = options body := new(bytes.Buffer) return types.ImageBuildResponse{Body: io.NopCloser(body)}, nil diff --git a/cli/command/image/client_test.go b/cli/command/image/client_test.go index 85b31b79b3..5c5bf985a4 100644 --- a/cli/command/image/client_test.go +++ b/cli/command/image/client_test.go @@ -30,9 +30,9 @@ type fakeClient struct { imageBuildFunc func(context.Context, io.Reader, types.ImageBuildOptions) (types.ImageBuildResponse, error) } -func (cli *fakeClient) ImageTag(_ context.Context, image, ref string) error { +func (cli *fakeClient) ImageTag(_ context.Context, img, ref string) error { if cli.imageTagFunc != nil { - return cli.imageTagFunc(image, ref) + return cli.imageTagFunc(img, ref) } return nil } @@ -95,9 +95,9 @@ func (cli *fakeClient) ImageList(_ context.Context, options types.ImageListOptio return []image.Summary{}, nil } -func (cli *fakeClient) ImageInspectWithRaw(_ context.Context, image string) (types.ImageInspect, []byte, error) { +func (cli *fakeClient) ImageInspectWithRaw(_ context.Context, img string) (types.ImageInspect, []byte, error) { if cli.imageInspectFunc != nil { - return cli.imageInspectFunc(image) + return cli.imageInspectFunc(img) } return types.ImageInspect{}, nil, nil } @@ -118,9 +118,9 @@ func (cli *fakeClient) ImageHistory(_ context.Context, img string) ([]image.Hist return []image.HistoryResponseItem{{ID: img, Created: time.Now().Unix()}}, nil } -func (cli *fakeClient) ImageBuild(ctx context.Context, context io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error) { +func (cli *fakeClient) ImageBuild(ctx context.Context, buildContext io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error) { if cli.imageBuildFunc != nil { - return cli.imageBuildFunc(ctx, context, options) + return cli.imageBuildFunc(ctx, buildContext, options) } return types.ImageBuildResponse{Body: io.NopCloser(strings.NewReader(""))}, nil } diff --git a/cli/command/image/pull.go b/cli/command/image/pull.go index b866c96191..b602619d9a 100644 --- a/cli/command/image/pull.go +++ b/cli/command/image/pull.go @@ -54,7 +54,7 @@ func NewPullCommand(dockerCli command.Cli) *cobra.Command { } // RunPull performs a pull against the engine based on the specified options -func RunPull(cli command.Cli, opts PullOptions) error { +func RunPull(dockerCLI command.Cli, opts PullOptions) error { distributionRef, err := reference.ParseNormalizedNamed(opts.remote) switch { case err != nil: @@ -64,12 +64,12 @@ func RunPull(cli command.Cli, opts PullOptions) error { case !opts.all && reference.IsNameOnly(distributionRef): distributionRef = reference.TagNameOnly(distributionRef) if tagged, ok := distributionRef.(reference.Tagged); ok && !opts.quiet { - fmt.Fprintf(cli.Out(), "Using default tag: %s\n", tagged.Tag()) + fmt.Fprintf(dockerCLI.Out(), "Using default tag: %s\n", tagged.Tag()) } } ctx := context.Background() - imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, AuthResolver(cli), distributionRef.String()) + imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, AuthResolver(dockerCLI), distributionRef.String()) if err != nil { return err } @@ -77,9 +77,9 @@ func RunPull(cli command.Cli, opts PullOptions) error { // Check if reference has a digest _, isCanonical := distributionRef.(reference.Canonical) if !opts.untrusted && !isCanonical { - err = trustedPull(ctx, cli, imgRefAndAuth, opts) + err = trustedPull(ctx, dockerCLI, imgRefAndAuth, opts) } else { - err = imagePullPrivileged(ctx, cli, imgRefAndAuth, opts) + err = imagePullPrivileged(ctx, dockerCLI, imgRefAndAuth, opts) } if err != nil { if strings.Contains(err.Error(), "when fetching 'plugin'") { @@ -87,6 +87,6 @@ func RunPull(cli command.Cli, opts PullOptions) error { } return err } - fmt.Fprintln(cli.Out(), imgRefAndAuth.Reference().String()) + fmt.Fprintln(dockerCLI.Out(), imgRefAndAuth.Reference().String()) return nil } diff --git a/cli/command/image/trust.go b/cli/command/image/trust.go index 34fa620ff6..675da83fd6 100644 --- a/cli/command/image/trust.go +++ b/cli/command/image/trust.go @@ -44,7 +44,7 @@ func TrustedPush(ctx context.Context, cli command.Cli, repoInfo *registry.Reposi // PushTrustedReference pushes a canonical reference to the trust server. // //nolint:gocyclo -func PushTrustedReference(streams command.Streams, repoInfo *registry.RepositoryInfo, ref reference.Named, authConfig registrytypes.AuthConfig, in io.Reader) error { +func PushTrustedReference(ioStreams command.Streams, repoInfo *registry.RepositoryInfo, ref reference.Named, authConfig registrytypes.AuthConfig, in io.Reader) error { // If it is a trusted push we would like to find the target entry which match the // tag provided in the function and then do an AddTarget later. target := &client.Target{} @@ -83,14 +83,14 @@ func PushTrustedReference(streams command.Streams, repoInfo *registry.Repository default: // We want trust signatures to always take an explicit tag, // otherwise it will act as an untrusted push. - if err := jsonmessage.DisplayJSONMessagesToStream(in, streams.Out(), nil); err != nil { + if err := jsonmessage.DisplayJSONMessagesToStream(in, ioStreams.Out(), nil); err != nil { return err } - fmt.Fprintln(streams.Err(), "No tag specified, skipping trust metadata push") + fmt.Fprintln(ioStreams.Err(), "No tag specified, skipping trust metadata push") return nil } - if err := jsonmessage.DisplayJSONMessagesToStream(in, streams.Out(), handleTarget); err != nil { + if err := jsonmessage.DisplayJSONMessagesToStream(in, ioStreams.Out(), handleTarget); err != nil { return err } @@ -102,9 +102,9 @@ func PushTrustedReference(streams command.Streams, repoInfo *registry.Repository return errors.Errorf("no targets found, please provide a specific tag in order to sign it") } - fmt.Fprintln(streams.Out(), "Signing and pushing trust metadata") + fmt.Fprintln(ioStreams.Out(), "Signing and pushing trust metadata") - repo, err := trust.GetNotaryRepository(streams.In(), streams.Out(), command.UserAgent(), repoInfo, &authConfig, "push", "pull") + repo, err := trust.GetNotaryRepository(ioStreams.In(), ioStreams.Out(), command.UserAgent(), repoInfo, &authConfig, "push", "pull") if err != nil { return errors.Wrap(err, "error establishing connection to trust repository") } @@ -132,7 +132,7 @@ func PushTrustedReference(streams command.Streams, repoInfo *registry.Repository if err := repo.Initialize([]string{rootKeyID}, data.CanonicalSnapshotRole); err != nil { return trust.NotaryError(repoInfo.Name.Name(), err) } - fmt.Fprintf(streams.Out(), "Finished initializing %q\n", repoInfo.Name.Name()) + fmt.Fprintf(ioStreams.Out(), "Finished initializing %q\n", repoInfo.Name.Name()) err = repo.AddTarget(target, data.CanonicalTargetsRole) case nil: // already initialized and we have successfully downloaded the latest metadata @@ -150,7 +150,7 @@ func PushTrustedReference(streams command.Streams, repoInfo *registry.Repository return trust.NotaryError(repoInfo.Name.Name(), err) } - fmt.Fprintf(streams.Out(), "Successfully signed %s:%s\n", repoInfo.Name.Name(), tag) + fmt.Fprintf(ioStreams.Out(), "Successfully signed %s:%s\n", repoInfo.Name.Name(), tag) return nil } diff --git a/cli/command/manifest/annotate_test.go b/cli/command/manifest/annotate_test.go index 1c6a4ace3d..5e95d1c7f1 100644 --- a/cli/command/manifest/annotate_test.go +++ b/cli/command/manifest/annotate_test.go @@ -40,13 +40,13 @@ func TestManifestAnnotateError(t *testing.T) { } func TestManifestAnnotate(t *testing.T) { - store := store.NewStore(t.TempDir()) + manifestStore := store.NewStore(t.TempDir()) cli := test.NewFakeCli(nil) - cli.SetManifestStore(store) + cli.SetManifestStore(manifestStore) namedRef := ref(t, "alpine:3.0") imageManifest := fullImageManifest(t, namedRef) - err := store.Save(ref(t, "list:v1"), namedRef, imageManifest) + err := manifestStore.Save(ref(t, "list:v1"), namedRef, imageManifest) assert.NilError(t, err) cmd := newAnnotateCommand(cli) diff --git a/cli/command/manifest/create_test.go b/cli/command/manifest/create_test.go index 833f616f14..71fe6c63e9 100644 --- a/cli/command/manifest/create_test.go +++ b/cli/command/manifest/create_test.go @@ -41,18 +41,18 @@ func TestManifestCreateErrors(t *testing.T) { // create a manifest list, then overwrite it, and inspect to see if the old one is still there func TestManifestCreateAmend(t *testing.T) { - store := store.NewStore(t.TempDir()) + manifestStore := store.NewStore(t.TempDir()) cli := test.NewFakeCli(nil) - cli.SetManifestStore(store) + cli.SetManifestStore(manifestStore) namedRef := ref(t, "alpine:3.0") imageManifest := fullImageManifest(t, namedRef) - err := store.Save(ref(t, "list:v1"), namedRef, imageManifest) + err := manifestStore.Save(ref(t, "list:v1"), namedRef, imageManifest) assert.NilError(t, err) namedRef = ref(t, "alpine:3.1") imageManifest = fullImageManifest(t, namedRef) - err = store.Save(ref(t, "list:v1"), namedRef, imageManifest) + err = manifestStore.Save(ref(t, "list:v1"), namedRef, imageManifest) assert.NilError(t, err) cmd := newCreateListCommand(cli) @@ -64,7 +64,7 @@ func TestManifestCreateAmend(t *testing.T) { // make a new cli to clear the buffers cli = test.NewFakeCli(nil) - cli.SetManifestStore(store) + cli.SetManifestStore(manifestStore) inspectCmd := newInspectCommand(cli) inspectCmd.SetArgs([]string{"example.com/list:v1"}) assert.NilError(t, inspectCmd.Execute()) @@ -75,13 +75,13 @@ func TestManifestCreateAmend(t *testing.T) { // attempt to overwrite a saved manifest and get refused func TestManifestCreateRefuseAmend(t *testing.T) { - store := store.NewStore(t.TempDir()) + manifestStore := store.NewStore(t.TempDir()) cli := test.NewFakeCli(nil) - cli.SetManifestStore(store) + cli.SetManifestStore(manifestStore) namedRef := ref(t, "alpine:3.0") imageManifest := fullImageManifest(t, namedRef) - err := store.Save(ref(t, "list:v1"), namedRef, imageManifest) + err := manifestStore.Save(ref(t, "list:v1"), namedRef, imageManifest) assert.NilError(t, err) cmd := newCreateListCommand(cli) @@ -93,10 +93,10 @@ func TestManifestCreateRefuseAmend(t *testing.T) { // attempt to make a manifest list without valid images func TestManifestCreateNoManifest(t *testing.T) { - store := store.NewStore(t.TempDir()) + manifestStore := store.NewStore(t.TempDir()) cli := test.NewFakeCli(nil) - cli.SetManifestStore(store) + cli.SetManifestStore(manifestStore) cli.SetRegistryClient(&fakeRegistryClient{ getManifestFunc: func(_ context.Context, ref reference.Named) (manifesttypes.ImageManifest, error) { return manifesttypes.ImageManifest{}, errors.Errorf("No such image: %v", ref) diff --git a/cli/command/manifest/rm_test.go b/cli/command/manifest/rm_test.go index d76f85a507..b360c0d8bb 100644 --- a/cli/command/manifest/rm_test.go +++ b/cli/command/manifest/rm_test.go @@ -11,22 +11,22 @@ import ( // create two manifest lists and remove them both func TestRmSeveralManifests(t *testing.T) { - store := store.NewStore(t.TempDir()) + manifestStore := store.NewStore(t.TempDir()) cli := test.NewFakeCli(nil) - cli.SetManifestStore(store) + cli.SetManifestStore(manifestStore) list1 := ref(t, "first:1") namedRef := ref(t, "alpine:3.0") - err := store.Save(list1, namedRef, fullImageManifest(t, namedRef)) + err := manifestStore.Save(list1, namedRef, fullImageManifest(t, namedRef)) assert.NilError(t, err) namedRef = ref(t, "alpine:3.1") - err = store.Save(list1, namedRef, fullImageManifest(t, namedRef)) + err = manifestStore.Save(list1, namedRef, fullImageManifest(t, namedRef)) assert.NilError(t, err) list2 := ref(t, "second:2") namedRef = ref(t, "alpine:3.2") - err = store.Save(list2, namedRef, fullImageManifest(t, namedRef)) + err = manifestStore.Save(list2, namedRef, fullImageManifest(t, namedRef)) assert.NilError(t, err) cmd := newRmManifestListCommand(cli) @@ -43,14 +43,14 @@ func TestRmSeveralManifests(t *testing.T) { // attempt to remove a manifest list which was never created func TestRmManifestNotCreated(t *testing.T) { - store := store.NewStore(t.TempDir()) + manifestStore := store.NewStore(t.TempDir()) cli := test.NewFakeCli(nil) - cli.SetManifestStore(store) + cli.SetManifestStore(manifestStore) list2 := ref(t, "second:2") namedRef := ref(t, "alpine:3.2") - err := store.Save(list2, namedRef, fullImageManifest(t, namedRef)) + err := manifestStore.Save(list2, namedRef, fullImageManifest(t, namedRef)) assert.NilError(t, err) cmd := newRmManifestListCommand(cli) diff --git a/cli/command/network/connect.go b/cli/command/network/connect.go index 75e3c0b4c8..872608c1b1 100644 --- a/cli/command/network/connect.go +++ b/cli/command/network/connect.go @@ -78,9 +78,9 @@ func runConnect(dockerCli command.Cli, options connectOptions) error { return client.NetworkConnect(context.Background(), options.network, options.container, epConfig) } -func convertDriverOpt(opts []string) (map[string]string, error) { +func convertDriverOpt(options []string) (map[string]string, error) { driverOpt := make(map[string]string) - for _, opt := range opts { + for _, opt := range options { k, v, ok := strings.Cut(opt, "=") // TODO(thaJeztah): we should probably not accept whitespace here (both for key and value). k = strings.TrimSpace(k) diff --git a/cli/command/service/formatter.go b/cli/command/service/formatter.go index 0dc02d3522..3a7ae004c6 100644 --- a/cli/command/service/formatter.go +++ b/cli/command/service/formatter.go @@ -346,13 +346,13 @@ func (ctx *serviceInspectContext) TaskPlacementPreferences() []string { if ctx.Service.Spec.TaskTemplate.Placement == nil { return nil } - var strings []string + var out []string for _, pref := range ctx.Service.Spec.TaskTemplate.Placement.Preferences { if pref.Spread != nil { - strings = append(strings, "spread="+pref.Spread.SpreadDescriptor) + out = append(out, "spread="+pref.Spread.SpreadDescriptor) } } - return strings + return out } func (ctx *serviceInspectContext) MaxReplicas() uint64 { diff --git a/cli/command/service/list.go b/cli/command/service/list.go index 3bca98b70e..444b894779 100644 --- a/cli/command/service/list.go +++ b/cli/command/service/list.go @@ -22,7 +22,7 @@ type listOptions struct { filter opts.FilterOpt } -func newListCommand(dockerCli command.Cli) *cobra.Command { +func newListCommand(dockerCLI command.Cli) *cobra.Command { options := listOptions{filter: opts.NewFilterOpt()} cmd := &cobra.Command{ @@ -31,7 +31,7 @@ func newListCommand(dockerCli command.Cli) *cobra.Command { Short: "List services", Args: cli.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { - return runList(dockerCli, options) + return runList(dockerCLI, options) }, ValidArgsFunction: completion.NoComplete, } @@ -44,20 +44,20 @@ func newListCommand(dockerCli command.Cli) *cobra.Command { return cmd } -func runList(dockerCli command.Cli, opts listOptions) error { +func runList(dockerCLI command.Cli, options listOptions) error { var ( - apiClient = dockerCli.Client() + apiClient = dockerCLI.Client() ctx = context.Background() err error ) listOpts := types.ServiceListOptions{ - Filters: opts.filter.Value(), + Filters: options.filter.Value(), // When not running "quiet", also get service status (number of running // and desired tasks). Note that this is only supported on API v1.41 and // up; older API versions ignore this option, and we will have to collect // the information manually below. - Status: !opts.quiet, + Status: !options.quiet, } services, err := apiClient.ServiceList(ctx, listOpts) @@ -84,18 +84,18 @@ func runList(dockerCli command.Cli, opts listOptions) error { } } - format := opts.format + format := options.format if len(format) == 0 { - if len(dockerCli.ConfigFile().ServicesFormat) > 0 && !opts.quiet { - format = dockerCli.ConfigFile().ServicesFormat + if len(dockerCLI.ConfigFile().ServicesFormat) > 0 && !options.quiet { + format = dockerCLI.ConfigFile().ServicesFormat } else { format = formatter.TableFormatKey } } servicesCtx := formatter.Context{ - Output: dockerCli.Out(), - Format: NewListFormat(format, opts.quiet), + Output: dockerCLI.Out(), + Format: NewListFormat(format, options.quiet), } return ListFormatWrite(servicesCtx, services) } diff --git a/cli/command/service/logs.go b/cli/command/service/logs.go index aef5f71d1a..cb3471244a 100644 --- a/cli/command/service/logs.go +++ b/cli/command/service/logs.go @@ -181,12 +181,12 @@ type taskFormatter struct { cache map[logContext]string } -func newTaskFormatter(client client.APIClient, opts *logsOptions, padding int) *taskFormatter { +func newTaskFormatter(apiClient client.APIClient, opts *logsOptions, padding int) *taskFormatter { return &taskFormatter{ - client: client, + client: apiClient, opts: opts, padding: padding, - r: idresolver.New(client, opts.noResolve), + r: idresolver.New(apiClient, opts.noResolve), cache: make(map[logContext]string), } } diff --git a/cli/command/service/opts.go b/cli/command/service/opts.go index d36afa5ef1..09dff46ef4 100644 --- a/cli/command/service/opts.go +++ b/cli/command/service/opts.go @@ -82,17 +82,17 @@ type placementPrefOpts struct { strings []string } -func (opts *placementPrefOpts) String() string { - if len(opts.strings) == 0 { +func (o *placementPrefOpts) String() string { + if len(o.strings) == 0 { return "" } - return fmt.Sprintf("%v", opts.strings) + return fmt.Sprintf("%v", o.strings) } // Set validates the input value and adds it to the internal slices. // Note: in the future strategies other than "spread", may be supported, // as well as additional comma-separated options. -func (opts *placementPrefOpts) Set(value string) error { +func (o *placementPrefOpts) Set(value string) error { strategy, arg, ok := strings.Cut(value, "=") if !ok || strategy == "" { return errors.New(`placement preference must be of the format "="`) @@ -101,17 +101,17 @@ func (opts *placementPrefOpts) Set(value string) error { return errors.Errorf("unsupported placement preference %s (only spread is supported)", strategy) } - opts.prefs = append(opts.prefs, swarm.PlacementPreference{ + o.prefs = append(o.prefs, swarm.PlacementPreference{ Spread: &swarm.SpreadOver{ SpreadDescriptor: arg, }, }) - opts.strings = append(opts.strings, value) + o.strings = append(o.strings, value) return nil } // Type returns a string name for this Option type -func (opts *placementPrefOpts) Type() string { +func (o *placementPrefOpts) Type() string { return "pref" } @@ -167,7 +167,7 @@ func updateConfigFromDefaults(defaultUpdateConfig *api.UpdateConfig) *swarm.Upda } } -func (opts updateOptions) updateConfig(flags *pflag.FlagSet) *swarm.UpdateConfig { +func (o updateOptions) updateConfig(flags *pflag.FlagSet) *swarm.UpdateConfig { if !anyChanged(flags, flagUpdateParallelism, flagUpdateDelay, flagUpdateMonitor, flagUpdateFailureAction, flagUpdateMaxFailureRatio, flagUpdateOrder) { return nil } @@ -175,28 +175,28 @@ func (opts updateOptions) updateConfig(flags *pflag.FlagSet) *swarm.UpdateConfig updateConfig := updateConfigFromDefaults(defaults.Service.Update) if flags.Changed(flagUpdateParallelism) { - updateConfig.Parallelism = opts.parallelism + updateConfig.Parallelism = o.parallelism } if flags.Changed(flagUpdateDelay) { - updateConfig.Delay = opts.delay + updateConfig.Delay = o.delay } if flags.Changed(flagUpdateMonitor) { - updateConfig.Monitor = opts.monitor + updateConfig.Monitor = o.monitor } if flags.Changed(flagUpdateFailureAction) { - updateConfig.FailureAction = opts.onFailure + updateConfig.FailureAction = o.onFailure } if flags.Changed(flagUpdateMaxFailureRatio) { - updateConfig.MaxFailureRatio = opts.maxFailureRatio.Value() + updateConfig.MaxFailureRatio = o.maxFailureRatio.Value() } if flags.Changed(flagUpdateOrder) { - updateConfig.Order = opts.order + updateConfig.Order = o.order } return updateConfig } -func (opts updateOptions) rollbackConfig(flags *pflag.FlagSet) *swarm.UpdateConfig { +func (o updateOptions) rollbackConfig(flags *pflag.FlagSet) *swarm.UpdateConfig { if !anyChanged(flags, flagRollbackParallelism, flagRollbackDelay, flagRollbackMonitor, flagRollbackFailureAction, flagRollbackMaxFailureRatio, flagRollbackOrder) { return nil } @@ -204,22 +204,22 @@ func (opts updateOptions) rollbackConfig(flags *pflag.FlagSet) *swarm.UpdateConf updateConfig := updateConfigFromDefaults(defaults.Service.Rollback) if flags.Changed(flagRollbackParallelism) { - updateConfig.Parallelism = opts.parallelism + updateConfig.Parallelism = o.parallelism } if flags.Changed(flagRollbackDelay) { - updateConfig.Delay = opts.delay + updateConfig.Delay = o.delay } if flags.Changed(flagRollbackMonitor) { - updateConfig.Monitor = opts.monitor + updateConfig.Monitor = o.monitor } if flags.Changed(flagRollbackFailureAction) { - updateConfig.FailureAction = opts.onFailure + updateConfig.FailureAction = o.onFailure } if flags.Changed(flagRollbackMaxFailureRatio) { - updateConfig.MaxFailureRatio = opts.maxFailureRatio.Value() + updateConfig.MaxFailureRatio = o.maxFailureRatio.Value() } if flags.Changed(flagRollbackOrder) { - updateConfig.Order = opts.order + updateConfig.Order = o.order } return updateConfig @@ -433,42 +433,42 @@ type healthCheckOptions struct { noHealthcheck bool } -func (opts *healthCheckOptions) toHealthConfig() (*container.HealthConfig, error) { +func (o *healthCheckOptions) toHealthConfig() (*container.HealthConfig, error) { var healthConfig *container.HealthConfig - haveHealthSettings := opts.cmd != "" || - opts.interval.Value() != nil || - opts.timeout.Value() != nil || - opts.startPeriod.Value() != nil || - opts.startInterval.Value() != nil || - opts.retries != 0 - if opts.noHealthcheck { + haveHealthSettings := o.cmd != "" || + o.interval.Value() != nil || + o.timeout.Value() != nil || + o.startPeriod.Value() != nil || + o.startInterval.Value() != nil || + o.retries != 0 + if o.noHealthcheck { if haveHealthSettings { return nil, errors.Errorf("--%s conflicts with --health-* options", flagNoHealthcheck) } healthConfig = &container.HealthConfig{Test: []string{"NONE"}} } else if haveHealthSettings { var test []string - if opts.cmd != "" { - test = []string{"CMD-SHELL", opts.cmd} + if o.cmd != "" { + test = []string{"CMD-SHELL", o.cmd} } var interval, timeout, startPeriod, startInterval time.Duration - if ptr := opts.interval.Value(); ptr != nil { + if ptr := o.interval.Value(); ptr != nil { interval = *ptr } - if ptr := opts.timeout.Value(); ptr != nil { + if ptr := o.timeout.Value(); ptr != nil { timeout = *ptr } - if ptr := opts.startPeriod.Value(); ptr != nil { + if ptr := o.startPeriod.Value(); ptr != nil { startPeriod = *ptr } - if ptr := opts.startInterval.Value(); ptr != nil { + if ptr := o.startInterval.Value(); ptr != nil { startInterval = *ptr } healthConfig = &container.HealthConfig{ Test: test, Interval: interval, Timeout: timeout, - Retries: opts.retries, + Retries: o.retries, StartPeriod: startPeriod, StartInterval: startInterval, } @@ -828,7 +828,7 @@ func addDetachFlag(flags *pflag.FlagSet, detach *bool) { // addServiceFlags adds all flags that are common to both `create` and `update`. // Any flags that are not common are added separately in the individual command -func addServiceFlags(flags *pflag.FlagSet, opts *serviceOptions, defaultFlagValues flagDefaults) { +func addServiceFlags(flags *pflag.FlagSet, options *serviceOptions, defaultFlagValues flagDefaults) { flagDesc := func(flagName string, desc string) string { if defaultValue, ok := defaultFlagValues[flagName]; ok { return fmt.Sprintf("%s (default %v)", desc, defaultValue) @@ -836,98 +836,98 @@ func addServiceFlags(flags *pflag.FlagSet, opts *serviceOptions, defaultFlagValu return desc } - addDetachFlag(flags, &opts.detach) - flags.BoolVarP(&opts.quiet, flagQuiet, "q", false, "Suppress progress output") + addDetachFlag(flags, &options.detach) + flags.BoolVarP(&options.quiet, flagQuiet, "q", false, "Suppress progress output") - flags.StringVarP(&opts.workdir, flagWorkdir, "w", "", "Working directory inside the container") - flags.StringVarP(&opts.user, flagUser, "u", "", "Username or UID (format: [:])") - flags.Var(&opts.credentialSpec, flagCredentialSpec, "Credential spec for managed service account (Windows only)") + flags.StringVarP(&options.workdir, flagWorkdir, "w", "", "Working directory inside the container") + flags.StringVarP(&options.user, flagUser, "u", "", "Username or UID (format: [:])") + flags.Var(&options.credentialSpec, flagCredentialSpec, "Credential spec for managed service account (Windows only)") flags.SetAnnotation(flagCredentialSpec, "version", []string{"1.29"}) - flags.StringVar(&opts.hostname, flagHostname, "", "Container hostname") + flags.StringVar(&options.hostname, flagHostname, "", "Container hostname") flags.SetAnnotation(flagHostname, "version", []string{"1.25"}) - flags.Var(&opts.entrypoint, flagEntrypoint, "Overwrite the default ENTRYPOINT of the image") - flags.Var(&opts.capAdd, flagCapAdd, "Add Linux capabilities") + flags.Var(&options.entrypoint, flagEntrypoint, "Overwrite the default ENTRYPOINT of the image") + flags.Var(&options.capAdd, flagCapAdd, "Add Linux capabilities") flags.SetAnnotation(flagCapAdd, "version", []string{"1.41"}) - flags.Var(&opts.capDrop, flagCapDrop, "Drop Linux capabilities") + flags.Var(&options.capDrop, flagCapDrop, "Drop Linux capabilities") flags.SetAnnotation(flagCapDrop, "version", []string{"1.41"}) - flags.Var(&opts.resources.limitCPU, flagLimitCPU, "Limit CPUs") - flags.Var(&opts.resources.limitMemBytes, flagLimitMemory, "Limit Memory") - flags.Var(&opts.resources.resCPU, flagReserveCPU, "Reserve CPUs") - flags.Var(&opts.resources.resMemBytes, flagReserveMemory, "Reserve Memory") - flags.Int64Var(&opts.resources.limitPids, flagLimitPids, 0, "Limit maximum number of processes (default 0 = unlimited)") + flags.Var(&options.resources.limitCPU, flagLimitCPU, "Limit CPUs") + flags.Var(&options.resources.limitMemBytes, flagLimitMemory, "Limit Memory") + flags.Var(&options.resources.resCPU, flagReserveCPU, "Reserve CPUs") + flags.Var(&options.resources.resMemBytes, flagReserveMemory, "Reserve Memory") + flags.Int64Var(&options.resources.limitPids, flagLimitPids, 0, "Limit maximum number of processes (default 0 = unlimited)") flags.SetAnnotation(flagLimitPids, "version", []string{"1.41"}) - flags.Var(&opts.stopGrace, flagStopGracePeriod, flagDesc(flagStopGracePeriod, "Time to wait before force killing a container (ns|us|ms|s|m|h)")) - flags.Var(&opts.replicas, flagReplicas, "Number of tasks") - flags.Var(&opts.maxConcurrent, flagConcurrent, "Number of job tasks to run concurrently (default equal to --replicas)") + flags.Var(&options.stopGrace, flagStopGracePeriod, flagDesc(flagStopGracePeriod, "Time to wait before force killing a container (ns|us|ms|s|m|h)")) + flags.Var(&options.replicas, flagReplicas, "Number of tasks") + flags.Var(&options.maxConcurrent, flagConcurrent, "Number of job tasks to run concurrently (default equal to --replicas)") flags.SetAnnotation(flagConcurrent, "version", []string{"1.41"}) - flags.Uint64Var(&opts.maxReplicas, flagMaxReplicas, defaultFlagValues.getUint64(flagMaxReplicas), "Maximum number of tasks per node (default 0 = unlimited)") + flags.Uint64Var(&options.maxReplicas, flagMaxReplicas, defaultFlagValues.getUint64(flagMaxReplicas), "Maximum number of tasks per node (default 0 = unlimited)") flags.SetAnnotation(flagMaxReplicas, "version", []string{"1.40"}) - flags.StringVar(&opts.restartPolicy.condition, flagRestartCondition, "", flagDesc(flagRestartCondition, `Restart when condition is met ("none", "on-failure", "any")`)) - flags.Var(&opts.restartPolicy.delay, flagRestartDelay, flagDesc(flagRestartDelay, "Delay between restart attempts (ns|us|ms|s|m|h)")) - flags.Var(&opts.restartPolicy.maxAttempts, flagRestartMaxAttempts, flagDesc(flagRestartMaxAttempts, "Maximum number of restarts before giving up")) + flags.StringVar(&options.restartPolicy.condition, flagRestartCondition, "", flagDesc(flagRestartCondition, `Restart when condition is met ("none", "on-failure", "any")`)) + flags.Var(&options.restartPolicy.delay, flagRestartDelay, flagDesc(flagRestartDelay, "Delay between restart attempts (ns|us|ms|s|m|h)")) + flags.Var(&options.restartPolicy.maxAttempts, flagRestartMaxAttempts, flagDesc(flagRestartMaxAttempts, "Maximum number of restarts before giving up")) - flags.Var(&opts.restartPolicy.window, flagRestartWindow, flagDesc(flagRestartWindow, "Window used to evaluate the restart policy (ns|us|ms|s|m|h)")) + flags.Var(&options.restartPolicy.window, flagRestartWindow, flagDesc(flagRestartWindow, "Window used to evaluate the restart policy (ns|us|ms|s|m|h)")) - flags.Uint64Var(&opts.update.parallelism, flagUpdateParallelism, defaultFlagValues.getUint64(flagUpdateParallelism), "Maximum number of tasks updated simultaneously (0 to update all at once)") - flags.DurationVar(&opts.update.delay, flagUpdateDelay, 0, flagDesc(flagUpdateDelay, "Delay between updates (ns|us|ms|s|m|h)")) - flags.DurationVar(&opts.update.monitor, flagUpdateMonitor, 0, flagDesc(flagUpdateMonitor, "Duration after each task update to monitor for failure (ns|us|ms|s|m|h)")) + flags.Uint64Var(&options.update.parallelism, flagUpdateParallelism, defaultFlagValues.getUint64(flagUpdateParallelism), "Maximum number of tasks updated simultaneously (0 to update all at once)") + flags.DurationVar(&options.update.delay, flagUpdateDelay, 0, flagDesc(flagUpdateDelay, "Delay between updates (ns|us|ms|s|m|h)")) + flags.DurationVar(&options.update.monitor, flagUpdateMonitor, 0, flagDesc(flagUpdateMonitor, "Duration after each task update to monitor for failure (ns|us|ms|s|m|h)")) flags.SetAnnotation(flagUpdateMonitor, "version", []string{"1.25"}) - flags.StringVar(&opts.update.onFailure, flagUpdateFailureAction, "", flagDesc(flagUpdateFailureAction, `Action on update failure ("pause", "continue", "rollback")`)) - flags.Var(&opts.update.maxFailureRatio, flagUpdateMaxFailureRatio, flagDesc(flagUpdateMaxFailureRatio, "Failure rate to tolerate during an update")) + flags.StringVar(&options.update.onFailure, flagUpdateFailureAction, "", flagDesc(flagUpdateFailureAction, `Action on update failure ("pause", "continue", "rollback")`)) + flags.Var(&options.update.maxFailureRatio, flagUpdateMaxFailureRatio, flagDesc(flagUpdateMaxFailureRatio, "Failure rate to tolerate during an update")) flags.SetAnnotation(flagUpdateMaxFailureRatio, "version", []string{"1.25"}) - flags.StringVar(&opts.update.order, flagUpdateOrder, "", flagDesc(flagUpdateOrder, `Update order ("start-first", "stop-first")`)) + flags.StringVar(&options.update.order, flagUpdateOrder, "", flagDesc(flagUpdateOrder, `Update order ("start-first", "stop-first")`)) flags.SetAnnotation(flagUpdateOrder, "version", []string{"1.29"}) - flags.Uint64Var(&opts.rollback.parallelism, flagRollbackParallelism, defaultFlagValues.getUint64(flagRollbackParallelism), + flags.Uint64Var(&options.rollback.parallelism, flagRollbackParallelism, defaultFlagValues.getUint64(flagRollbackParallelism), "Maximum number of tasks rolled back simultaneously (0 to roll back all at once)") flags.SetAnnotation(flagRollbackParallelism, "version", []string{"1.28"}) - flags.DurationVar(&opts.rollback.delay, flagRollbackDelay, 0, flagDesc(flagRollbackDelay, "Delay between task rollbacks (ns|us|ms|s|m|h)")) + flags.DurationVar(&options.rollback.delay, flagRollbackDelay, 0, flagDesc(flagRollbackDelay, "Delay between task rollbacks (ns|us|ms|s|m|h)")) flags.SetAnnotation(flagRollbackDelay, "version", []string{"1.28"}) - flags.DurationVar(&opts.rollback.monitor, flagRollbackMonitor, 0, flagDesc(flagRollbackMonitor, "Duration after each task rollback to monitor for failure (ns|us|ms|s|m|h)")) + flags.DurationVar(&options.rollback.monitor, flagRollbackMonitor, 0, flagDesc(flagRollbackMonitor, "Duration after each task rollback to monitor for failure (ns|us|ms|s|m|h)")) flags.SetAnnotation(flagRollbackMonitor, "version", []string{"1.28"}) - flags.StringVar(&opts.rollback.onFailure, flagRollbackFailureAction, "", flagDesc(flagRollbackFailureAction, `Action on rollback failure ("pause", "continue")`)) + flags.StringVar(&options.rollback.onFailure, flagRollbackFailureAction, "", flagDesc(flagRollbackFailureAction, `Action on rollback failure ("pause", "continue")`)) flags.SetAnnotation(flagRollbackFailureAction, "version", []string{"1.28"}) - flags.Var(&opts.rollback.maxFailureRatio, flagRollbackMaxFailureRatio, flagDesc(flagRollbackMaxFailureRatio, "Failure rate to tolerate during a rollback")) + flags.Var(&options.rollback.maxFailureRatio, flagRollbackMaxFailureRatio, flagDesc(flagRollbackMaxFailureRatio, "Failure rate to tolerate during a rollback")) flags.SetAnnotation(flagRollbackMaxFailureRatio, "version", []string{"1.28"}) - flags.StringVar(&opts.rollback.order, flagRollbackOrder, "", flagDesc(flagRollbackOrder, `Rollback order ("start-first", "stop-first")`)) + flags.StringVar(&options.rollback.order, flagRollbackOrder, "", flagDesc(flagRollbackOrder, `Rollback order ("start-first", "stop-first")`)) flags.SetAnnotation(flagRollbackOrder, "version", []string{"1.29"}) - flags.StringVar(&opts.endpoint.mode, flagEndpointMode, defaultFlagValues.getString(flagEndpointMode), "Endpoint mode (vip or dnsrr)") + flags.StringVar(&options.endpoint.mode, flagEndpointMode, defaultFlagValues.getString(flagEndpointMode), "Endpoint mode (vip or dnsrr)") - flags.BoolVar(&opts.registryAuth, flagRegistryAuth, false, "Send registry authentication details to swarm agents") - flags.BoolVar(&opts.noResolveImage, flagNoResolveImage, false, "Do not query the registry to resolve image digest and supported platforms") + flags.BoolVar(&options.registryAuth, flagRegistryAuth, false, "Send registry authentication details to swarm agents") + flags.BoolVar(&options.noResolveImage, flagNoResolveImage, false, "Do not query the registry to resolve image digest and supported platforms") flags.SetAnnotation(flagNoResolveImage, "version", []string{"1.30"}) - flags.StringVar(&opts.logDriver.name, flagLogDriver, "", "Logging driver for service") - flags.Var(&opts.logDriver.opts, flagLogOpt, "Logging driver options") + flags.StringVar(&options.logDriver.name, flagLogDriver, "", "Logging driver for service") + flags.Var(&options.logDriver.opts, flagLogOpt, "Logging driver options") - flags.StringVar(&opts.healthcheck.cmd, flagHealthCmd, "", "Command to run to check health") + flags.StringVar(&options.healthcheck.cmd, flagHealthCmd, "", "Command to run to check health") flags.SetAnnotation(flagHealthCmd, "version", []string{"1.25"}) - flags.Var(&opts.healthcheck.interval, flagHealthInterval, "Time between running the check (ms|s|m|h)") + flags.Var(&options.healthcheck.interval, flagHealthInterval, "Time between running the check (ms|s|m|h)") flags.SetAnnotation(flagHealthInterval, "version", []string{"1.25"}) - flags.Var(&opts.healthcheck.timeout, flagHealthTimeout, "Maximum time to allow one check to run (ms|s|m|h)") + flags.Var(&options.healthcheck.timeout, flagHealthTimeout, "Maximum time to allow one check to run (ms|s|m|h)") flags.SetAnnotation(flagHealthTimeout, "version", []string{"1.25"}) - flags.IntVar(&opts.healthcheck.retries, flagHealthRetries, 0, "Consecutive failures needed to report unhealthy") + flags.IntVar(&options.healthcheck.retries, flagHealthRetries, 0, "Consecutive failures needed to report unhealthy") flags.SetAnnotation(flagHealthRetries, "version", []string{"1.25"}) - flags.Var(&opts.healthcheck.startPeriod, flagHealthStartPeriod, "Start period for the container to initialize before counting retries towards unstable (ms|s|m|h)") + flags.Var(&options.healthcheck.startPeriod, flagHealthStartPeriod, "Start period for the container to initialize before counting retries towards unstable (ms|s|m|h)") flags.SetAnnotation(flagHealthStartPeriod, "version", []string{"1.29"}) - flags.Var(&opts.healthcheck.startInterval, flagHealthStartInterval, "Time between running the check during the start period (ms|s|m|h)") + flags.Var(&options.healthcheck.startInterval, flagHealthStartInterval, "Time between running the check during the start period (ms|s|m|h)") flags.SetAnnotation(flagHealthStartInterval, "version", []string{"1.44"}) - flags.BoolVar(&opts.healthcheck.noHealthcheck, flagNoHealthcheck, false, "Disable any container-specified HEALTHCHECK") + flags.BoolVar(&options.healthcheck.noHealthcheck, flagNoHealthcheck, false, "Disable any container-specified HEALTHCHECK") flags.SetAnnotation(flagNoHealthcheck, "version", []string{"1.25"}) - flags.BoolVarP(&opts.tty, flagTTY, "t", false, "Allocate a pseudo-TTY") + flags.BoolVarP(&options.tty, flagTTY, "t", false, "Allocate a pseudo-TTY") flags.SetAnnotation(flagTTY, "version", []string{"1.25"}) - flags.BoolVar(&opts.readOnly, flagReadOnly, false, "Mount the container's root filesystem as read only") + flags.BoolVar(&options.readOnly, flagReadOnly, false, "Mount the container's root filesystem as read only") flags.SetAnnotation(flagReadOnly, "version", []string{"1.28"}) - flags.StringVar(&opts.stopSignal, flagStopSignal, "", "Signal to stop the container") + flags.StringVar(&options.stopSignal, flagStopSignal, "", "Signal to stop the container") flags.SetAnnotation(flagStopSignal, "version", []string{"1.28"}) - flags.StringVar(&opts.isolation, flagIsolation, "", "Service container isolation mode") + flags.StringVar(&options.isolation, flagIsolation, "", "Service container isolation mode") flags.SetAnnotation(flagIsolation, "version", []string{"1.35"}) } diff --git a/cli/command/service/parse.go b/cli/command/service/parse.go index 56265e9545..4a1e2ed17b 100644 --- a/cli/command/service/parse.go +++ b/cli/command/service/parse.go @@ -12,7 +12,7 @@ import ( // ParseSecrets retrieves the secrets with the requested names and fills // secret IDs into the secret references. -func ParseSecrets(client client.SecretAPIClient, requestedSecrets []*swarmtypes.SecretReference) ([]*swarmtypes.SecretReference, error) { +func ParseSecrets(apiClient client.SecretAPIClient, requestedSecrets []*swarmtypes.SecretReference) ([]*swarmtypes.SecretReference, error) { if len(requestedSecrets) == 0 { return []*swarmtypes.SecretReference{}, nil } @@ -34,7 +34,7 @@ func ParseSecrets(client client.SecretAPIClient, requestedSecrets []*swarmtypes. args.Add("name", s.SecretName) } - secrets, err := client.SecretList(ctx, types.SecretListOptions{ + secrets, err := apiClient.SecretList(ctx, types.SecretListOptions{ Filters: args, }) if err != nil { @@ -65,7 +65,7 @@ func ParseSecrets(client client.SecretAPIClient, requestedSecrets []*swarmtypes. // ParseConfigs retrieves the configs from the requested names and converts // them to config references to use with the spec -func ParseConfigs(client client.ConfigAPIClient, requestedConfigs []*swarmtypes.ConfigReference) ([]*swarmtypes.ConfigReference, error) { +func ParseConfigs(apiClient client.ConfigAPIClient, requestedConfigs []*swarmtypes.ConfigReference) ([]*swarmtypes.ConfigReference, error) { if len(requestedConfigs) == 0 { return []*swarmtypes.ConfigReference{}, nil } @@ -115,7 +115,7 @@ func ParseConfigs(client client.ConfigAPIClient, requestedConfigs []*swarmtypes. args.Add("name", s.ConfigName) } - configs, err := client.ConfigList(ctx, types.ConfigListOptions{ + configs, err := apiClient.ConfigList(ctx, types.ConfigListOptions{ Filters: args, }) if err != nil { diff --git a/cli/command/service/progress/progress.go b/cli/command/service/progress/progress.go index 61f347b8fb..3061f6503a 100644 --- a/cli/command/service/progress/progress.go +++ b/cli/command/service/progress/progress.go @@ -70,7 +70,7 @@ func terminalState(state swarm.TaskState) bool { // ServiceProgress outputs progress information for convergence of a service. // //nolint:gocyclo -func ServiceProgress(ctx context.Context, client client.APIClient, serviceID string, progressWriter io.WriteCloser) error { +func ServiceProgress(ctx context.Context, apiClient client.APIClient, serviceID string, progressWriter io.WriteCloser) error { defer progressWriter.Close() progressOut := streamformatter.NewJSONProgressOutput(progressWriter, false) @@ -84,7 +84,7 @@ func ServiceProgress(ctx context.Context, client client.APIClient, serviceID str taskFilter.Add("_up-to-date", "true") getUpToDateTasks := func() ([]swarm.Task, error) { - return client.TaskList(ctx, types.TaskListOptions{Filters: taskFilter}) + return apiClient.TaskList(ctx, types.TaskListOptions{Filters: taskFilter}) } var ( @@ -97,7 +97,7 @@ func ServiceProgress(ctx context.Context, client client.APIClient, serviceID str ) for { - service, _, err := client.ServiceInspectWithRaw(ctx, serviceID, types.ServiceInspectOptions{}) + service, _, err := apiClient.ServiceInspectWithRaw(ctx, serviceID, types.ServiceInspectOptions{}) if err != nil { return err } @@ -156,7 +156,7 @@ func ServiceProgress(ctx context.Context, client client.APIClient, serviceID str return err } - activeNodes, err := getActiveNodes(ctx, client) + activeNodes, err := getActiveNodes(ctx, apiClient) if err != nil { return err } @@ -218,8 +218,8 @@ func ServiceProgress(ctx context.Context, client client.APIClient, serviceID str } } -func getActiveNodes(ctx context.Context, client client.APIClient) (map[string]struct{}, error) { - nodes, err := client.NodeList(ctx, types.NodeListOptions{}) +func getActiveNodes(ctx context.Context, apiClient client.APIClient) (map[string]struct{}, error) { + nodes, err := apiClient.NodeList(ctx, types.NodeListOptions{}) if err != nil { return nil, err } diff --git a/cli/command/service/ps.go b/cli/command/service/ps.go index ce49fce1f5..8f1fed2891 100644 --- a/cli/command/service/ps.go +++ b/cli/command/service/ps.go @@ -52,18 +52,18 @@ func newPsCommand(dockerCli command.Cli) *cobra.Command { } func runPS(dockerCli command.Cli, options psOptions) error { - client := dockerCli.Client() + apiClient := dockerCli.Client() ctx := context.Background() - filter, notfound, err := createFilter(ctx, client, options) + filter, notfound, err := createFilter(ctx, apiClient, options) if err != nil { return err } - if err := updateNodeFilter(ctx, client, filter); err != nil { + if err := updateNodeFilter(ctx, apiClient, filter); err != nil { return err } - tasks, err := client.TaskList(ctx, types.TaskListOptions{Filters: filter}) + tasks, err := apiClient.TaskList(ctx, types.TaskListOptions{Filters: filter}) if err != nil { return err } @@ -75,7 +75,7 @@ func runPS(dockerCli command.Cli, options psOptions) error { if options.quiet { options.noTrunc = true } - if err := task.Print(ctx, dockerCli, tasks, idresolver.New(client, options.noResolve), !options.noTrunc, options.quiet, format); err != nil { + if err := task.Print(ctx, dockerCli, tasks, idresolver.New(apiClient, options.noResolve), !options.noTrunc, options.quiet, format); err != nil { return err } if len(notfound) != 0 { @@ -84,7 +84,7 @@ func runPS(dockerCli command.Cli, options psOptions) error { return nil } -func createFilter(ctx context.Context, client client.APIClient, options psOptions) (filters.Args, []string, error) { +func createFilter(ctx context.Context, apiClient client.APIClient, options psOptions) (filters.Args, []string, error) { filter := options.filter.Value() serviceIDFilter := filters.NewArgs() @@ -93,11 +93,11 @@ func createFilter(ctx context.Context, client client.APIClient, options psOption serviceIDFilter.Add("id", service) serviceNameFilter.Add("name", service) } - serviceByIDList, err := client.ServiceList(ctx, types.ServiceListOptions{Filters: serviceIDFilter}) + serviceByIDList, err := apiClient.ServiceList(ctx, types.ServiceListOptions{Filters: serviceIDFilter}) if err != nil { return filter, nil, err } - serviceByNameList, err := client.ServiceList(ctx, types.ServiceListOptions{Filters: serviceNameFilter}) + serviceByNameList, err := apiClient.ServiceList(ctx, types.ServiceListOptions{Filters: serviceNameFilter}) if err != nil { return filter, nil, err } @@ -142,11 +142,11 @@ loop: return filter, notfound, err } -func updateNodeFilter(ctx context.Context, client client.APIClient, filter filters.Args) error { +func updateNodeFilter(ctx context.Context, apiClient client.APIClient, filter filters.Args) error { if filter.Contains("node") { nodeFilters := filter.Get("node") for _, nodeFilter := range nodeFilters { - nodeReference, err := node.Reference(ctx, client, nodeFilter) + nodeReference, err := node.Reference(ctx, apiClient, nodeFilter) if err != nil { return err } diff --git a/cli/command/stack/client_test.go b/cli/command/stack/client_test.go index c3d5021b3d..4cb8a3b5db 100644 --- a/cli/command/stack/client_test.go +++ b/cli/command/stack/client_test.go @@ -224,8 +224,8 @@ func configFromName(name string) swarm.Config { } } -func namespaceFromFilters(filters filters.Args) string { - label := filters.Get("label")[0] +func namespaceFromFilters(fltrs filters.Args) string { + label := fltrs.Get("label")[0] return strings.TrimPrefix(label, convert.LabelNamespace+"=") } diff --git a/cli/command/stack/config.go b/cli/command/stack/config.go index 354c35625a..b63a719fc8 100644 --- a/cli/command/stack/config.go +++ b/cli/command/stack/config.go @@ -46,8 +46,8 @@ func newConfigCommand(dockerCli command.Cli) *cobra.Command { // outputConfig returns the merged and interpolated config file func outputConfig(configFiles composetypes.ConfigDetails, skipInterpolation bool) (string, error) { - optsFunc := func(options *composeLoader.Options) { - options.SkipInterpolation = skipInterpolation + optsFunc := func(opts *composeLoader.Options) { + opts.SkipInterpolation = skipInterpolation } config, err := composeLoader.Load(configFiles, optsFunc) if err != nil { diff --git a/cli/command/stack/swarm/client_test.go b/cli/command/stack/swarm/client_test.go index db72a0ffa3..afb93458f0 100644 --- a/cli/command/stack/swarm/client_test.go +++ b/cli/command/stack/swarm/client_test.go @@ -213,8 +213,8 @@ func configFromName(name string) swarm.Config { } } -func namespaceFromFilters(filters filters.Args) string { - label := filters.Get("label")[0] +func namespaceFromFilters(fltrs filters.Args) string { + label := fltrs.Get("label")[0] return strings.TrimPrefix(label, convert.LabelNamespace+"=") } diff --git a/cli/command/swarm/client_test.go b/cli/command/swarm/client_test.go index 67eeee175e..9e37db0e60 100644 --- a/cli/command/swarm/client_test.go +++ b/cli/command/swarm/client_test.go @@ -71,9 +71,9 @@ func (cli *fakeClient) SwarmLeave(context.Context, bool) error { return nil } -func (cli *fakeClient) SwarmUpdate(_ context.Context, _ swarm.Version, swarm swarm.Spec, flags swarm.UpdateFlags) error { +func (cli *fakeClient) SwarmUpdate(_ context.Context, _ swarm.Version, swarmSpec swarm.Spec, flags swarm.UpdateFlags) error { if cli.swarmUpdateFunc != nil { - return cli.swarmUpdateFunc(swarm, flags) + return cli.swarmUpdateFunc(swarmSpec, flags) } return nil } diff --git a/cli/command/swarm/opts.go b/cli/command/swarm/opts.go index acbadf9d0e..f8ebc900e8 100644 --- a/cli/command/swarm/opts.go +++ b/cli/command/swarm/opts.go @@ -216,38 +216,38 @@ func parseExternalCA(caSpec string) (*swarm.ExternalCA, error) { return &externalCA, nil } -func addSwarmCAFlags(flags *pflag.FlagSet, opts *swarmCAOptions) { - flags.DurationVar(&opts.nodeCertExpiry, flagCertExpiry, 90*24*time.Hour, "Validity period for node certificates (ns|us|ms|s|m|h)") - flags.Var(&opts.externalCA, flagExternalCA, "Specifications of one or more certificate signing endpoints") +func addSwarmCAFlags(flags *pflag.FlagSet, options *swarmCAOptions) { + flags.DurationVar(&options.nodeCertExpiry, flagCertExpiry, 90*24*time.Hour, "Validity period for node certificates (ns|us|ms|s|m|h)") + flags.Var(&options.externalCA, flagExternalCA, "Specifications of one or more certificate signing endpoints") } -func addSwarmFlags(flags *pflag.FlagSet, opts *swarmOptions) { - flags.Int64Var(&opts.taskHistoryLimit, flagTaskHistoryLimit, 5, "Task history retention limit") - flags.DurationVar(&opts.dispatcherHeartbeat, flagDispatcherHeartbeat, 5*time.Second, "Dispatcher heartbeat period (ns|us|ms|s|m|h)") - flags.Uint64Var(&opts.maxSnapshots, flagMaxSnapshots, 0, "Number of additional Raft snapshots to retain") +func addSwarmFlags(flags *pflag.FlagSet, options *swarmOptions) { + flags.Int64Var(&options.taskHistoryLimit, flagTaskHistoryLimit, 5, "Task history retention limit") + flags.DurationVar(&options.dispatcherHeartbeat, flagDispatcherHeartbeat, 5*time.Second, "Dispatcher heartbeat period (ns|us|ms|s|m|h)") + flags.Uint64Var(&options.maxSnapshots, flagMaxSnapshots, 0, "Number of additional Raft snapshots to retain") flags.SetAnnotation(flagMaxSnapshots, "version", []string{"1.25"}) - flags.Uint64Var(&opts.snapshotInterval, flagSnapshotInterval, 10000, "Number of log entries between Raft snapshots") + flags.Uint64Var(&options.snapshotInterval, flagSnapshotInterval, 10000, "Number of log entries between Raft snapshots") flags.SetAnnotation(flagSnapshotInterval, "version", []string{"1.25"}) - addSwarmCAFlags(flags, &opts.swarmCAOptions) + addSwarmCAFlags(flags, &options.swarmCAOptions) } -func (opts *swarmOptions) mergeSwarmSpec(spec *swarm.Spec, flags *pflag.FlagSet, caCert string) { +func (o *swarmOptions) mergeSwarmSpec(spec *swarm.Spec, flags *pflag.FlagSet, caCert string) { if flags.Changed(flagTaskHistoryLimit) { - spec.Orchestration.TaskHistoryRetentionLimit = &opts.taskHistoryLimit + spec.Orchestration.TaskHistoryRetentionLimit = &o.taskHistoryLimit } if flags.Changed(flagDispatcherHeartbeat) { - spec.Dispatcher.HeartbeatPeriod = opts.dispatcherHeartbeat + spec.Dispatcher.HeartbeatPeriod = o.dispatcherHeartbeat } if flags.Changed(flagMaxSnapshots) { - spec.Raft.KeepOldSnapshots = &opts.maxSnapshots + spec.Raft.KeepOldSnapshots = &o.maxSnapshots } if flags.Changed(flagSnapshotInterval) { - spec.Raft.SnapshotInterval = opts.snapshotInterval + spec.Raft.SnapshotInterval = o.snapshotInterval } if flags.Changed(flagAutolock) { - spec.EncryptionConfig.AutoLockManagers = opts.autolock + spec.EncryptionConfig.AutoLockManagers = o.autolock } - opts.mergeSwarmSpecCAFlags(spec, flags, caCert) + o.mergeSwarmSpecCAFlags(spec, flags, caCert) } type swarmCAOptions struct { @@ -255,20 +255,20 @@ type swarmCAOptions struct { externalCA ExternalCAOption } -func (opts *swarmCAOptions) mergeSwarmSpecCAFlags(spec *swarm.Spec, flags *pflag.FlagSet, caCert string) { +func (o *swarmCAOptions) mergeSwarmSpecCAFlags(spec *swarm.Spec, flags *pflag.FlagSet, caCert string) { if flags.Changed(flagCertExpiry) { - spec.CAConfig.NodeCertExpiry = opts.nodeCertExpiry + spec.CAConfig.NodeCertExpiry = o.nodeCertExpiry } if flags.Changed(flagExternalCA) { - spec.CAConfig.ExternalCAs = opts.externalCA.Value() + spec.CAConfig.ExternalCAs = o.externalCA.Value() for _, ca := range spec.CAConfig.ExternalCAs { ca.CACert = caCert } } } -func (opts *swarmOptions) ToSpec(flags *pflag.FlagSet) swarm.Spec { +func (o *swarmOptions) ToSpec(flags *pflag.FlagSet) swarm.Spec { var spec swarm.Spec - opts.mergeSwarmSpec(&spec, flags, "") + o.mergeSwarmSpec(&spec, flags, "") return spec } diff --git a/cli/command/system/info_test.go b/cli/command/system/info_test.go index 6744f3b5cf..19699c5987 100644 --- a/cli/command/system/info_test.go +++ b/cli/command/system/info_test.go @@ -464,7 +464,7 @@ func TestFormatInfo(t *testing.T) { { doc: "syntax", template: "{{.badString}}", - expectedError: `template: :1:2: executing "" at <.badString>: can't evaluate field badString in type system.info`, + expectedError: `template: :1:2: executing "" at <.badString>: can't evaluate field badString in type system.dockerInfo`, }, } { tc := tc diff --git a/cli/command/trust/inspect.go b/cli/command/trust/inspect.go index 980fb321c4..3dd40b1cfc 100644 --- a/cli/command/trust/inspect.go +++ b/cli/command/trust/inspect.go @@ -38,18 +38,18 @@ func newInspectCommand(dockerCli command.Cli) *cobra.Command { return cmd } -func runInspect(dockerCli command.Cli, opts inspectOptions) error { +func runInspect(dockerCLI command.Cli, opts inspectOptions) error { if opts.prettyPrint { var err error for index, remote := range opts.remotes { - if err = prettyPrintTrustInfo(dockerCli, remote); err != nil { + if err = prettyPrintTrustInfo(dockerCLI, remote); err != nil { return err } // Additional separator between the inspection output of each image if index < len(opts.remotes)-1 { - fmt.Fprint(dockerCli.Out(), "\n\n") + fmt.Fprint(dockerCLI.Out(), "\n\n") } } @@ -57,14 +57,14 @@ func runInspect(dockerCli command.Cli, opts inspectOptions) error { } getRefFunc := func(ref string) (interface{}, []byte, error) { - i, err := getRepoTrustInfo(dockerCli, ref) + i, err := getRepoTrustInfo(dockerCLI, ref) return nil, i, err } - return inspect.Inspect(dockerCli.Out(), opts.remotes, "", getRefFunc) + return inspect.Inspect(dockerCLI.Out(), opts.remotes, "", getRefFunc) } -func getRepoTrustInfo(cli command.Cli, remote string) ([]byte, error) { - signatureRows, adminRolesWithSigs, delegationRoles, err := lookupTrustInfo(cli, remote) +func getRepoTrustInfo(dockerCLI command.Cli, remote string) ([]byte, error) { + signatureRows, adminRolesWithSigs, delegationRoles, err := lookupTrustInfo(dockerCLI, remote) if err != nil { return []byte{}, err } diff --git a/cli/command/trust/revoke.go b/cli/command/trust/revoke.go index df2a22aa4d..f36dff190a 100644 --- a/cli/command/trust/revoke.go +++ b/cli/command/trust/revoke.go @@ -19,14 +19,14 @@ type revokeOptions struct { forceYes bool } -func newRevokeCommand(dockerCli command.Cli) *cobra.Command { +func newRevokeCommand(dockerCLI command.Cli) *cobra.Command { options := revokeOptions{} cmd := &cobra.Command{ Use: "revoke [OPTIONS] IMAGE[:TAG]", Short: "Remove trust for an image", Args: cli.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - return revokeTrust(dockerCli, args[0], options) + return revokeTrust(dockerCLI, args[0], options) }, } flags := cmd.Flags() @@ -34,9 +34,9 @@ func newRevokeCommand(dockerCli command.Cli) *cobra.Command { return cmd } -func revokeTrust(cli command.Cli, remote string, options revokeOptions) error { +func revokeTrust(dockerCLI command.Cli, remote string, options revokeOptions) error { ctx := context.Background() - imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, image.AuthResolver(cli), remote) + imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, image.AuthResolver(dockerCLI), remote) if err != nil { return err } @@ -45,14 +45,14 @@ func revokeTrust(cli command.Cli, remote string, options revokeOptions) error { return fmt.Errorf("cannot use a digest reference for IMAGE:TAG") } if imgRefAndAuth.Tag() == "" && !options.forceYes { - deleteRemote := command.PromptForConfirmation(os.Stdin, cli.Out(), fmt.Sprintf("Please confirm you would like to delete all signature data for %s?", remote)) + deleteRemote := command.PromptForConfirmation(os.Stdin, dockerCLI.Out(), fmt.Sprintf("Please confirm you would like to delete all signature data for %s?", remote)) if !deleteRemote { - fmt.Fprintf(cli.Out(), "\nAborting action.\n") + fmt.Fprintf(dockerCLI.Out(), "\nAborting action.\n") return nil } } - notaryRepo, err := cli.NotaryClient(imgRefAndAuth, trust.ActionsPushAndPull) + notaryRepo, err := dockerCLI.NotaryClient(imgRefAndAuth, trust.ActionsPushAndPull) if err != nil { return err } @@ -64,7 +64,7 @@ func revokeTrust(cli command.Cli, remote string, options revokeOptions) error { if err := revokeSignature(notaryRepo, tag); err != nil { return errors.Wrapf(err, "could not remove signature for %s", remote) } - fmt.Fprintf(cli.Out(), "Successfully deleted signature for %s\n", remote) + fmt.Fprintf(dockerCLI.Out(), "Successfully deleted signature for %s\n", remote) return nil } diff --git a/cli/command/trust/sign.go b/cli/command/trust/sign.go index 7679b38f7c..1ac45a1acc 100644 --- a/cli/command/trust/sign.go +++ b/cli/command/trust/sign.go @@ -14,6 +14,7 @@ import ( "github.com/docker/cli/cli/trust" "github.com/docker/docker/api/types" registrytypes "github.com/docker/docker/api/types/registry" + apiclient "github.com/docker/docker/client" "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/theupdateframework/notary/client" @@ -25,7 +26,7 @@ type signOptions struct { imageName string } -func newSignCommand(dockerCli command.Cli) *cobra.Command { +func newSignCommand(dockerCLI command.Cli) *cobra.Command { options := signOptions{} cmd := &cobra.Command{ Use: "sign IMAGE:TAG", @@ -33,7 +34,7 @@ func newSignCommand(dockerCli command.Cli) *cobra.Command { Args: cli.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { options.imageName = args[0] - return runSignImage(dockerCli, options) + return runSignImage(dockerCLI, options) }, } flags := cmd.Flags() @@ -41,10 +42,10 @@ func newSignCommand(dockerCli command.Cli) *cobra.Command { return cmd } -func runSignImage(cli command.Cli, options signOptions) error { +func runSignImage(dockerCLI command.Cli, options signOptions) error { imageName := options.imageName ctx := context.Background() - imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, image.AuthResolver(cli), imageName) + imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, image.AuthResolver(dockerCLI), imageName) if err != nil { return err } @@ -52,7 +53,7 @@ func runSignImage(cli command.Cli, options signOptions) error { return err } - notaryRepo, err := cli.NotaryClient(imgRefAndAuth, trust.ActionsPushAndPull) + notaryRepo, err := dockerCLI.NotaryClient(imgRefAndAuth, trust.ActionsPushAndPull) if err != nil { return trust.NotaryError(imgRefAndAuth.Reference().Name(), err) } @@ -66,7 +67,7 @@ func runSignImage(cli command.Cli, options signOptions) error { switch err.(type) { case client.ErrRepoNotInitialized, client.ErrRepositoryNotExist: // before initializing a new repo, check that the image exists locally: - if err := checkLocalImageExistence(ctx, cli, imageName); err != nil { + if err := checkLocalImageExistence(ctx, dockerCLI.Client(), imageName); err != nil { return err } @@ -75,25 +76,25 @@ func runSignImage(cli command.Cli, options signOptions) error { return trust.NotaryError(imgRefAndAuth.Reference().Name(), err) } - fmt.Fprintf(cli.Out(), "Created signer: %s\n", imgRefAndAuth.AuthConfig().Username) - fmt.Fprintf(cli.Out(), "Finished initializing signed repository for %s\n", imageName) + fmt.Fprintf(dockerCLI.Out(), "Created signer: %s\n", imgRefAndAuth.AuthConfig().Username) + fmt.Fprintf(dockerCLI.Out(), "Finished initializing signed repository for %s\n", imageName) default: return trust.NotaryError(imgRefAndAuth.RepoInfo().Name.Name(), err) } } - requestPrivilege := command.RegistryAuthenticationPrivilegedFunc(cli, imgRefAndAuth.RepoInfo().Index, "push") + requestPrivilege := command.RegistryAuthenticationPrivilegedFunc(dockerCLI, imgRefAndAuth.RepoInfo().Index, "push") target, err := createTarget(notaryRepo, imgRefAndAuth.Tag()) if err != nil || options.local { switch err := err.(type) { // If the error is nil then the local flag is set case client.ErrNoSuchTarget, client.ErrRepositoryNotExist, nil: // Fail fast if the image doesn't exist locally - if err := checkLocalImageExistence(ctx, cli, imageName); err != nil { + if err := checkLocalImageExistence(ctx, dockerCLI.Client(), imageName); err != nil { return err } - fmt.Fprintf(cli.Err(), "Signing and pushing trust data for local image %s, may overwrite remote trust data\n", imageName) + fmt.Fprintf(dockerCLI.Err(), "Signing and pushing trust data for local image %s, may overwrite remote trust data\n", imageName) - authConfig := command.ResolveAuthConfig(cli.ConfigFile(), imgRefAndAuth.RepoInfo().Index) + authConfig := command.ResolveAuthConfig(dockerCLI.ConfigFile(), imgRefAndAuth.RepoInfo().Index) encodedAuth, err := registrytypes.EncodeAuthConfig(authConfig) if err != nil { return err @@ -102,12 +103,12 @@ func runSignImage(cli command.Cli, options signOptions) error { RegistryAuth: encodedAuth, PrivilegeFunc: requestPrivilege, } - return image.TrustedPush(ctx, cli, imgRefAndAuth.RepoInfo(), imgRefAndAuth.Reference(), *imgRefAndAuth.AuthConfig(), options) + return image.TrustedPush(ctx, dockerCLI, imgRefAndAuth.RepoInfo(), imgRefAndAuth.Reference(), *imgRefAndAuth.AuthConfig(), options) default: return err } } - return signAndPublishToTarget(cli.Out(), imgRefAndAuth, notaryRepo, target) + return signAndPublishToTarget(dockerCLI.Out(), imgRefAndAuth, notaryRepo, target) } func signAndPublishToTarget(out io.Writer, imgRefAndAuth trust.ImageRefAndAuth, notaryRepo client.Repository, target client.Target) error { @@ -140,8 +141,8 @@ func validateTag(imgRefAndAuth trust.ImageRefAndAuth) error { return nil } -func checkLocalImageExistence(ctx context.Context, cli command.Cli, imageName string) error { - _, _, err := cli.Client().ImageInspectWithRaw(ctx, imageName) +func checkLocalImageExistence(ctx context.Context, apiClient apiclient.APIClient, imageName string) error { + _, _, err := apiClient.ImageInspectWithRaw(ctx, imageName) return err } diff --git a/cli/command/trust/signer_add.go b/cli/command/trust/signer_add.go index ec4b61a4a2..e840970790 100644 --- a/cli/command/trust/signer_add.go +++ b/cli/command/trust/signer_add.go @@ -27,7 +27,7 @@ type signerAddOptions struct { repos []string } -func newSignerAddCommand(dockerCli command.Cli) *cobra.Command { +func newSignerAddCommand(dockerCLI command.Cli) *cobra.Command { var options signerAddOptions cmd := &cobra.Command{ Use: "add OPTIONS NAME REPOSITORY [REPOSITORY...] ", @@ -36,7 +36,7 @@ func newSignerAddCommand(dockerCli command.Cli) *cobra.Command { RunE: func(cmd *cobra.Command, args []string) error { options.signer = args[0] options.repos = args[1:] - return addSigner(dockerCli, options) + return addSigner(dockerCLI, options) }, } flags := cmd.Flags() @@ -47,7 +47,7 @@ func newSignerAddCommand(dockerCli command.Cli) *cobra.Command { var validSignerName = regexp.MustCompile(`^[a-z0-9][a-z0-9\_\-]*$`).MatchString -func addSigner(cli command.Cli, options signerAddOptions) error { +func addSigner(dockerCLI command.Cli, options signerAddOptions) error { signerName := options.signer if !validSignerName(signerName) { return fmt.Errorf("signer name \"%s\" must start with lowercase alphanumeric characters and can include \"-\" or \"_\" after the first character", signerName) @@ -65,12 +65,12 @@ func addSigner(cli command.Cli, options signerAddOptions) error { } var errRepos []string for _, repoName := range options.repos { - fmt.Fprintf(cli.Out(), "Adding signer \"%s\" to %s...\n", signerName, repoName) - if err := addSignerToRepo(cli, signerName, repoName, signerPubKeys); err != nil { - fmt.Fprintln(cli.Err(), err.Error()+"\n") + fmt.Fprintf(dockerCLI.Out(), "Adding signer \"%s\" to %s...\n", signerName, repoName) + if err := addSignerToRepo(dockerCLI, signerName, repoName, signerPubKeys); err != nil { + fmt.Fprintln(dockerCLI.Err(), err.Error()+"\n") errRepos = append(errRepos, repoName) } else { - fmt.Fprintf(cli.Out(), "Successfully added signer: %s to %s\n\n", signerName, repoName) + fmt.Fprintf(dockerCLI.Out(), "Successfully added signer: %s to %s\n\n", signerName, repoName) } } if len(errRepos) > 0 { @@ -79,14 +79,14 @@ func addSigner(cli command.Cli, options signerAddOptions) error { return nil } -func addSignerToRepo(cli command.Cli, signerName string, repoName string, signerPubKeys []data.PublicKey) error { +func addSignerToRepo(dockerCLI command.Cli, signerName string, repoName string, signerPubKeys []data.PublicKey) error { ctx := context.Background() - imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, image.AuthResolver(cli), repoName) + imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, image.AuthResolver(dockerCLI), repoName) if err != nil { return err } - notaryRepo, err := cli.NotaryClient(imgRefAndAuth, trust.ActionsPushAndPull) + notaryRepo, err := dockerCLI.NotaryClient(imgRefAndAuth, trust.ActionsPushAndPull) if err != nil { return trust.NotaryError(imgRefAndAuth.Reference().Name(), err) } @@ -94,11 +94,11 @@ func addSignerToRepo(cli command.Cli, signerName string, repoName string, signer if _, err = notaryRepo.ListTargets(); err != nil { switch err.(type) { case client.ErrRepoNotInitialized, client.ErrRepositoryNotExist: - fmt.Fprintf(cli.Out(), "Initializing signed repository for %s...\n", repoName) + fmt.Fprintf(dockerCLI.Out(), "Initializing signed repository for %s...\n", repoName) if err := getOrGenerateRootKeyAndInitRepo(notaryRepo); err != nil { return trust.NotaryError(repoName, err) } - fmt.Fprintf(cli.Out(), "Successfully initialized %q\n", repoName) + fmt.Fprintf(dockerCLI.Out(), "Successfully initialized %q\n", repoName) default: return trust.NotaryError(repoName, err) } diff --git a/cli/command/trust/signer_remove.go b/cli/command/trust/signer_remove.go index 300a8c23c3..226c39de04 100644 --- a/cli/command/trust/signer_remove.go +++ b/cli/command/trust/signer_remove.go @@ -39,12 +39,12 @@ func newSignerRemoveCommand(dockerCli command.Cli) *cobra.Command { return cmd } -func removeSigner(cli command.Cli, options signerRemoveOptions) error { +func removeSigner(dockerCLI command.Cli, options signerRemoveOptions) error { var errRepos []string for _, repo := range options.repos { - fmt.Fprintf(cli.Out(), "Removing signer \"%s\" from %s...\n", options.signer, repo) - if _, err := removeSingleSigner(cli, repo, options.signer, options.forceYes); err != nil { - fmt.Fprintln(cli.Err(), err.Error()+"\n") + fmt.Fprintf(dockerCLI.Out(), "Removing signer \"%s\" from %s...\n", options.signer, repo) + if _, err := removeSingleSigner(dockerCLI, repo, options.signer, options.forceYes); err != nil { + fmt.Fprintln(dockerCLI.Err(), err.Error()+"\n") errRepos = append(errRepos, repo) } } @@ -78,9 +78,9 @@ func isLastSignerForReleases(roleWithSig data.Role, allRoles []client.RoleWithSi // removeSingleSigner attempts to remove a single signer and returns whether signer removal happened. // The signer not being removed doesn't necessarily raise an error e.g. user choosing "No" when prompted for confirmation. -func removeSingleSigner(cli command.Cli, repoName, signerName string, forceYes bool) (bool, error) { +func removeSingleSigner(dockerCLI command.Cli, repoName, signerName string, forceYes bool) (bool, error) { ctx := context.Background() - imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, image.AuthResolver(cli), repoName) + imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, image.AuthResolver(dockerCLI), repoName) if err != nil { return false, err } @@ -89,7 +89,7 @@ func removeSingleSigner(cli command.Cli, repoName, signerName string, forceYes b if signerDelegation == releasesRoleTUFName { return false, errors.Errorf("releases is a reserved keyword and cannot be removed") } - notaryRepo, err := cli.NotaryClient(imgRefAndAuth, trust.ActionsPushAndPull) + notaryRepo, err := dockerCLI.NotaryClient(imgRefAndAuth, trust.ActionsPushAndPull) if err != nil { return false, trust.NotaryError(imgRefAndAuth.Reference().Name(), err) } @@ -112,14 +112,14 @@ func removeSingleSigner(cli command.Cli, repoName, signerName string, forceYes b return false, err } if ok, err := isLastSignerForReleases(role, allRoles); ok && !forceYes { - removeSigner := command.PromptForConfirmation(os.Stdin, cli.Out(), fmt.Sprintf("The signer \"%s\" signed the last released version of %s. "+ + removeSigner := command.PromptForConfirmation(os.Stdin, dockerCLI.Out(), fmt.Sprintf("The signer \"%s\" signed the last released version of %s. "+ "Removing this signer will make %s unpullable. "+ "Are you sure you want to continue?", signerName, repoName, repoName, )) if !removeSigner { - fmt.Fprintf(cli.Out(), "\nAborting action.\n") + fmt.Fprintf(dockerCLI.Out(), "\nAborting action.\n") return false, nil } } else if err != nil { @@ -136,7 +136,7 @@ func removeSingleSigner(cli command.Cli, repoName, signerName string, forceYes b return false, err } - fmt.Fprintf(cli.Out(), "Successfully removed %s from %s\n\n", signerName, repoName) + fmt.Fprintf(dockerCLI.Out(), "Successfully removed %s from %s\n\n", signerName, repoName) return true, nil } diff --git a/cli/compose/convert/service.go b/cli/compose/convert/service.go index e835380bff..dc996dd3c8 100644 --- a/cli/compose/convert/service.go +++ b/cli/compose/convert/service.go @@ -27,25 +27,20 @@ const ( func Services( namespace Namespace, config *composetypes.Config, - client client.CommonAPIClient, + apiClient client.CommonAPIClient, ) (map[string]swarm.ServiceSpec, error) { result := make(map[string]swarm.ServiceSpec) - - services := config.Services - volumes := config.Volumes - networks := config.Networks - - for _, service := range services { - secrets, err := convertServiceSecrets(client, namespace, service.Secrets, config.Secrets) + for _, service := range config.Services { + secrets, err := convertServiceSecrets(apiClient, namespace, service.Secrets, config.Secrets) if err != nil { return nil, errors.Wrapf(err, "service %s", service.Name) } - configs, err := convertServiceConfigObjs(client, namespace, service, config.Configs) + configs, err := convertServiceConfigObjs(apiClient, namespace, service, config.Configs) if err != nil { return nil, errors.Wrapf(err, "service %s", service.Name) } - serviceSpec, err := Service(client.ClientVersion(), namespace, service, networks, volumes, secrets, configs) + serviceSpec, err := Service(apiClient.ClientVersion(), namespace, service, config.Networks, config.Volumes, secrets, configs) if err != nil { return nil, errors.Wrapf(err, "service %s", service.Name) } @@ -245,7 +240,7 @@ func convertServiceNetworks( // TODO: fix secrets API so that SecretAPIClient is not required here func convertServiceSecrets( - client client.SecretAPIClient, + apiClient client.SecretAPIClient, namespace Namespace, secrets []composetypes.ServiceSecretConfig, secretSpecs map[string]composetypes.SecretConfig, @@ -272,7 +267,7 @@ func convertServiceSecrets( }) } - secrs, err := servicecli.ParseSecrets(client, refs) + secrs, err := servicecli.ParseSecrets(apiClient, refs) if err != nil { return nil, err } @@ -289,7 +284,7 @@ func convertServiceSecrets( // // TODO: fix configs API so that ConfigsAPIClient is not required here func convertServiceConfigObjs( - client client.ConfigAPIClient, + apiClient client.ConfigAPIClient, namespace Namespace, service composetypes.ServiceConfig, configSpecs map[string]composetypes.ConfigObjConfig, @@ -348,7 +343,7 @@ func convertServiceConfigObjs( } - confs, err := servicecli.ParseConfigs(client, refs) + confs, err := servicecli.ParseConfigs(apiClient, refs) if err != nil { return nil, err } diff --git a/cli/compose/convert/service_test.go b/cli/compose/convert/service_test.go index 1293fda45e..e5064973a4 100644 --- a/cli/compose/convert/service_test.go +++ b/cli/compose/convert/service_test.go @@ -497,7 +497,7 @@ func TestConvertServiceSecrets(t *testing.T) { Name: "bar_secret", }, } - client := &fakeClient{ + apiClient := &fakeClient{ secretListFunc: func(opts types.SecretListOptions) ([]swarm.Secret, error) { assert.Check(t, is.Contains(opts.Filters.Get("name"), "foo_secret")) assert.Check(t, is.Contains(opts.Filters.Get("name"), "bar_secret")) @@ -507,7 +507,7 @@ func TestConvertServiceSecrets(t *testing.T) { }, nil }, } - refs, err := convertServiceSecrets(client, namespace, secrets, secretSpecs) + refs, err := convertServiceSecrets(apiClient, namespace, secrets, secretSpecs) assert.NilError(t, err) expected := []*swarm.SecretReference{ { @@ -554,7 +554,7 @@ func TestConvertServiceConfigs(t *testing.T) { Name: "baz_config", }, } - client := &fakeClient{ + apiClient := &fakeClient{ configListFunc: func(opts types.ConfigListOptions) ([]swarm.Config, error) { assert.Check(t, is.Contains(opts.Filters.Get("name"), "foo_config")) assert.Check(t, is.Contains(opts.Filters.Get("name"), "bar_config")) @@ -566,7 +566,7 @@ func TestConvertServiceConfigs(t *testing.T) { }, nil }, } - refs, err := convertServiceConfigObjs(client, namespace, service, configSpecs) + refs, err := convertServiceConfigObjs(apiClient, namespace, service, configSpecs) assert.NilError(t, err) expected := []*swarm.ConfigReference{ { diff --git a/cli/compose/convert/volume_test.go b/cli/compose/convert/volume_test.go index 6ab2056a3b..7f9da874fb 100644 --- a/cli/compose/convert/volume_test.go +++ b/cli/compose/convert/volume_test.go @@ -18,9 +18,9 @@ func TestConvertVolumeToMountAnonymousVolume(t *testing.T) { Type: mount.TypeVolume, Target: "/foo/bar", } - mount, err := convertVolumeToMount(config, volumes{}, NewNamespace("foo")) + mnt, err := convertVolumeToMount(config, volumes{}, NewNamespace("foo")) assert.NilError(t, err) - assert.Check(t, is.DeepEqual(expected, mount)) + assert.Check(t, is.DeepEqual(expected, mnt)) } func TestConvertVolumeToMountAnonymousBind(t *testing.T) { @@ -173,9 +173,9 @@ func TestConvertVolumeToMountNamedVolume(t *testing.T) { NoCopy: true, }, } - mount, err := convertVolumeToMount(config, stackVolumes, namespace) + mnt, err := convertVolumeToMount(config, stackVolumes, namespace) assert.NilError(t, err) - assert.Check(t, is.DeepEqual(expected, mount)) + assert.Check(t, is.DeepEqual(expected, mnt)) } func TestConvertVolumeToMountNamedVolumeWithNameCustomizd(t *testing.T) { @@ -220,9 +220,9 @@ func TestConvertVolumeToMountNamedVolumeWithNameCustomizd(t *testing.T) { NoCopy: true, }, } - mount, err := convertVolumeToMount(config, stackVolumes, namespace) + mnt, err := convertVolumeToMount(config, stackVolumes, namespace) assert.NilError(t, err) - assert.Check(t, is.DeepEqual(expected, mount)) + assert.Check(t, is.DeepEqual(expected, mnt)) } func TestConvertVolumeToMountNamedVolumeExternal(t *testing.T) { @@ -244,9 +244,9 @@ func TestConvertVolumeToMountNamedVolumeExternal(t *testing.T) { Source: "outside", Target: "/foo", } - mount, err := convertVolumeToMount(config, stackVolumes, namespace) + mnt, err := convertVolumeToMount(config, stackVolumes, namespace) assert.NilError(t, err) - assert.Check(t, is.DeepEqual(expected, mount)) + assert.Check(t, is.DeepEqual(expected, mnt)) } func TestConvertVolumeToMountNamedVolumeExternalNoCopy(t *testing.T) { @@ -273,9 +273,9 @@ func TestConvertVolumeToMountNamedVolumeExternalNoCopy(t *testing.T) { NoCopy: true, }, } - mount, err := convertVolumeToMount(config, stackVolumes, namespace) + mnt, err := convertVolumeToMount(config, stackVolumes, namespace) assert.NilError(t, err) - assert.Check(t, is.DeepEqual(expected, mount)) + assert.Check(t, is.DeepEqual(expected, mnt)) } func TestConvertVolumeToMountBind(t *testing.T) { @@ -295,9 +295,9 @@ func TestConvertVolumeToMountBind(t *testing.T) { ReadOnly: true, Bind: &composetypes.ServiceVolumeBind{Propagation: "shared"}, } - mount, err := convertVolumeToMount(config, stackVolumes, namespace) + mnt, err := convertVolumeToMount(config, stackVolumes, namespace) assert.NilError(t, err) - assert.Check(t, is.DeepEqual(expected, mount)) + assert.Check(t, is.DeepEqual(expected, mnt)) } func TestConvertVolumeToMountVolumeDoesNotExist(t *testing.T) { @@ -325,9 +325,9 @@ func TestConvertTmpfsToMountVolume(t *testing.T) { Target: "/foo/bar", TmpfsOptions: &mount.TmpfsOptions{SizeBytes: 1000}, } - mount, err := convertVolumeToMount(config, volumes{}, NewNamespace("foo")) + mnt, err := convertVolumeToMount(config, volumes{}, NewNamespace("foo")) assert.NilError(t, err) - assert.Check(t, is.DeepEqual(expected, mount)) + assert.Check(t, is.DeepEqual(expected, mnt)) } func TestConvertTmpfsToMountVolumeWithSource(t *testing.T) { @@ -355,9 +355,9 @@ func TestConvertVolumeToMountAnonymousNpipe(t *testing.T) { Source: `\\.\pipe\foo`, Target: `\\.\pipe\foo`, } - mount, err := convertVolumeToMount(config, volumes{}, NewNamespace("foo")) + mnt, err := convertVolumeToMount(config, volumes{}, NewNamespace("foo")) assert.NilError(t, err) - assert.Check(t, is.DeepEqual(expected, mount)) + assert.Check(t, is.DeepEqual(expected, mnt)) } func TestConvertVolumeMountClusterName(t *testing.T) { @@ -389,9 +389,9 @@ func TestConvertVolumeMountClusterName(t *testing.T) { ClusterOptions: &mount.ClusterOptions{}, } - mount, err := convertVolumeToMount(config, stackVolumes, NewNamespace("foo")) + mnt, err := convertVolumeToMount(config, stackVolumes, NewNamespace("foo")) assert.NilError(t, err) - assert.Check(t, is.DeepEqual(expected, mount)) + assert.Check(t, is.DeepEqual(expected, mnt)) } func TestConvertVolumeMountClusterGroup(t *testing.T) { @@ -423,7 +423,7 @@ func TestConvertVolumeMountClusterGroup(t *testing.T) { ClusterOptions: &mount.ClusterOptions{}, } - mount, err := convertVolumeToMount(config, stackVolumes, NewNamespace("foo")) + mnt, err := convertVolumeToMount(config, stackVolumes, NewNamespace("foo")) assert.NilError(t, err) - assert.Check(t, is.DeepEqual(expected, mount)) + assert.Check(t, is.DeepEqual(expected, mnt)) } diff --git a/cli/compose/loader/loader.go b/cli/compose/loader/loader.go index a507181960..5f4ca29cdd 100644 --- a/cli/compose/loader/loader.go +++ b/cli/compose/loader/loader.go @@ -39,8 +39,8 @@ type Options struct { // WithDiscardEnvFiles sets the Options to discard the `env_file` section after resolving to // the `environment` section -func WithDiscardEnvFiles(opts *Options) { - opts.discardEnvFiles = true +func WithDiscardEnvFiles(options *Options) { + options.discardEnvFiles = true } // ParseYAML reads the bytes from a file, parses the bytes into a mapping @@ -62,12 +62,12 @@ func ParseYAML(source []byte) (map[string]interface{}, error) { } // Load reads a ConfigDetails and returns a fully loaded configuration -func Load(configDetails types.ConfigDetails, options ...func(*Options)) (*types.Config, error) { +func Load(configDetails types.ConfigDetails, opt ...func(*Options)) (*types.Config, error) { if len(configDetails.ConfigFiles) < 1 { return nil, errors.Errorf("No files specified") } - opts := &Options{ + options := &Options{ Interpolate: &interp.Options{ Substitute: template.Substitute, LookupValue: configDetails.LookupEnv, @@ -75,8 +75,8 @@ func Load(configDetails types.ConfigDetails, options ...func(*Options)) (*types. }, } - for _, op := range options { - op(opts) + for _, op := range opt { + op(options) } configs := []*types.Config{} @@ -96,14 +96,14 @@ func Load(configDetails types.ConfigDetails, options ...func(*Options)) (*types. return nil, err } - if !opts.SkipInterpolation { - configDict, err = interpolateConfig(configDict, *opts.Interpolate) + if !options.SkipInterpolation { + configDict, err = interpolateConfig(configDict, *options.Interpolate) if err != nil { return nil, err } } - if !opts.SkipValidation { + if !options.SkipValidation { if err := schema.Validate(configDict, configDetails.Version); err != nil { return nil, err } @@ -114,7 +114,7 @@ func Load(configDetails types.ConfigDetails, options ...func(*Options)) (*types. return nil, err } cfg.Filename = file.Filename - if opts.discardEnvFiles { + if options.discardEnvFiles { for i := range cfg.Services { cfg.Services[i].EnvFile = nil } @@ -512,16 +512,16 @@ func resolveVolumePaths(volumes []types.ServiceVolumeConfig, workingDir string, } // TODO: make this more robust -func expandUser(path string, lookupEnv template.Mapping) string { - if strings.HasPrefix(path, "~") { +func expandUser(srcPath string, lookupEnv template.Mapping) string { + if strings.HasPrefix(srcPath, "~") { home, ok := lookupEnv("HOME") if !ok { logrus.Warn("cannot expand '~', because the environment lacks HOME") - return path + return srcPath } - return strings.Replace(path, "~", home, 1) + return strings.Replace(srcPath, "~", home, 1) } - return path + return srcPath } func transformUlimits(data interface{}) (interface{}, error) { diff --git a/cli/compose/schema/schema.go b/cli/compose/schema/schema.go index 9b85c202f1..2ba477c192 100644 --- a/cli/compose/schema/schema.go +++ b/cli/compose/schema/schema.go @@ -141,34 +141,34 @@ func (err validationError) Error() string { return fmt.Sprintf("%s %s", err.parent.Field(), description) } -func getMostSpecificError(errors []gojsonschema.ResultError) validationError { +func getMostSpecificError(errs []gojsonschema.ResultError) validationError { mostSpecificError := 0 - for i, err := range errors { - if specificity(err) > specificity(errors[mostSpecificError]) { + for i, err := range errs { + if specificity(err) > specificity(errs[mostSpecificError]) { mostSpecificError = i continue } - if specificity(err) == specificity(errors[mostSpecificError]) { + if specificity(err) == specificity(errs[mostSpecificError]) { // Invalid type errors win in a tie-breaker for most specific field name - if err.Type() == "invalid_type" && errors[mostSpecificError].Type() != "invalid_type" { + if err.Type() == "invalid_type" && errs[mostSpecificError].Type() != "invalid_type" { mostSpecificError = i } } } - if mostSpecificError+1 == len(errors) { - return validationError{parent: errors[mostSpecificError]} + if mostSpecificError+1 == len(errs) { + return validationError{parent: errs[mostSpecificError]} } - switch errors[mostSpecificError].Type() { + switch errs[mostSpecificError].Type() { case "number_one_of", "number_any_of": return validationError{ - parent: errors[mostSpecificError], - child: errors[mostSpecificError+1], + parent: errs[mostSpecificError], + child: errs[mostSpecificError+1], } default: - return validationError{parent: errors[mostSpecificError]} + return validationError{parent: errs[mostSpecificError]} } } diff --git a/cli/context/store/store.go b/cli/context/store/store.go index ceea2edd1d..bff13665a7 100644 --- a/cli/context/store/store.go +++ b/cli/context/store/store.go @@ -475,8 +475,8 @@ func parseMetadata(data []byte, name string) (Metadata, error) { return meta, nil } -func importEndpointTLS(tlsData *ContextTLSData, path string, data []byte) error { - parts := strings.SplitN(strings.TrimPrefix(path, "tls/"), "/", 2) +func importEndpointTLS(tlsData *ContextTLSData, tlsPath string, data []byte) error { + parts := strings.SplitN(strings.TrimPrefix(tlsPath, "tls/"), "/", 2) if len(parts) != 2 { // TLS endpoints require archived file directory with 2 layers // i.e. tls/{endpointName}/{fileName} diff --git a/cmd/docker/docker.go b/cmd/docker/docker.go index 6a99b58b15..e55bed3588 100644 --- a/cmd/docker/docker.go +++ b/cmd/docker/docker.go @@ -378,16 +378,16 @@ func hideUnsupportedFeatures(cmd *cobra.Command, details versionDetails) error { } // Checks if a command or one of its ancestors is in the list -func findCommand(cmd *cobra.Command, commands []string) bool { +func findCommand(cmd *cobra.Command, cmds []string) bool { if cmd == nil { return false } - for _, c := range commands { + for _, c := range cmds { if c == cmd.Name() { return true } } - return findCommand(cmd.Parent(), commands) + return findCommand(cmd.Parent(), cmds) } func isSupported(cmd *cobra.Command, details versionDetails) error { diff --git a/internal/test/builders/swarm.go b/internal/test/builders/swarm.go index ab1a930628..986976fd5d 100644 --- a/internal/test/builders/swarm.go +++ b/internal/test/builders/swarm.go @@ -10,7 +10,7 @@ import ( // Any number of swarm function builder can be pass to augment it. func Swarm(swarmBuilders ...func(*swarm.Swarm)) *swarm.Swarm { t1 := time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC) - swarm := &swarm.Swarm{ + s := &swarm.Swarm{ ClusterInfo: swarm.ClusterInfo{ ID: "swarm", Meta: swarm.Meta{ @@ -25,15 +25,15 @@ func Swarm(swarmBuilders ...func(*swarm.Swarm)) *swarm.Swarm { } for _, builder := range swarmBuilders { - builder(swarm) + builder(s) } - return swarm + return s } // Autolock set the swarm into autolock mode func Autolock() func(*swarm.Swarm) { - return func(swarm *swarm.Swarm) { - swarm.Spec.EncryptionConfig.AutoLockManagers = true + return func(s *swarm.Swarm) { + s.Spec.EncryptionConfig.AutoLockManagers = true } } diff --git a/internal/test/builders/volume.go b/internal/test/builders/volume.go index 3f8fa90ef8..90b697810b 100644 --- a/internal/test/builders/volume.go +++ b/internal/test/builders/volume.go @@ -4,7 +4,7 @@ import "github.com/docker/docker/api/types/volume" // Volume creates a volume with default values. // Any number of volume function builder can be passed to augment it. -func Volume(builders ...func(volume *volume.Volume)) *volume.Volume { +func Volume(builders ...func(vol *volume.Volume)) *volume.Volume { vol := &volume.Volume{ Name: "volume", Driver: "local", @@ -20,22 +20,22 @@ func Volume(builders ...func(volume *volume.Volume)) *volume.Volume { } // VolumeLabels sets the volume labels -func VolumeLabels(labels map[string]string) func(volume *volume.Volume) { - return func(volume *volume.Volume) { - volume.Labels = labels +func VolumeLabels(labels map[string]string) func(vol *volume.Volume) { + return func(vol *volume.Volume) { + vol.Labels = labels } } // VolumeName sets the volume labels -func VolumeName(name string) func(volume *volume.Volume) { - return func(volume *volume.Volume) { - volume.Name = name +func VolumeName(name string) func(vol *volume.Volume) { + return func(vol *volume.Volume) { + vol.Name = name } } // VolumeDriver sets the volume driver -func VolumeDriver(name string) func(volume *volume.Volume) { - return func(volume *volume.Volume) { - volume.Driver = name +func VolumeDriver(name string) func(vol *volume.Volume) { + return func(vol *volume.Volume) { + vol.Driver = name } } diff --git a/internal/test/cli.go b/internal/test/cli.go index 11d674d857..2315a7a1f2 100644 --- a/internal/test/cli.go +++ b/internal/test/cli.go @@ -41,11 +41,11 @@ type FakeCli struct { } // NewFakeCli returns a fake for the command.Cli interface -func NewFakeCli(client client.APIClient, opts ...func(*FakeCli)) *FakeCli { +func NewFakeCli(apiClient client.APIClient, opts ...func(*FakeCli)) *FakeCli { outBuffer := new(bytes.Buffer) errBuffer := new(bytes.Buffer) c := &FakeCli{ - client: client, + client: apiClient, out: streams.NewOut(outBuffer), outBuffer: outBuffer, err: errBuffer, @@ -77,13 +77,13 @@ func (c *FakeCli) SetOut(out *streams.Out) { } // SetConfigFile sets the "fake" config file -func (c *FakeCli) SetConfigFile(configfile *configfile.ConfigFile) { - c.configfile = configfile +func (c *FakeCli) SetConfigFile(configFile *configfile.ConfigFile) { + c.configfile = configFile } // SetContextStore sets the "fake" context store -func (c *FakeCli) SetContextStore(store store.Store) { - c.contextStore = store +func (c *FakeCli) SetContextStore(contextStore store.Store) { + c.contextStore = contextStore } // SetCurrentContext sets the "fake" current context @@ -186,13 +186,13 @@ func (c *FakeCli) RegistryClient(bool) registryclient.RegistryClient { } // SetManifestStore on the fake cli -func (c *FakeCli) SetManifestStore(store manifeststore.Store) { - c.manifestStore = store +func (c *FakeCli) SetManifestStore(manifestStore manifeststore.Store) { + c.manifestStore = manifestStore } // SetRegistryClient on the fake cli -func (c *FakeCli) SetRegistryClient(client registryclient.RegistryClient) { - c.registryClient = client +func (c *FakeCli) SetRegistryClient(registryClient registryclient.RegistryClient) { + c.registryClient = registryClient } // ContentTrustEnabled on the fake cli From 9c0c49a5f29097cc123a6637b25f2245c4fbb612 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Mon, 20 Nov 2023 17:44:39 +0100 Subject: [PATCH 16/19] golangci-lint: revive: enable empty-lines Signed-off-by: Sebastiaan van Stijn --- .golangci.yml | 8 ++++++++ cli/command/container/cp.go | 1 - cli/command/formatter/container_test.go | 1 - cli/command/formatter/image.go | 1 - cli/command/network/connect_test.go | 1 - cli/command/network/create_test.go | 1 - cli/command/network/remove_test.go | 1 - cli/command/service/progress/progress.go | 1 - cli/command/service/scale.go | 1 - cli/command/swarm/ipnet_slice_test.go | 1 - cli/compose/convert/service.go | 2 -- cli/context/docker/load.go | 1 - 12 files changed, 8 insertions(+), 12 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index c306a9c29e..ccaafa38c7 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -61,6 +61,14 @@ linters-settings: - name: import-shadowing severity: warning disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#empty-block + - name: empty-block + severity: warning + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#empty-lines + - name: empty-lines + severity: warning + disabled: false issues: # The default exclusion rules are a bit too permissive, so copying the relevant ones below diff --git a/cli/command/container/cp.go b/cli/command/container/cp.go index 5ef409ca88..b7f1fe6c39 100644 --- a/cli/command/container/cp.go +++ b/cli/command/container/cp.go @@ -246,7 +246,6 @@ func copyFromContainer(ctx context.Context, dockerCli command.Cli, copyConfig cp linkTarget, rebaseName = archive.GetRebaseName(srcPath, linkTarget) srcPath = linkTarget } - } ctx, cancel := signal.NotifyContext(ctx, os.Interrupt) diff --git a/cli/command/formatter/container_test.go b/cli/command/formatter/container_test.go index 1c09a57791..0dd28430a2 100644 --- a/cli/command/formatter/container_test.go +++ b/cli/command/formatter/container_test.go @@ -265,7 +265,6 @@ size: 0B assert.Equal(t, out.String(), tc.expected) } }) - } } diff --git a/cli/command/formatter/image.go b/cli/command/formatter/image.go index da636891ad..d16f42b5ba 100644 --- a/cli/command/formatter/image.go +++ b/cli/command/formatter/image.go @@ -166,7 +166,6 @@ func imageFormatTaggedAndDigest(ctx ImageContext, img image.Summary) []*imageCon for _, dgst := range digests { addImage(repo, tag, dgst) } - } } diff --git a/cli/command/network/connect_test.go b/cli/command/network/connect_test.go index c245a78543..9a8b0e6d0d 100644 --- a/cli/command/network/connect_test.go +++ b/cli/command/network/connect_test.go @@ -39,7 +39,6 @@ func TestNetworkConnectErrors(t *testing.T) { cmd.SetArgs(tc.args) cmd.SetOut(io.Discard) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) - } } diff --git a/cli/command/network/create_test.go b/cli/command/network/create_test.go index 95938df15e..e2432ae3f9 100644 --- a/cli/command/network/create_test.go +++ b/cli/command/network/create_test.go @@ -139,7 +139,6 @@ func TestNetworkCreateErrors(t *testing.T) { } cmd.SetOut(io.Discard) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) - } } diff --git a/cli/command/network/remove_test.go b/cli/command/network/remove_test.go index ed85e54699..98ea2592f6 100644 --- a/cli/command/network/remove_test.go +++ b/cli/command/network/remove_test.go @@ -90,7 +90,6 @@ func TestNetworkRemoveForce(t *testing.T) { } else { assert.Check(t, is.Contains(fakeCli.ErrBuffer().String(), tc.expectedErr)) assert.ErrorContains(t, err, "Code: 1") - } }) } diff --git a/cli/command/service/progress/progress.go b/cli/command/service/progress/progress.go index 3061f6503a..11436370d1 100644 --- a/cli/command/service/progress/progress.go +++ b/cli/command/service/progress/progress.go @@ -493,7 +493,6 @@ func (u *globalProgressUpdater) tasksByNode(tasks []swarm.Task) map[string]swarm numberedStates[existingTask.Status.State] <= numberedStates[task.Status.State] { continue } - } tasksByNode[task.NodeID] = task } diff --git a/cli/command/service/scale.go b/cli/command/service/scale.go index bdc53ae401..4e6efd84cc 100644 --- a/cli/command/service/scale.go +++ b/cli/command/service/scale.go @@ -76,7 +76,6 @@ func runScale(dockerCli command.Cli, options *scaleOptions, args []string) error } else { serviceIDs = append(serviceIDs, serviceID) } - } if len(serviceIDs) > 0 { diff --git a/cli/command/swarm/ipnet_slice_test.go b/cli/command/swarm/ipnet_slice_test.go index 3f28466ea1..5a25f554c2 100644 --- a/cli/command/swarm/ipnet_slice_test.go +++ b/cli/command/swarm/ipnet_slice_test.go @@ -131,7 +131,6 @@ func TestIPNetBadQuoting(t *testing.T) { } for i, test := range tests { - var cidrs []net.IPNet f := setUpIPNetFlagSet(&cidrs) diff --git a/cli/compose/convert/service.go b/cli/compose/convert/service.go index dc996dd3c8..0f8af6897c 100644 --- a/cli/compose/convert/service.go +++ b/cli/compose/convert/service.go @@ -340,7 +340,6 @@ func convertServiceConfigObjs( ConfigName: name, Runtime: &swarm.ConfigReferenceRuntimeTarget{}, }) - } confs, err := servicecli.ParseConfigs(apiClient, refs) @@ -441,7 +440,6 @@ func convertHealthcheck(healthcheck *composetypes.HealthCheckConfig) (*container return &container.HealthConfig{ Test: []string{"NONE"}, }, nil - } if healthcheck.Timeout != nil { timeout = time.Duration(*healthcheck.Timeout) diff --git a/cli/context/docker/load.go b/cli/context/docker/load.go index 8c597bf9a8..700b73c940 100644 --- a/cli/context/docker/load.go +++ b/cli/context/docker/load.go @@ -98,7 +98,6 @@ func (ep *Endpoint) ClientOpts() ([]client.Opt, error) { withHTTPClient(tlsConfig), client.WithHost(ep.Host), ) - } else { result = append(result, client.WithHTTPClient(&http.Client{ From 0e73168b7e6d1d029d76d05b843b1aaec46739a8 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Mon, 20 Nov 2023 18:04:36 +0100 Subject: [PATCH 17/19] golangci-lint: revive: enable use-any Signed-off-by: Sebastiaan van Stijn --- .golangci.yml | 4 + cli-plugins/manager/error.go | 2 +- cli/command/cli.go | 4 +- cli/command/config/inspect.go | 2 +- cli/command/container/inspect.go | 2 +- cli/command/context.go | 8 +- cli/command/context/create.go | 2 +- cli/command/context/create_test.go | 6 +- cli/command/context/inspect.go | 2 +- cli/command/context_test.go | 2 +- cli/command/defaultcontextstore.go | 4 +- cli/command/defaultcontextstore_test.go | 10 +- cli/command/formatter/container.go | 4 +- cli/command/formatter/container_test.go | 4 +- cli/command/formatter/custom.go | 6 +- cli/command/formatter/formatter.go | 2 +- cli/command/formatter/formatter_test.go | 2 +- cli/command/formatter/reflect.go | 10 +- cli/command/formatter/reflect_test.go | 2 +- cli/command/formatter/volume_test.go | 4 +- cli/command/idresolver/idresolver.go | 4 +- cli/command/image/inspect.go | 2 +- cli/command/inspect/inspector.go | 16 +- cli/command/network/formatter_test.go | 4 +- cli/command/network/inspect.go | 2 +- cli/command/node/formatter_test.go | 10 +- cli/command/node/inspect.go | 2 +- cli/command/plugin/formatter_test.go | 4 +- cli/command/plugin/inspect.go | 2 +- cli/command/secret/inspect.go | 2 +- cli/command/service/formatter_test.go | 4 +- cli/command/service/inspect.go | 4 +- cli/command/service/inspect_test.go | 8 +- cli/command/service/opts.go | 4 +- cli/command/stack/loader/loader.go | 4 +- cli/command/system/inspect.go | 22 +- cli/command/trust/inspect.go | 2 +- cli/command/utils.go | 2 +- cli/command/volume/inspect.go | 2 +- cli/compose/interpolation/interpolation.go | 16 +- .../interpolation/interpolation_test.go | 42 +- cli/compose/loader/full-struct_test.go | 14 +- cli/compose/loader/interpolate.go | 8 +- cli/compose/loader/loader.go | 184 ++++---- cli/compose/loader/loader_test.go | 74 +-- cli/compose/loader/merge.go | 30 +- cli/compose/loader/merge_test.go | 432 +++++++++--------- cli/compose/schema/schema.go | 8 +- cli/compose/schema/schema_test.go | 4 +- cli/compose/template/template.go | 10 +- cli/compose/template/template_test.go | 24 +- cli/compose/types/types.go | 66 +-- cli/context/store/metadata_test.go | 6 +- cli/context/store/metadatastore.go | 6 +- cli/context/store/store.go | 6 +- cli/context/store/store_test.go | 14 +- cli/context/store/storeconfig.go | 2 +- cli/context/store/storeconfig_test.go | 6 +- cmd/docker/builder_test.go | 4 +- templates/templates.go | 2 +- 60 files changed, 572 insertions(+), 568 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index ccaafa38c7..89162cd8bc 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -69,6 +69,10 @@ linters-settings: - name: empty-lines severity: warning disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#use-any + - name: use-any + severity: warning + disabled: false issues: # The default exclusion rules are a bit too permissive, so copying the relevant ones below diff --git a/cli-plugins/manager/error.go b/cli-plugins/manager/error.go index 11822d660c..ae66fb6b03 100644 --- a/cli-plugins/manager/error.go +++ b/cli-plugins/manager/error.go @@ -43,6 +43,6 @@ func wrapAsPluginError(err error, msg string) error { // NewPluginError creates a new pluginError, analogous to // errors.Errorf. -func NewPluginError(msg string, args ...interface{}) error { +func NewPluginError(msg string, args ...any) error { return &pluginError{cause: errors.Errorf(msg, args...)} } diff --git a/cli/command/cli.go b/cli/command/cli.go index 87b9b9d0db..1649e9092d 100644 --- a/cli/command/cli.go +++ b/cli/command/cli.go @@ -514,7 +514,7 @@ func UserAgent() string { } var defaultStoreEndpoints = []store.NamedTypeGetter{ - store.EndpointTypeGetter(docker.DockerEndpoint, func() interface{} { return &docker.EndpointMeta{} }), + store.EndpointTypeGetter(docker.DockerEndpoint, func() any { return &docker.EndpointMeta{} }), } // RegisterDefaultStoreEndpoints registers a new named endpoint @@ -528,7 +528,7 @@ func RegisterDefaultStoreEndpoints(ep ...store.NamedTypeGetter) { // DefaultContextStoreConfig returns a new store.Config with the default set of endpoints configured. func DefaultContextStoreConfig() store.Config { return store.NewConfig( - func() interface{} { return &DockerContext{} }, + func() any { return &DockerContext{} }, defaultStoreEndpoints..., ) } diff --git a/cli/command/config/inspect.go b/cli/command/config/inspect.go index 64773419ad..617a98830c 100644 --- a/cli/command/config/inspect.go +++ b/cli/command/config/inspect.go @@ -48,7 +48,7 @@ func RunConfigInspect(dockerCli command.Cli, opts InspectOptions) error { opts.Format = "pretty" } - getRef := func(id string) (interface{}, []byte, error) { + getRef := func(id string) (any, []byte, error) { return client.ConfigInspectWithRaw(ctx, id) } f := opts.Format diff --git a/cli/command/container/inspect.go b/cli/command/container/inspect.go index b9e320b827..70c2609fac 100644 --- a/cli/command/container/inspect.go +++ b/cli/command/container/inspect.go @@ -43,7 +43,7 @@ func runInspect(dockerCli command.Cli, opts inspectOptions) error { client := dockerCli.Client() ctx := context.Background() - getRefFunc := func(ref string) (interface{}, []byte, error) { + getRefFunc := func(ref string) (any, []byte, error) { return client.ContainerInspectWithRaw(ctx, ref, opts.size) } return inspect.Inspect(dockerCli.Out(), opts.refs, opts.format, getRefFunc) diff --git a/cli/command/context.go b/cli/command/context.go index 29a2be860f..9353e12cdf 100644 --- a/cli/command/context.go +++ b/cli/command/context.go @@ -10,12 +10,12 @@ import ( // DockerContext is a typed representation of what we put in Context metadata type DockerContext struct { Description string - AdditionalFields map[string]interface{} + AdditionalFields map[string]any } // MarshalJSON implements custom JSON marshalling func (dc DockerContext) MarshalJSON() ([]byte, error) { - s := map[string]interface{}{} + s := map[string]any{} if dc.Description != "" { s["Description"] = dc.Description } @@ -29,7 +29,7 @@ func (dc DockerContext) MarshalJSON() ([]byte, error) { // UnmarshalJSON implements custom JSON marshalling func (dc *DockerContext) UnmarshalJSON(payload []byte) error { - var data map[string]interface{} + var data map[string]any if err := json.Unmarshal(payload, &data); err != nil { return err } @@ -39,7 +39,7 @@ func (dc *DockerContext) UnmarshalJSON(payload []byte) error { dc.Description = v.(string) default: if dc.AdditionalFields == nil { - dc.AdditionalFields = make(map[string]interface{}) + dc.AdditionalFields = make(map[string]any) } dc.AdditionalFields[k] = v } diff --git a/cli/command/context/create.go b/cli/command/context/create.go index 93560a4531..b72d1c1c6c 100644 --- a/cli/command/context/create.go +++ b/cli/command/context/create.go @@ -87,7 +87,7 @@ func createNewContext(contextStore store.ReaderWriter, o *CreateOptions) error { return errors.Wrap(err, "unable to create docker endpoint config") } contextMetadata := store.Metadata{ - Endpoints: map[string]interface{}{ + Endpoints: map[string]any{ docker.DockerEndpoint: dockerEP, }, Metadata: command.DockerContext{ diff --git a/cli/command/context/create_test.go b/cli/command/context/create_test.go index f27ad8aac6..bb5370d0d4 100644 --- a/cli/command/context/create_test.go +++ b/cli/command/context/create_test.go @@ -16,15 +16,15 @@ func makeFakeCli(t *testing.T, opts ...func(*test.FakeCli)) *test.FakeCli { t.Helper() dir := t.TempDir() storeConfig := store.NewConfig( - func() interface{} { return &command.DockerContext{} }, - store.EndpointTypeGetter(docker.DockerEndpoint, func() interface{} { return &docker.EndpointMeta{} }), + func() any { return &command.DockerContext{} }, + store.EndpointTypeGetter(docker.DockerEndpoint, func() any { return &docker.EndpointMeta{} }), ) contextStore := &command.ContextStoreWithDefault{ Store: store.New(dir, storeConfig), Resolver: func() (*command.DefaultContext, error) { return &command.DefaultContext{ Meta: store.Metadata{ - Endpoints: map[string]interface{}{ + Endpoints: map[string]any{ docker.DockerEndpoint: docker.EndpointMeta{ Host: "unix:///var/run/docker.sock", }, diff --git a/cli/command/context/inspect.go b/cli/command/context/inspect.go index ddd0f92639..caf42555d1 100644 --- a/cli/command/context/inspect.go +++ b/cli/command/context/inspect.go @@ -40,7 +40,7 @@ func newInspectCommand(dockerCli command.Cli) *cobra.Command { } func runInspect(dockerCli command.Cli, opts inspectOptions) error { - getRefFunc := func(ref string) (interface{}, []byte, error) { + getRefFunc := func(ref string) (any, []byte, error) { c, err := dockerCli.ContextStore().GetMetadata(ref) if err != nil { return nil, nil, err diff --git a/cli/command/context_test.go b/cli/command/context_test.go index 7ef2157942..333bbbcb7f 100644 --- a/cli/command/context_test.go +++ b/cli/command/context_test.go @@ -10,7 +10,7 @@ import ( func TestDockerContextMetadataKeepAdditionalFields(t *testing.T) { c := DockerContext{ Description: "test", - AdditionalFields: map[string]interface{}{ + AdditionalFields: map[string]any{ "foo": "bar", }, } diff --git a/cli/command/defaultcontextstore.go b/cli/command/defaultcontextstore.go index 3e136a174c..d0a46c61a2 100644 --- a/cli/command/defaultcontextstore.go +++ b/cli/command/defaultcontextstore.go @@ -46,7 +46,7 @@ type EndpointDefaultResolver interface { // returns nil, nil, nil. // //nolint:dupword // ignore "Duplicate words (nil,) found" - ResolveDefault() (interface{}, *store.EndpointTLSData, error) + ResolveDefault() (any, *store.EndpointTLSData, error) } // ResolveDefaultContext creates a Metadata for the current CLI invocation parameters @@ -55,7 +55,7 @@ func ResolveDefaultContext(opts *cliflags.ClientOptions, config store.Config) (* Endpoints: make(map[string]store.EndpointTLSData), } contextMetadata := store.Metadata{ - Endpoints: make(map[string]interface{}), + Endpoints: make(map[string]any), Metadata: DockerContext{ Description: "", }, diff --git a/cli/command/defaultcontextstore_test.go b/cli/command/defaultcontextstore_test.go index a368135ff7..83094a4ea2 100644 --- a/cli/command/defaultcontextstore_test.go +++ b/cli/command/defaultcontextstore_test.go @@ -23,14 +23,14 @@ type testContext struct { Bar string `json:"another_very_recognizable_field_name"` } -var testCfg = store.NewConfig(func() interface{} { return &testContext{} }, - store.EndpointTypeGetter("ep1", func() interface{} { return &endpoint{} }), - store.EndpointTypeGetter("ep2", func() interface{} { return &endpoint{} }), +var testCfg = store.NewConfig(func() any { return &testContext{} }, + store.EndpointTypeGetter("ep1", func() any { return &endpoint{} }), + store.EndpointTypeGetter("ep2", func() any { return &endpoint{} }), ) func testDefaultMetadata() store.Metadata { return store.Metadata{ - Endpoints: map[string]interface{}{ + Endpoints: map[string]any{ "ep1": endpoint{Foo: "bar"}, }, Metadata: testContext{Bar: "baz"}, @@ -149,7 +149,7 @@ func TestErrCreateDefault(t *testing.T) { meta := testDefaultMetadata() s := testStore(t, meta, store.ContextTLSData{}) err := s.CreateOrUpdate(store.Metadata{ - Endpoints: map[string]interface{}{ + Endpoints: map[string]any{ "ep1": endpoint{Foo: "bar"}, }, Metadata: testContext{Bar: "baz"}, diff --git a/cli/command/formatter/container.go b/cli/command/formatter/container.go index 5151a2194b..76eecd2c23 100644 --- a/cli/command/formatter/container.go +++ b/cli/command/formatter/container.go @@ -86,7 +86,7 @@ type ContainerContext struct { // used in the template. It's currently only used to detect use of the .Size // field which (if used) automatically sets the '--size' option when making // the API call. - FieldsUsed map[string]interface{} + FieldsUsed map[string]any } // NewContainerContext creates a new context for rendering containers @@ -226,7 +226,7 @@ func (c *ContainerContext) Status() string { // Size returns the container's size and virtual size (e.g. "2B (virtual 21.5MB)") func (c *ContainerContext) Size() string { if c.FieldsUsed == nil { - c.FieldsUsed = map[string]interface{}{} + c.FieldsUsed = map[string]any{} } c.FieldsUsed["Size"] = struct{}{} srw := units.HumanSizeWithPrecision(float64(c.c.SizeRw), 3) diff --git a/cli/command/formatter/container_test.go b/cli/command/formatter/container_test.go index 0dd28430a2..3be931aeab 100644 --- a/cli/command/formatter/container_test.go +++ b/cli/command/formatter/container_test.go @@ -339,7 +339,7 @@ func TestContainerContextWriteJSON(t *testing.T) { {ID: "containerID2", Names: []string{"/foobar_bar"}, Image: "ubuntu", Created: unix, State: "running"}, } expectedCreated := time.Unix(unix, 0).String() - expectedJSONs := []map[string]interface{}{ + expectedJSONs := []map[string]any{ { "Command": "\"\"", "CreatedAt": expectedCreated, @@ -380,7 +380,7 @@ func TestContainerContextWriteJSON(t *testing.T) { } for i, line := range strings.Split(strings.TrimSpace(out.String()), "\n") { msg := fmt.Sprintf("Output: line %d: %s", i, line) - var m map[string]interface{} + var m map[string]any err := json.Unmarshal([]byte(line), &m) assert.NilError(t, err, msg) assert.Check(t, is.DeepEqual(expectedJSONs[i], m), msg) diff --git a/cli/command/formatter/custom.go b/cli/command/formatter/custom.go index 2d6c979c32..dac42e4b06 100644 --- a/cli/command/formatter/custom.go +++ b/cli/command/formatter/custom.go @@ -22,7 +22,7 @@ const ( // SubContext defines what Context implementation should provide type SubContext interface { - FullHeader() interface{} + FullHeader() any } // SubHeaderContext is a map destined to formatter header (table format) @@ -39,10 +39,10 @@ func (c SubHeaderContext) Label(name string) string { // HeaderContext provides the subContext interface for managing headers type HeaderContext struct { - Header interface{} + Header any } // FullHeader returns the header as an interface -func (c *HeaderContext) FullHeader() interface{} { +func (c *HeaderContext) FullHeader() any { return c.Header } diff --git a/cli/command/formatter/formatter.go b/cli/command/formatter/formatter.go index 55c5ea6e02..3f214b66aa 100644 --- a/cli/command/formatter/formatter.go +++ b/cli/command/formatter/formatter.go @@ -51,7 +51,7 @@ type Context struct { // internal element finalFormat string - header interface{} + header any buffer *bytes.Buffer } diff --git a/cli/command/formatter/formatter_test.go b/cli/command/formatter/formatter_test.go index 0f7ca93442..1ee328a00e 100644 --- a/cli/command/formatter/formatter_test.go +++ b/cli/command/formatter/formatter_test.go @@ -25,7 +25,7 @@ type fakeSubContext struct { Name string } -func (f fakeSubContext) FullHeader() interface{} { +func (f fakeSubContext) FullHeader() any { return map[string]string{"Name": "NAME"} } diff --git a/cli/command/formatter/reflect.go b/cli/command/formatter/reflect.go index 9d153bc988..990b9d2202 100644 --- a/cli/command/formatter/reflect.go +++ b/cli/command/formatter/reflect.go @@ -10,7 +10,7 @@ import ( // MarshalJSON marshals x into json // It differs a bit from encoding/json MarshalJSON function for formatter -func MarshalJSON(x interface{}) ([]byte, error) { +func MarshalJSON(x any) ([]byte, error) { m, err := marshalMap(x) if err != nil { return nil, err @@ -18,8 +18,8 @@ func MarshalJSON(x interface{}) ([]byte, error) { return json.Marshal(m) } -// marshalMap marshals x to map[string]interface{} -func marshalMap(x interface{}) (map[string]interface{}, error) { +// marshalMap marshals x to map[string]any +func marshalMap(x any) (map[string]any, error) { val := reflect.ValueOf(x) if val.Kind() != reflect.Ptr { return nil, errors.Errorf("expected a pointer to a struct, got %v", val.Kind()) @@ -32,7 +32,7 @@ func marshalMap(x interface{}) (map[string]interface{}, error) { return nil, errors.Errorf("expected a pointer to a struct, got a pointer to %v", valElem.Kind()) } typ := val.Type() - m := make(map[string]interface{}) + m := make(map[string]any) for i := 0; i < val.NumMethod(); i++ { k, v, err := marshalForMethod(typ.Method(i), val.Method(i)) if err != nil { @@ -49,7 +49,7 @@ var unmarshallableNames = map[string]struct{}{"FullHeader": {}} // marshalForMethod returns the map key and the map value for marshalling the method. // It returns ("", nil, nil) for valid but non-marshallable parameter. (e.g. "unexportedFunc()") -func marshalForMethod(typ reflect.Method, val reflect.Value) (string, interface{}, error) { +func marshalForMethod(typ reflect.Method, val reflect.Value) (string, any, error) { if val.Kind() != reflect.Func { return "", nil, errors.Errorf("expected func, got %v", val.Kind()) } diff --git a/cli/command/formatter/reflect_test.go b/cli/command/formatter/reflect_test.go index c4e2383f03..74afb92e93 100644 --- a/cli/command/formatter/reflect_test.go +++ b/cli/command/formatter/reflect_test.go @@ -33,7 +33,7 @@ func (d *dummy) FullHeader() string { return "FullHeader(should not be marshalled)" } -var dummyExpected = map[string]interface{}{ +var dummyExpected = map[string]any{ "Func1": "Func1", "Func4": 4, "Func5": dummyType("Func5"), diff --git a/cli/command/formatter/volume_test.go b/cli/command/formatter/volume_test.go index 64997a2d81..26e6361dae 100644 --- a/cli/command/formatter/volume_test.go +++ b/cli/command/formatter/volume_test.go @@ -147,7 +147,7 @@ func TestVolumeContextWriteJSON(t *testing.T) { {Driver: "foo", Name: "foobar_baz"}, {Driver: "bar", Name: "foobar_bar"}, } - expectedJSONs := []map[string]interface{}{ + expectedJSONs := []map[string]any{ {"Availability": "N/A", "Driver": "foo", "Group": "N/A", "Labels": "", "Links": "N/A", "Mountpoint": "", "Name": "foobar_baz", "Scope": "", "Size": "N/A", "Status": "N/A"}, {"Availability": "N/A", "Driver": "bar", "Group": "N/A", "Labels": "", "Links": "N/A", "Mountpoint": "", "Name": "foobar_bar", "Scope": "", "Size": "N/A", "Status": "N/A"}, } @@ -158,7 +158,7 @@ func TestVolumeContextWriteJSON(t *testing.T) { } for i, line := range strings.Split(strings.TrimSpace(out.String()), "\n") { msg := fmt.Sprintf("Output: line %d: %s", i, line) - var m map[string]interface{} + var m map[string]any err := json.Unmarshal([]byte(line), &m) assert.NilError(t, err, msg) assert.Check(t, is.DeepEqual(expectedJSONs[i], m), msg) diff --git a/cli/command/idresolver/idresolver.go b/cli/command/idresolver/idresolver.go index 8eb4f54bfb..3ba6eacf5f 100644 --- a/cli/command/idresolver/idresolver.go +++ b/cli/command/idresolver/idresolver.go @@ -25,7 +25,7 @@ func New(apiClient client.APIClient, noResolve bool) *IDResolver { } } -func (r *IDResolver) get(ctx context.Context, t interface{}, id string) (string, error) { +func (r *IDResolver) get(ctx context.Context, t any, id string) (string, error) { switch t.(type) { case swarm.Node: node, _, err := r.client.NodeInspectWithRaw(ctx, id) @@ -55,7 +55,7 @@ func (r *IDResolver) get(ctx context.Context, t interface{}, id string) (string, // Resolve will attempt to resolve an ID to a Name by querying the manager. // Results are stored into a cache. // If the `-n` flag is used in the command-line, resolution is disabled. -func (r *IDResolver) Resolve(ctx context.Context, t interface{}, id string) (string, error) { +func (r *IDResolver) Resolve(ctx context.Context, t any, id string) (string, error) { if r.noResolve { return id, nil } diff --git a/cli/command/image/inspect.go b/cli/command/image/inspect.go index 2e3d5bf086..0f9a918192 100644 --- a/cli/command/image/inspect.go +++ b/cli/command/image/inspect.go @@ -38,7 +38,7 @@ func runInspect(dockerCli command.Cli, opts inspectOptions) error { client := dockerCli.Client() ctx := context.Background() - getRefFunc := func(ref string) (interface{}, []byte, error) { + getRefFunc := func(ref string) (any, []byte, error) { return client.ImageInspectWithRaw(ctx, ref) } return inspect.Inspect(dockerCli.Out(), opts.refs, opts.format, getRefFunc) diff --git a/cli/command/inspect/inspector.go b/cli/command/inspect/inspector.go index 4a6f210807..15078cc0d1 100644 --- a/cli/command/inspect/inspector.go +++ b/cli/command/inspect/inspector.go @@ -16,7 +16,7 @@ import ( // Inspector defines an interface to implement to process elements type Inspector interface { // Inspect writes the raw element in JSON format. - Inspect(typedElement interface{}, rawElement []byte) error + Inspect(typedElement any, rawElement []byte) error // Flush writes the result of inspecting all elements into the output stream. Flush() error } @@ -57,7 +57,7 @@ func NewTemplateInspectorFromString(out io.Writer, tmplStr string) (Inspector, e // GetRefFunc is a function which used by Inspect to fetch an object from a // reference -type GetRefFunc func(ref string) (interface{}, []byte, error) +type GetRefFunc func(ref string) (any, []byte, error) // Inspect fetches objects by reference using GetRefFunc and writes the json // representation to the output writer. @@ -96,7 +96,7 @@ func Inspect(out io.Writer, references []string, tmplStr string, getRef GetRefFu // Inspect executes the inspect template. // It decodes the raw element into a map if the initial execution fails. // This allows docker cli to parse inspect structs injected with Swarm fields. -func (i *TemplateInspector) Inspect(typedElement interface{}, rawElement []byte) error { +func (i *TemplateInspector) Inspect(typedElement any, rawElement []byte) error { buffer := new(bytes.Buffer) if err := i.tmpl.Execute(buffer, typedElement); err != nil { if rawElement == nil { @@ -112,7 +112,7 @@ func (i *TemplateInspector) Inspect(typedElement interface{}, rawElement []byte) // tryRawInspectFallback executes the inspect template with a raw interface. // This allows docker cli to parse inspect structs injected with Swarm fields. func (i *TemplateInspector) tryRawInspectFallback(rawElement []byte) error { - var raw interface{} + var raw any buffer := new(bytes.Buffer) rdr := bytes.NewReader(rawElement) dec := json.NewDecoder(rdr) @@ -150,7 +150,7 @@ func NewIndentedInspector(outputStream io.Writer) Inspector { raw: func(dst *bytes.Buffer, src []byte) error { return json.Indent(dst, src, "", " ") }, - el: func(v interface{}) ([]byte, error) { + el: func(v any) ([]byte, error) { return json.MarshalIndent(v, "", " ") }, } @@ -168,13 +168,13 @@ func NewJSONInspector(outputStream io.Writer) Inspector { type elementsInspector struct { outputStream io.Writer - elements []interface{} + elements []any rawElements [][]byte raw func(dst *bytes.Buffer, src []byte) error - el func(v interface{}) ([]byte, error) + el func(v any) ([]byte, error) } -func (e *elementsInspector) Inspect(typedElement interface{}, rawElement []byte) error { +func (e *elementsInspector) Inspect(typedElement any, rawElement []byte) error { if rawElement != nil { e.rawElements = append(e.rawElements, rawElement) } else { diff --git a/cli/command/network/formatter_test.go b/cli/command/network/formatter_test.go index b7807cd536..301428cd9a 100644 --- a/cli/command/network/formatter_test.go +++ b/cli/command/network/formatter_test.go @@ -177,7 +177,7 @@ func TestNetworkContextWriteJSON(t *testing.T) { {ID: "networkID1", Name: "foobar_baz"}, {ID: "networkID2", Name: "foobar_bar"}, } - expectedJSONs := []map[string]interface{}{ + expectedJSONs := []map[string]any{ {"Driver": "", "ID": "networkID1", "IPv6": "false", "Internal": "false", "Labels": "", "Name": "foobar_baz", "Scope": "", "CreatedAt": "0001-01-01 00:00:00 +0000 UTC"}, {"Driver": "", "ID": "networkID2", "IPv6": "false", "Internal": "false", "Labels": "", "Name": "foobar_bar", "Scope": "", "CreatedAt": "0001-01-01 00:00:00 +0000 UTC"}, } @@ -189,7 +189,7 @@ func TestNetworkContextWriteJSON(t *testing.T) { } for i, line := range strings.Split(strings.TrimSpace(out.String()), "\n") { msg := fmt.Sprintf("Output: line %d: %s", i, line) - var m map[string]interface{} + var m map[string]any err := json.Unmarshal([]byte(line), &m) assert.NilError(t, err, msg) assert.Check(t, is.DeepEqual(expectedJSONs[i], m), msg) diff --git a/cli/command/network/inspect.go b/cli/command/network/inspect.go index 33dba10df7..621b14a41d 100644 --- a/cli/command/network/inspect.go +++ b/cli/command/network/inspect.go @@ -43,7 +43,7 @@ func runInspect(dockerCli command.Cli, opts inspectOptions) error { ctx := context.Background() - getNetFunc := func(name string) (interface{}, []byte, error) { + getNetFunc := func(name string) (any, []byte, error) { return client.NetworkInspectWithRaw(ctx, name, types.NetworkInspectOptions{Verbose: opts.verbose}) } diff --git a/cli/command/node/formatter_test.go b/cli/command/node/formatter_test.go index 1d35623e47..cd5a4f12c2 100644 --- a/cli/command/node/formatter_test.go +++ b/cli/command/node/formatter_test.go @@ -216,11 +216,11 @@ foobar_boo Unknown func TestNodeContextWriteJSON(t *testing.T) { cases := []struct { - expected []map[string]interface{} + expected []map[string]any info system.Info }{ { - expected: []map[string]interface{}{ + expected: []map[string]any{ {"Availability": "", "Hostname": "foobar_baz", "ID": "nodeID1", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Unknown", "EngineVersion": "1.2.3"}, {"Availability": "", "Hostname": "foobar_bar", "ID": "nodeID2", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Unknown", "EngineVersion": ""}, {"Availability": "", "Hostname": "foobar_boo", "ID": "nodeID3", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Unknown", "EngineVersion": "18.03.0-ce"}, @@ -228,7 +228,7 @@ func TestNodeContextWriteJSON(t *testing.T) { info: system.Info{}, }, { - expected: []map[string]interface{}{ + expected: []map[string]any{ {"Availability": "", "Hostname": "foobar_baz", "ID": "nodeID1", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Ready", "EngineVersion": "1.2.3"}, {"Availability": "", "Hostname": "foobar_bar", "ID": "nodeID2", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Needs Rotation", "EngineVersion": ""}, {"Availability": "", "Hostname": "foobar_boo", "ID": "nodeID3", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Unknown", "EngineVersion": "18.03.0-ce"}, @@ -257,7 +257,7 @@ func TestNodeContextWriteJSON(t *testing.T) { } for i, line := range strings.Split(strings.TrimSpace(out.String()), "\n") { msg := fmt.Sprintf("Output: line %d: %s", i, line) - var m map[string]interface{} + var m map[string]any err := json.Unmarshal([]byte(line), &m) assert.NilError(t, err, msg) assert.Check(t, is.DeepEqual(testcase.expected[i], m), msg) @@ -319,7 +319,7 @@ func TestNodeInspectWriteContext(t *testing.T) { Format: NewFormat("pretty", false), Output: out, } - err := InspectFormatWrite(context, []string{"nodeID1"}, func(string) (interface{}, []byte, error) { + err := InspectFormatWrite(context, []string{"nodeID1"}, func(string) (any, []byte, error) { return node, nil, nil }) if err != nil { diff --git a/cli/command/node/inspect.go b/cli/command/node/inspect.go index 96abfd1927..4073bc995e 100644 --- a/cli/command/node/inspect.go +++ b/cli/command/node/inspect.go @@ -45,7 +45,7 @@ func runInspect(dockerCli command.Cli, opts inspectOptions) error { opts.format = "pretty" } - getRef := func(ref string) (interface{}, []byte, error) { + getRef := func(ref string) (any, []byte, error) { nodeRef, err := Reference(ctx, client, ref) if err != nil { return nil, nil, err diff --git a/cli/command/plugin/formatter_test.go b/cli/command/plugin/formatter_test.go index a5e1a4b1f7..85be3927a5 100644 --- a/cli/command/plugin/formatter_test.go +++ b/cli/command/plugin/formatter_test.go @@ -148,7 +148,7 @@ func TestPluginContextWriteJSON(t *testing.T) { {ID: "pluginID1", Name: "foobar_baz"}, {ID: "pluginID2", Name: "foobar_bar"}, } - expectedJSONs := []map[string]interface{}{ + expectedJSONs := []map[string]any{ {"Description": "", "Enabled": false, "ID": "pluginID1", "Name": "foobar_baz", "PluginReference": ""}, {"Description": "", "Enabled": false, "ID": "pluginID2", "Name": "foobar_bar", "PluginReference": ""}, } @@ -159,7 +159,7 @@ func TestPluginContextWriteJSON(t *testing.T) { t.Fatal(err) } for i, line := range strings.Split(strings.TrimSpace(out.String()), "\n") { - var m map[string]interface{} + var m map[string]any if err := json.Unmarshal([]byte(line), &m); err != nil { t.Fatal(err) } diff --git a/cli/command/plugin/inspect.go b/cli/command/plugin/inspect.go index c84711af2b..08085792a5 100644 --- a/cli/command/plugin/inspect.go +++ b/cli/command/plugin/inspect.go @@ -36,7 +36,7 @@ func newInspectCommand(dockerCli command.Cli) *cobra.Command { func runInspect(dockerCli command.Cli, opts inspectOptions) error { client := dockerCli.Client() ctx := context.Background() - getRef := func(ref string) (interface{}, []byte, error) { + getRef := func(ref string) (any, []byte, error) { return client.PluginInspectWithRaw(ctx, ref) } diff --git a/cli/command/secret/inspect.go b/cli/command/secret/inspect.go index 2b63ecc4b2..a3e6e10724 100644 --- a/cli/command/secret/inspect.go +++ b/cli/command/secret/inspect.go @@ -46,7 +46,7 @@ func runSecretInspect(dockerCli command.Cli, opts inspectOptions) error { opts.format = "pretty" } - getRef := func(id string) (interface{}, []byte, error) { + getRef := func(id string) (any, []byte, error) { return client.SecretInspectWithRaw(ctx, id) } f := opts.format diff --git a/cli/command/service/formatter_test.go b/cli/command/service/formatter_test.go index 574f57e30d..2c5db65911 100644 --- a/cli/command/service/formatter_test.go +++ b/cli/command/service/formatter_test.go @@ -283,7 +283,7 @@ func TestServiceContextWriteJSON(t *testing.T) { }, }, } - expectedJSONs := []map[string]interface{}{ + expectedJSONs := []map[string]any{ {"ID": "02_bar", "Name": "bar", "Mode": "replicated", "Replicas": "2/4", "Image": "", "Ports": "*:80->8080/tcp"}, {"ID": "01_baz", "Name": "baz", "Mode": "global", "Replicas": "1/3", "Image": "", "Ports": "*:80->8080/tcp"}, } @@ -295,7 +295,7 @@ func TestServiceContextWriteJSON(t *testing.T) { } for i, line := range strings.Split(strings.TrimSpace(out.String()), "\n") { msg := fmt.Sprintf("Output: line %d: %s", i, line) - var m map[string]interface{} + var m map[string]any err := json.Unmarshal([]byte(line), &m) assert.NilError(t, err, msg) assert.Check(t, is.DeepEqual(expectedJSONs[i], m), msg) diff --git a/cli/command/service/inspect.go b/cli/command/service/inspect.go index d026ab062e..ac76c70dbc 100644 --- a/cli/command/service/inspect.go +++ b/cli/command/service/inspect.go @@ -54,7 +54,7 @@ func runInspect(dockerCli command.Cli, opts inspectOptions) error { opts.format = "pretty" } - getRef := func(ref string) (interface{}, []byte, error) { + getRef := func(ref string) (any, []byte, error) { // Service inspect shows defaults values in empty fields. service, _, err := client.ServiceInspectWithRaw(ctx, ref, types.ServiceInspectOptions{InsertDefaults: true}) if err == nil || !errdefs.IsNotFound(err) { @@ -63,7 +63,7 @@ func runInspect(dockerCli command.Cli, opts inspectOptions) error { return nil, nil, errors.Errorf("Error: no such service: %s", ref) } - getNetwork := func(ref string) (interface{}, []byte, error) { + getNetwork := func(ref string) (any, []byte, error) { network, _, err := client.NetworkInspectWithRaw(ctx, ref, types.NetworkInspectOptions{Scope: "swarm"}) if err == nil || !errdefs.IsNotFound(err) { return network, nil, err diff --git a/cli/command/service/inspect_test.go b/cli/command/service/inspect_test.go index 04c2bdec6b..7b6ab1998a 100644 --- a/cli/command/service/inspect_test.go +++ b/cli/command/service/inspect_test.go @@ -129,10 +129,10 @@ func formatServiceInspect(t *testing.T, format formatter.Format, now time.Time) } err := InspectFormatWrite(ctx, []string{"de179gar9d0o7ltdybungplod"}, - func(ref string) (interface{}, []byte, error) { + func(ref string) (any, []byte, error) { return s, nil, nil }, - func(ref string) (interface{}, []byte, error) { + func(ref string) (any, []byte, error) { return types.NetworkResource{ ID: "5vpyomhb6ievnk0i0o60gcnei", Name: "mynetwork", @@ -166,7 +166,7 @@ func TestJSONFormatWithNoUpdateConfig(t *testing.T) { // s2: {"ID":..} s1 := formatServiceInspect(t, NewFormat(""), now) s2 := formatServiceInspect(t, NewFormat("{{json .}}"), now) - var m1Wrap []map[string]interface{} + var m1Wrap []map[string]any if err := json.Unmarshal([]byte(s1), &m1Wrap); err != nil { t.Fatal(err) } @@ -174,7 +174,7 @@ func TestJSONFormatWithNoUpdateConfig(t *testing.T) { t.Fatalf("strange s1=%s", s1) } m1 := m1Wrap[0] - var m2 map[string]interface{} + var m2 map[string]any if err := json.Unmarshal([]byte(s2), &m2); err != nil { t.Fatal(err) } diff --git a/cli/command/service/opts.go b/cli/command/service/opts.go index 09dff46ef4..0d96ea4ed5 100644 --- a/cli/command/service/opts.go +++ b/cli/command/service/opts.go @@ -770,7 +770,7 @@ func (options *serviceOptions) ToService(ctx context.Context, apiClient client.N return service, nil } -type flagDefaults map[string]interface{} +type flagDefaults map[string]any func (fd flagDefaults) getUint64(flagName string) uint64 { if val, ok := fd[flagName].(uint64); ok { @@ -787,7 +787,7 @@ func (fd flagDefaults) getString(flagName string) string { } func buildServiceDefaultFlagMapping() flagDefaults { - defaultFlagValues := make(map[string]interface{}) + defaultFlagValues := make(map[string]any) defaultFlagValues[flagStopGracePeriod], _ = gogotypes.DurationFromProto(defaults.Service.Task.GetContainer().StopGracePeriod) defaultFlagValues[flagRestartCondition] = `"` + defaultRestartCondition() + `"` diff --git a/cli/command/stack/loader/loader.go b/cli/command/stack/loader/loader.go index 39df5d05f7..2f41655b19 100644 --- a/cli/command/stack/loader/loader.go +++ b/cli/command/stack/loader/loader.go @@ -50,8 +50,8 @@ func LoadComposefile(dockerCli command.Cli, opts options.Deploy) (*composetypes. return config, nil } -func getDictsFrom(configFiles []composetypes.ConfigFile) []map[string]interface{} { - dicts := []map[string]interface{}{} +func getDictsFrom(configFiles []composetypes.ConfigFile) []map[string]any { + dicts := []map[string]any{} for _, configFile := range configFiles { dicts = append(dicts, configFile.Config) diff --git a/cli/command/system/inspect.go b/cli/command/system/inspect.go index 26c0f8a2b1..a5e79c625f 100644 --- a/cli/command/system/inspect.go +++ b/cli/command/system/inspect.go @@ -56,56 +56,56 @@ func runInspect(dockerCli command.Cli, opts inspectOptions) error { } func inspectContainers(ctx context.Context, dockerCli command.Cli, getSize bool) inspect.GetRefFunc { - return func(ref string) (interface{}, []byte, error) { + return func(ref string) (any, []byte, error) { return dockerCli.Client().ContainerInspectWithRaw(ctx, ref, getSize) } } func inspectImages(ctx context.Context, dockerCli command.Cli) inspect.GetRefFunc { - return func(ref string) (interface{}, []byte, error) { + return func(ref string) (any, []byte, error) { return dockerCli.Client().ImageInspectWithRaw(ctx, ref) } } func inspectNetwork(ctx context.Context, dockerCli command.Cli) inspect.GetRefFunc { - return func(ref string) (interface{}, []byte, error) { + return func(ref string) (any, []byte, error) { return dockerCli.Client().NetworkInspectWithRaw(ctx, ref, types.NetworkInspectOptions{}) } } func inspectNode(ctx context.Context, dockerCli command.Cli) inspect.GetRefFunc { - return func(ref string) (interface{}, []byte, error) { + return func(ref string) (any, []byte, error) { return dockerCli.Client().NodeInspectWithRaw(ctx, ref) } } func inspectService(ctx context.Context, dockerCli command.Cli) inspect.GetRefFunc { - return func(ref string) (interface{}, []byte, error) { + return func(ref string) (any, []byte, error) { // Service inspect shows defaults values in empty fields. return dockerCli.Client().ServiceInspectWithRaw(ctx, ref, types.ServiceInspectOptions{InsertDefaults: true}) } } func inspectTasks(ctx context.Context, dockerCli command.Cli) inspect.GetRefFunc { - return func(ref string) (interface{}, []byte, error) { + return func(ref string) (any, []byte, error) { return dockerCli.Client().TaskInspectWithRaw(ctx, ref) } } func inspectVolume(ctx context.Context, dockerCli command.Cli) inspect.GetRefFunc { - return func(ref string) (interface{}, []byte, error) { + return func(ref string) (any, []byte, error) { return dockerCli.Client().VolumeInspectWithRaw(ctx, ref) } } func inspectPlugin(ctx context.Context, dockerCli command.Cli) inspect.GetRefFunc { - return func(ref string) (interface{}, []byte, error) { + return func(ref string) (any, []byte, error) { return dockerCli.Client().PluginInspectWithRaw(ctx, ref) } } func inspectSecret(ctx context.Context, dockerCli command.Cli) inspect.GetRefFunc { - return func(ref string) (interface{}, []byte, error) { + return func(ref string) (any, []byte, error) { return dockerCli.Client().SecretInspectWithRaw(ctx, ref) } } @@ -115,7 +115,7 @@ func inspectAll(ctx context.Context, dockerCli command.Cli, getSize bool, typeCo objectType string isSizeSupported bool isSwarmObject bool - objectInspector func(string) (interface{}, []byte, error) + objectInspector func(string) (any, []byte, error) }{ { objectType: "container", @@ -171,7 +171,7 @@ func inspectAll(ctx context.Context, dockerCli command.Cli, getSize bool, typeCo return info.Swarm.ControlAvailable } - return func(ref string) (interface{}, []byte, error) { + return func(ref string) (any, []byte, error) { const ( swarmSupportUnknown = iota swarmSupported diff --git a/cli/command/trust/inspect.go b/cli/command/trust/inspect.go index 3dd40b1cfc..b2040d2838 100644 --- a/cli/command/trust/inspect.go +++ b/cli/command/trust/inspect.go @@ -56,7 +56,7 @@ func runInspect(dockerCLI command.Cli, opts inspectOptions) error { return err } - getRefFunc := func(ref string) (interface{}, []byte, error) { + getRefFunc := func(ref string) (any, []byte, error) { i, err := getRepoTrustInfo(dockerCLI, ref) return nil, i, err } diff --git a/cli/command/utils.go b/cli/command/utils.go index d55d5dc28a..622b67b98f 100644 --- a/cli/command/utils.go +++ b/cli/command/utils.go @@ -58,7 +58,7 @@ func capitalizeFirst(s string) string { } // PrettyPrint outputs arbitrary data for human formatted output by uppercasing the first letter. -func PrettyPrint(i interface{}) string { +func PrettyPrint(i any) string { switch t := i.(type) { case nil: return "None" diff --git a/cli/command/volume/inspect.go b/cli/command/volume/inspect.go index 4bf35b26b8..6cff6b6178 100644 --- a/cli/command/volume/inspect.go +++ b/cli/command/volume/inspect.go @@ -40,7 +40,7 @@ func runInspect(dockerCli command.Cli, opts inspectOptions) error { ctx := context.Background() - getVolFunc := func(name string) (interface{}, []byte, error) { + getVolFunc := func(name string) (any, []byte, error) { i, err := client.VolumeInspect(ctx, name) return i, nil, err } diff --git a/cli/compose/interpolation/interpolation.go b/cli/compose/interpolation/interpolation.go index e84756dba6..f597b7552d 100644 --- a/cli/compose/interpolation/interpolation.go +++ b/cli/compose/interpolation/interpolation.go @@ -25,10 +25,10 @@ type Options struct { type LookupValue func(key string) (string, bool) // Cast a value to a new type, or return an error if the value can't be cast -type Cast func(value string) (interface{}, error) +type Cast func(value string) (any, error) // Interpolate replaces variables in a string with the values from a mapping -func Interpolate(config map[string]interface{}, opts Options) (map[string]interface{}, error) { +func Interpolate(config map[string]any, opts Options) (map[string]any, error) { if opts.LookupValue == nil { opts.LookupValue = os.LookupEnv } @@ -39,7 +39,7 @@ func Interpolate(config map[string]interface{}, opts Options) (map[string]interf opts.Substitute = template.Substitute } - out := map[string]interface{}{} + out := map[string]any{} for key, value := range config { interpolatedValue, err := recursiveInterpolate(value, NewPath(key), opts) @@ -52,7 +52,7 @@ func Interpolate(config map[string]interface{}, opts Options) (map[string]interf return out, nil } -func recursiveInterpolate(value interface{}, path Path, opts Options) (interface{}, error) { +func recursiveInterpolate(value any, path Path, opts Options) (any, error) { switch value := value.(type) { case string: newValue, err := opts.Substitute(value, template.Mapping(opts.LookupValue)) @@ -66,8 +66,8 @@ func recursiveInterpolate(value interface{}, path Path, opts Options) (interface casted, err := caster(newValue) return casted, newPathError(path, errors.Wrap(err, "failed to cast to expected type")) - case map[string]interface{}: - out := map[string]interface{}{} + case map[string]any: + out := map[string]any{} for key, elem := range value { interpolatedElem, err := recursiveInterpolate(elem, path.Next(key), opts) if err != nil { @@ -77,8 +77,8 @@ func recursiveInterpolate(value interface{}, path Path, opts Options) (interface } return out, nil - case []interface{}: - out := make([]interface{}, len(value)) + case []any: + out := make([]any, len(value)) for i, elem := range value { interpolatedElem, err := recursiveInterpolate(elem, path.Next(PathMatchList), opts) if err != nil { diff --git a/cli/compose/interpolation/interpolation_test.go b/cli/compose/interpolation/interpolation_test.go index 069d8d2549..4b74dc352d 100644 --- a/cli/compose/interpolation/interpolation_test.go +++ b/cli/compose/interpolation/interpolation_test.go @@ -20,25 +20,25 @@ func defaultMapping(name string) (string, bool) { } func TestInterpolate(t *testing.T) { - services := map[string]interface{}{ - "servicea": map[string]interface{}{ + services := map[string]any{ + "servicea": map[string]any{ "image": "example:${USER}", - "volumes": []interface{}{"$FOO:/target"}, - "logging": map[string]interface{}{ + "volumes": []any{"$FOO:/target"}, + "logging": map[string]any{ "driver": "${FOO}", - "options": map[string]interface{}{ + "options": map[string]any{ "user": "$USER", }, }, }, } - expected := map[string]interface{}{ - "servicea": map[string]interface{}{ + expected := map[string]any{ + "servicea": map[string]any{ "image": "example:jenny", - "volumes": []interface{}{"bar:/target"}, - "logging": map[string]interface{}{ + "volumes": []any{"bar:/target"}, + "logging": map[string]any{ "driver": "bar", - "options": map[string]interface{}{ + "options": map[string]any{ "user": "jenny", }, }, @@ -50,8 +50,8 @@ func TestInterpolate(t *testing.T) { } func TestInvalidInterpolation(t *testing.T) { - services := map[string]interface{}{ - "servicea": map[string]interface{}{ + services := map[string]any{ + "servicea": map[string]any{ "image": "${", }, } @@ -62,13 +62,13 @@ func TestInvalidInterpolation(t *testing.T) { func TestInterpolateWithDefaults(t *testing.T) { t.Setenv("FOO", "BARZ") - config := map[string]interface{}{ - "networks": map[string]interface{}{ + config := map[string]any{ + "networks": map[string]any{ "foo": "thing_${FOO}", }, } - expected := map[string]interface{}{ - "networks": map[string]interface{}{ + expected := map[string]any{ + "networks": map[string]any{ "foo": "thing_BARZ", }, } @@ -78,12 +78,12 @@ func TestInterpolateWithDefaults(t *testing.T) { } func TestInterpolateWithCast(t *testing.T) { - config := map[string]interface{}{ - "foo": map[string]interface{}{ + config := map[string]any{ + "foo": map[string]any{ "replicas": "$count", }, } - toInt := func(value string) (interface{}, error) { + toInt := func(value string) (any, error) { return strconv.Atoi(value) } result, err := Interpolate(config, Options{ @@ -91,8 +91,8 @@ func TestInterpolateWithCast(t *testing.T) { TypeCastMapping: map[Path]Cast{NewPath(PathMatchAll, "replicas"): toInt}, }) assert.NilError(t, err) - expected := map[string]interface{}{ - "foo": map[string]interface{}{ + expected := map[string]any{ + "foo": map[string]any{ "replicas": 5, }, } diff --git a/cli/compose/loader/full-struct_test.go b/cli/compose/loader/full-struct_test.go index 57f5e12567..a4937465bb 100644 --- a/cli/compose/loader/full-struct_test.go +++ b/cli/compose/loader/full-struct_test.go @@ -14,10 +14,10 @@ func fullExampleConfig(workingDir, homeDir string) *types.Config { Volumes: volumes(), Configs: configs(workingDir), Secrets: secrets(workingDir), - Extras: map[string]interface{}{ + Extras: map[string]any{ "x-foo": "bar", "x-bar": "baz", - "x-nested": map[string]interface{}{ + "x-nested": map[string]any{ "foo": "bar", "bar": "baz", }, @@ -149,7 +149,7 @@ func services(workingDir, homeDir string) []types.ServiceConfig { "otherhost:50.31.209.229", "host.docker.internal:host-gateway", }, - Extras: map[string]interface{}{ + Extras: map[string]any{ "x-bar": "baz", "x-foo": "bar", }, @@ -415,7 +415,7 @@ func networks() map[string]types.NetworkConfig { "other-external-network": { Name: "my-cool-network", External: types.External{External: true}, - Extras: map[string]interface{}{ + Extras: map[string]any{ "x-bar": "baz", "x-foo": "bar", }, @@ -455,7 +455,7 @@ func volumes() map[string]types.VolumeConfig { "external-volume3": { Name: "this-is-volume3", External: types.External{External: true}, - Extras: map[string]interface{}{ + Extras: map[string]any{ "x-bar": "baz", "x-foo": "bar", }, @@ -517,7 +517,7 @@ func configs(workingDir string) map[string]types.ConfigObjConfig { "config4": { Name: "foo", File: workingDir, - Extras: map[string]interface{}{ + Extras: map[string]any{ "x-bar": "baz", "x-foo": "bar", }, @@ -544,7 +544,7 @@ func secrets(workingDir string) map[string]types.SecretConfig { "secret4": { Name: "bar", File: workingDir, - Extras: map[string]interface{}{ + Extras: map[string]any{ "x-bar": "baz", "x-foo": "bar", }, diff --git a/cli/compose/loader/interpolate.go b/cli/compose/loader/interpolate.go index d25936be86..d04679d6d6 100644 --- a/cli/compose/loader/interpolate.go +++ b/cli/compose/loader/interpolate.go @@ -47,16 +47,16 @@ func servicePath(parts ...string) interp.Path { return iPath(append([]string{"services", interp.PathMatchAll}, parts...)...) } -func toInt(value string) (interface{}, error) { +func toInt(value string) (any, error) { return strconv.Atoi(value) } -func toFloat(value string) (interface{}, error) { +func toFloat(value string) (any, error) { return strconv.ParseFloat(value, 64) } // should match http://yaml.org/type/bool.html -func toBoolean(value string) (interface{}, error) { +func toBoolean(value string) (any, error) { switch strings.ToLower(value) { case "y", "yes", "true", "on": return true, nil @@ -67,6 +67,6 @@ func toBoolean(value string) (interface{}, error) { } } -func interpolateConfig(configDict map[string]interface{}, opts interp.Options) (map[string]interface{}, error) { +func interpolateConfig(configDict map[string]any, opts interp.Options) (map[string]any, error) { return interp.Interpolate(configDict, opts) } diff --git a/cli/compose/loader/loader.go b/cli/compose/loader/loader.go index 5f4ca29cdd..0a7d852d20 100644 --- a/cli/compose/loader/loader.go +++ b/cli/compose/loader/loader.go @@ -45,12 +45,12 @@ func WithDiscardEnvFiles(options *Options) { // ParseYAML reads the bytes from a file, parses the bytes into a mapping // structure, and returns it. -func ParseYAML(source []byte) (map[string]interface{}, error) { - var cfg interface{} +func ParseYAML(source []byte) (map[string]any, error) { + var cfg any if err := yaml.Unmarshal(source, &cfg); err != nil { return nil, err } - cfgMap, ok := cfg.(map[interface{}]interface{}) + cfgMap, ok := cfg.(map[any]any) if !ok { return nil, errors.Errorf("top-level object must be a mapping") } @@ -58,7 +58,7 @@ func ParseYAML(source []byte) (map[string]interface{}, error) { if err != nil { return nil, err } - return converted.(map[string]interface{}), nil + return converted.(map[string]any), nil } // Load reads a ConfigDetails and returns a fully loaded configuration @@ -126,8 +126,8 @@ func Load(configDetails types.ConfigDetails, opt ...func(*Options)) (*types.Conf return merge(configs) } -func validateForbidden(configDict map[string]interface{}) error { - servicesDict, ok := configDict["services"].(map[string]interface{}) +func validateForbidden(configDict map[string]any) error { + servicesDict, ok := configDict["services"].(map[string]any) if !ok { return nil } @@ -138,7 +138,7 @@ func validateForbidden(configDict map[string]interface{}) error { return nil } -func loadSections(config map[string]interface{}, configDetails types.ConfigDetails) (*types.Config, error) { +func loadSections(config map[string]any, configDetails types.ConfigDetails) (*types.Config, error) { var err error cfg := types.Config{ Version: schema.Version(config), @@ -146,39 +146,39 @@ func loadSections(config map[string]interface{}, configDetails types.ConfigDetai loaders := []struct { key string - fnc func(config map[string]interface{}) error + fnc func(config map[string]any) error }{ { key: "services", - fnc: func(config map[string]interface{}) error { + fnc: func(config map[string]any) error { cfg.Services, err = LoadServices(config, configDetails.WorkingDir, configDetails.LookupEnv) return err }, }, { key: "networks", - fnc: func(config map[string]interface{}) error { + fnc: func(config map[string]any) error { cfg.Networks, err = LoadNetworks(config, configDetails.Version) return err }, }, { key: "volumes", - fnc: func(config map[string]interface{}) error { + fnc: func(config map[string]any) error { cfg.Volumes, err = LoadVolumes(config, configDetails.Version) return err }, }, { key: "secrets", - fnc: func(config map[string]interface{}) error { + fnc: func(config map[string]any) error { cfg.Secrets, err = LoadSecrets(config, configDetails) return err }, }, { key: "configs", - fnc: func(config map[string]interface{}) error { + fnc: func(config map[string]any) error { cfg.Configs, err = LoadConfigObjs(config, configDetails) return err }, @@ -193,22 +193,22 @@ func loadSections(config map[string]interface{}, configDetails types.ConfigDetai return &cfg, nil } -func getSection(config map[string]interface{}, key string) map[string]interface{} { +func getSection(config map[string]any, key string) map[string]any { section, ok := config[key] if !ok { - return make(map[string]interface{}) + return make(map[string]any) } - return section.(map[string]interface{}) + return section.(map[string]any) } // GetUnsupportedProperties returns the list of any unsupported properties that are // used in the Compose files. -func GetUnsupportedProperties(configDicts ...map[string]interface{}) []string { +func GetUnsupportedProperties(configDicts ...map[string]any) []string { unsupported := map[string]bool{} for _, configDict := range configDicts { for _, service := range getServices(configDict) { - serviceDict := service.(map[string]interface{}) + serviceDict := service.(map[string]any) for _, property := range types.UnsupportedProperties { if _, isSet := serviceDict[property]; isSet { unsupported[property] = true @@ -231,7 +231,7 @@ func sortedKeys(set map[string]bool) []string { // GetDeprecatedProperties returns the list of any deprecated properties that // are used in the compose files. -func GetDeprecatedProperties(configDicts ...map[string]interface{}) map[string]string { +func GetDeprecatedProperties(configDicts ...map[string]any) map[string]string { deprecated := map[string]string{} for _, configDict := range configDicts { @@ -244,11 +244,11 @@ func GetDeprecatedProperties(configDicts ...map[string]interface{}) map[string]s return deprecated } -func getProperties(services map[string]interface{}, propertyMap map[string]string) map[string]string { +func getProperties(services map[string]any, propertyMap map[string]string) map[string]string { output := map[string]string{} for _, service := range services { - if serviceDict, ok := service.(map[string]interface{}); ok { + if serviceDict, ok := service.(map[string]any); ok { for property, description := range propertyMap { if _, isSet := serviceDict[property]; isSet { output[property] = description @@ -270,19 +270,19 @@ func (e *ForbiddenPropertiesError) Error() string { return "Configuration contains forbidden properties" } -func getServices(configDict map[string]interface{}) map[string]interface{} { +func getServices(configDict map[string]any) map[string]any { if services, ok := configDict["services"]; ok { - if servicesDict, ok := services.(map[string]interface{}); ok { + if servicesDict, ok := services.(map[string]any); ok { return servicesDict } } - return map[string]interface{}{} + return map[string]any{} } // Transform converts the source into the target struct with compose types transformer // and the specified transformers if any. -func Transform(source interface{}, target interface{}, additionalTransformers ...Transformer) error { +func Transform(source any, target any, additionalTransformers ...Transformer) error { data := mapstructure.Metadata{} config := &mapstructure.DecoderConfig{ DecodeHook: mapstructure.ComposeDecodeHookFunc( @@ -299,7 +299,7 @@ func Transform(source interface{}, target interface{}, additionalTransformers .. } // TransformerFunc defines a function to perform the actual transformation -type TransformerFunc func(interface{}) (interface{}, error) +type TransformerFunc func(any) (any, error) // Transformer defines a map to type transformer type Transformer struct { @@ -308,7 +308,7 @@ type Transformer struct { } func createTransformHook(additionalTransformers ...Transformer) mapstructure.DecodeHookFuncType { - transforms := map[reflect.Type]func(interface{}) (interface{}, error){ + transforms := map[reflect.Type]func(any) (any, error){ reflect.TypeOf(types.External{}): transformExternal, reflect.TypeOf(types.HealthCheckTest{}): transformHealthCheckTest, reflect.TypeOf(types.ShellCommand{}): transformShellCommand, @@ -335,7 +335,7 @@ func createTransformHook(additionalTransformers ...Transformer) mapstructure.Dec transforms[transformer.TypeOf] = transformer.Func } - return func(_ reflect.Type, target reflect.Type, data interface{}) (interface{}, error) { + return func(_ reflect.Type, target reflect.Type, data any) (any, error) { transform, ok := transforms[target] if !ok { return data, nil @@ -345,9 +345,9 @@ func createTransformHook(additionalTransformers ...Transformer) mapstructure.Dec } // keys needs to be converted to strings for jsonschema -func convertToStringKeysRecursive(value interface{}, keyPrefix string) (interface{}, error) { - if mapping, ok := value.(map[interface{}]interface{}); ok { - dict := make(map[string]interface{}) +func convertToStringKeysRecursive(value any, keyPrefix string) (any, error) { + if mapping, ok := value.(map[any]any); ok { + dict := make(map[string]any) for key, entry := range mapping { str, ok := key.(string) if !ok { @@ -367,8 +367,8 @@ func convertToStringKeysRecursive(value interface{}, keyPrefix string) (interfac } return dict, nil } - if list, ok := value.([]interface{}); ok { - var convertedList []interface{} + if list, ok := value.([]any); ok { + var convertedList []any for index, entry := range list { newKeyPrefix := fmt.Sprintf("%s[%d]", keyPrefix, index) convertedEntry, err := convertToStringKeysRecursive(entry, newKeyPrefix) @@ -382,7 +382,7 @@ func convertToStringKeysRecursive(value interface{}, keyPrefix string) (interfac return value, nil } -func formatInvalidKeyError(keyPrefix string, key interface{}) error { +func formatInvalidKeyError(keyPrefix string, key any) error { var location string if keyPrefix == "" { location = "at top level" @@ -394,11 +394,11 @@ func formatInvalidKeyError(keyPrefix string, key interface{}) error { // LoadServices produces a ServiceConfig map from a compose file Dict // the servicesDict is not validated if directly used. Use Load() to enable validation -func LoadServices(servicesDict map[string]interface{}, workingDir string, lookupEnv template.Mapping) ([]types.ServiceConfig, error) { +func LoadServices(servicesDict map[string]any, workingDir string, lookupEnv template.Mapping) ([]types.ServiceConfig, error) { services := make([]types.ServiceConfig, 0, len(servicesDict)) for name, serviceDef := range servicesDict { - serviceConfig, err := LoadService(name, serviceDef.(map[string]interface{}), workingDir, lookupEnv) + serviceConfig, err := LoadService(name, serviceDef.(map[string]any), workingDir, lookupEnv) if err != nil { return nil, err } @@ -410,7 +410,7 @@ func LoadServices(servicesDict map[string]interface{}, workingDir string, lookup // LoadService produces a single ServiceConfig from a compose file Dict // the serviceDict is not validated if directly used. Use Load() to enable validation -func LoadService(name string, serviceDict map[string]interface{}, workingDir string, lookupEnv template.Mapping) (*types.ServiceConfig, error) { +func LoadService(name string, serviceDict map[string]any, workingDir string, lookupEnv template.Mapping) (*types.ServiceConfig, error) { serviceConfig := &types.ServiceConfig{} if err := Transform(serviceDict, serviceConfig); err != nil { return nil, err @@ -430,15 +430,15 @@ func LoadService(name string, serviceDict map[string]interface{}, workingDir str return serviceConfig, nil } -func loadExtras(name string, source map[string]interface{}) map[string]interface{} { - if dict, ok := source[name].(map[string]interface{}); ok { +func loadExtras(name string, source map[string]any) map[string]any { + if dict, ok := source[name].(map[string]any); ok { return getExtras(dict) } return nil } -func getExtras(dict map[string]interface{}) map[string]interface{} { - extras := map[string]interface{}{} +func getExtras(dict map[string]any) map[string]any { + extras := map[string]any{} for key, value := range dict { if strings.HasPrefix(key, "x-") { extras[key] = value @@ -524,11 +524,11 @@ func expandUser(srcPath string, lookupEnv template.Mapping) string { return srcPath } -func transformUlimits(data interface{}) (interface{}, error) { +func transformUlimits(data any) (any, error) { switch value := data.(type) { case int: return types.UlimitsConfig{Single: value}, nil - case map[string]interface{}: + case map[string]any: ulimit := types.UlimitsConfig{} ulimit.Soft = value["soft"].(int) ulimit.Hard = value["hard"].(int) @@ -540,7 +540,7 @@ func transformUlimits(data interface{}) (interface{}, error) { // LoadNetworks produces a NetworkConfig map from a compose file Dict // the source Dict is not validated if directly used. Use Load() to enable validation -func LoadNetworks(source map[string]interface{}, version string) (map[string]types.NetworkConfig, error) { +func LoadNetworks(source map[string]any, version string) (map[string]types.NetworkConfig, error) { networks := make(map[string]types.NetworkConfig) err := Transform(source, &networks) if err != nil { @@ -577,7 +577,7 @@ func externalVolumeError(volume, key string) error { // LoadVolumes produces a VolumeConfig map from a compose file Dict // the source Dict is not validated if directly used. Use Load() to enable validation -func LoadVolumes(source map[string]interface{}, version string) (map[string]types.VolumeConfig, error) { +func LoadVolumes(source map[string]any, version string) (map[string]types.VolumeConfig, error) { volumes := make(map[string]types.VolumeConfig) if err := Transform(source, &volumes); err != nil { return volumes, err @@ -614,7 +614,7 @@ func LoadVolumes(source map[string]interface{}, version string) (map[string]type // LoadSecrets produces a SecretConfig map from a compose file Dict // the source Dict is not validated if directly used. Use Load() to enable validation -func LoadSecrets(source map[string]interface{}, details types.ConfigDetails) (map[string]types.SecretConfig, error) { +func LoadSecrets(source map[string]any, details types.ConfigDetails) (map[string]types.SecretConfig, error) { secrets := make(map[string]types.SecretConfig) if err := Transform(source, &secrets); err != nil { return secrets, err @@ -633,7 +633,7 @@ func LoadSecrets(source map[string]interface{}, details types.ConfigDetails) (ma // LoadConfigObjs produces a ConfigObjConfig map from a compose file Dict // the source Dict is not validated if directly used. Use Load() to enable validation -func LoadConfigObjs(source map[string]interface{}, details types.ConfigDetails) (map[string]types.ConfigObjConfig, error) { +func LoadConfigObjs(source map[string]any, details types.ConfigDetails) (map[string]types.ConfigObjConfig, error) { configs := make(map[string]types.ConfigObjConfig) if err := Transform(source, &configs); err != nil { return configs, err @@ -686,9 +686,9 @@ func absPath(workingDir string, filePath string) string { return filepath.Join(workingDir, filePath) } -var transformMapStringString TransformerFunc = func(data interface{}) (interface{}, error) { +var transformMapStringString TransformerFunc = func(data any) (any, error) { switch value := data.(type) { - case map[string]interface{}: + case map[string]any: return toMapStringString(value, false), nil case map[string]string: return value, nil @@ -697,24 +697,24 @@ var transformMapStringString TransformerFunc = func(data interface{}) (interface } } -var transformExternal TransformerFunc = func(data interface{}) (interface{}, error) { +var transformExternal TransformerFunc = func(data any) (any, error) { switch value := data.(type) { case bool: - return map[string]interface{}{"external": value}, nil - case map[string]interface{}: - return map[string]interface{}{"external": true, "name": value["name"]}, nil + return map[string]any{"external": value}, nil + case map[string]any: + return map[string]any{"external": true, "name": value["name"]}, nil default: return data, errors.Errorf("invalid type %T for external", value) } } -var transformServicePort TransformerFunc = func(data interface{}) (interface{}, error) { +var transformServicePort TransformerFunc = func(data any) (any, error) { switch entries := data.(type) { - case []interface{}: + case []any: // We process the list instead of individual items here. // The reason is that one entry might be mapped to multiple ServicePortConfig. // Therefore we take an input of a list and return an output of a list. - ports := []interface{}{} + ports := []any{} for _, entry := range entries { switch value := entry.(type) { case int: @@ -729,7 +729,7 @@ var transformServicePort TransformerFunc = func(data interface{}) (interface{}, return data, err } ports = append(ports, v...) - case map[string]interface{}: + case map[string]any: ports = append(ports, value) default: return data, errors.Errorf("invalid type %T for port", value) @@ -741,42 +741,42 @@ var transformServicePort TransformerFunc = func(data interface{}) (interface{}, } } -var transformStringSourceMap TransformerFunc = func(data interface{}) (interface{}, error) { +var transformStringSourceMap TransformerFunc = func(data any) (any, error) { switch value := data.(type) { case string: - return map[string]interface{}{"source": value}, nil - case map[string]interface{}: + return map[string]any{"source": value}, nil + case map[string]any: return data, nil default: return data, errors.Errorf("invalid type %T for secret", value) } } -var transformBuildConfig TransformerFunc = func(data interface{}) (interface{}, error) { +var transformBuildConfig TransformerFunc = func(data any) (any, error) { switch value := data.(type) { case string: - return map[string]interface{}{"context": value}, nil - case map[string]interface{}: + return map[string]any{"context": value}, nil + case map[string]any: return data, nil default: return data, errors.Errorf("invalid type %T for service build", value) } } -var transformServiceVolumeConfig TransformerFunc = func(data interface{}) (interface{}, error) { +var transformServiceVolumeConfig TransformerFunc = func(data any) (any, error) { switch value := data.(type) { case string: return ParseVolume(value) - case map[string]interface{}: + case map[string]any: return data, nil default: return data, errors.Errorf("invalid type %T for service volume", value) } } -var transformServiceNetworkMap TransformerFunc = func(value interface{}) (interface{}, error) { - if list, ok := value.([]interface{}); ok { - mapValue := map[interface{}]interface{}{} +var transformServiceNetworkMap TransformerFunc = func(value any) (any, error) { + if list, ok := value.([]any); ok { + mapValue := map[any]any{} for _, name := range list { mapValue[name] = nil } @@ -785,8 +785,8 @@ var transformServiceNetworkMap TransformerFunc = func(value interface{}) (interf return value, nil } -var transformStringOrNumberList TransformerFunc = func(value interface{}) (interface{}, error) { - list := value.([]interface{}) +var transformStringOrNumberList TransformerFunc = func(value any) (any, error) { + list := value.([]any) result := make([]string, len(list)) for i, item := range list { result[i] = fmt.Sprint(item) @@ -794,11 +794,11 @@ var transformStringOrNumberList TransformerFunc = func(value interface{}) (inter return result, nil } -var transformStringList TransformerFunc = func(data interface{}) (interface{}, error) { +var transformStringList TransformerFunc = func(data any) (any, error) { switch value := data.(type) { case string: return []string{value}, nil - case []interface{}: + case []any: return value, nil default: return data, errors.Errorf("invalid type %T for string list", value) @@ -806,33 +806,33 @@ var transformStringList TransformerFunc = func(data interface{}) (interface{}, e } func transformMappingOrListFunc(sep string, allowNil bool) TransformerFunc { - return func(data interface{}) (interface{}, error) { + return func(data any) (any, error) { return transformMappingOrList(data, sep, allowNil), nil } } func transformListOrMappingFunc(sep string, allowNil bool) TransformerFunc { - return func(data interface{}) (interface{}, error) { + return func(data any) (any, error) { return transformListOrMapping(data, sep, allowNil), nil } } -func transformListOrMapping(listOrMapping interface{}, sep string, allowNil bool) interface{} { +func transformListOrMapping(listOrMapping any, sep string, allowNil bool) any { switch value := listOrMapping.(type) { - case map[string]interface{}: + case map[string]any: return toStringList(value, sep, allowNil) - case []interface{}: + case []any: return listOrMapping } panic(errors.Errorf("expected a map or a list, got %T: %#v", listOrMapping, listOrMapping)) } -func transformMappingOrList(mappingOrList interface{}, sep string, allowNil bool) interface{} { +func transformMappingOrList(mappingOrList any, sep string, allowNil bool) any { switch values := mappingOrList.(type) { - case map[string]interface{}: + case map[string]any: return toMapStringString(values, allowNil) - case []interface{}: - result := make(map[string]interface{}) + case []any: + result := make(map[string]any) for _, v := range values { key, val, hasValue := strings.Cut(v.(string), sep) switch { @@ -849,25 +849,25 @@ func transformMappingOrList(mappingOrList interface{}, sep string, allowNil bool panic(errors.Errorf("expected a map or a list, got %T: %#v", mappingOrList, mappingOrList)) } -var transformShellCommand TransformerFunc = func(value interface{}) (interface{}, error) { +var transformShellCommand TransformerFunc = func(value any) (any, error) { if str, ok := value.(string); ok { return shlex.Split(str) } return value, nil } -var transformHealthCheckTest TransformerFunc = func(data interface{}) (interface{}, error) { +var transformHealthCheckTest TransformerFunc = func(data any) (any, error) { switch value := data.(type) { case string: return append([]string{"CMD-SHELL"}, value), nil - case []interface{}: + case []any: return value, nil default: return value, errors.Errorf("invalid type %T for healthcheck.test", value) } } -var transformSize TransformerFunc = func(value interface{}) (interface{}, error) { +var transformSize TransformerFunc = func(value any) (any, error) { switch value := value.(type) { case int: return int64(value), nil @@ -877,7 +877,7 @@ var transformSize TransformerFunc = func(value interface{}) (interface{}, error) panic(errors.Errorf("invalid type for size %T", value)) } -var transformStringToDuration TransformerFunc = func(value interface{}) (interface{}, error) { +var transformStringToDuration TransformerFunc = func(value any) (any, error) { switch value := value.(type) { case string: d, err := time.ParseDuration(value) @@ -890,8 +890,8 @@ var transformStringToDuration TransformerFunc = func(value interface{}) (interfa } } -func toServicePortConfigs(value string) ([]interface{}, error) { - var portConfigs []interface{} +func toServicePortConfigs(value string) ([]any, error) { + var portConfigs []any ports, portBindings, err := nat.ParsePortSpecs([]string{value}) if err != nil { @@ -923,15 +923,15 @@ func toServicePortConfigs(value string) ([]interface{}, error) { return portConfigs, nil } -func toMapStringString(value map[string]interface{}, allowNil bool) map[string]interface{} { - output := make(map[string]interface{}) +func toMapStringString(value map[string]any, allowNil bool) map[string]any { + output := make(map[string]any) for key, value := range value { output[key] = toString(value, allowNil) } return output } -func toString(value interface{}, allowNil bool) interface{} { +func toString(value any, allowNil bool) any { switch { case value != nil: return fmt.Sprint(value) @@ -942,7 +942,7 @@ func toString(value interface{}, allowNil bool) interface{} { } } -func toStringList(value map[string]interface{}, separator string, allowNil bool) []string { +func toStringList(value map[string]any, separator string, allowNil bool) []string { output := []string{} for key, value := range value { if value == nil && !allowNil { diff --git a/cli/compose/loader/loader_test.go b/cli/compose/loader/loader_test.go index 2c5af26071..9328c40204 100644 --- a/cli/compose/loader/loader_test.go +++ b/cli/compose/loader/loader_test.go @@ -16,7 +16,7 @@ import ( "gotest.tools/v3/skip" ) -func buildConfigDetails(source map[string]interface{}, env map[string]string) types.ConfigDetails { +func buildConfigDetails(source map[string]any, env map[string]string) types.ConfigDetails { workingDir, err := os.Getwd() if err != nil { panic(err) @@ -74,39 +74,39 @@ networks: - subnet: 172.28.0.0/16 ` -var sampleDict = map[string]interface{}{ +var sampleDict = map[string]any{ "version": "3", - "services": map[string]interface{}{ - "foo": map[string]interface{}{ + "services": map[string]any{ + "foo": map[string]any{ "image": "busybox", - "networks": map[string]interface{}{"with_me": nil}, + "networks": map[string]any{"with_me": nil}, }, - "bar": map[string]interface{}{ + "bar": map[string]any{ "image": "busybox", - "environment": []interface{}{"FOO=1"}, - "networks": []interface{}{"with_ipam"}, + "environment": []any{"FOO=1"}, + "networks": []any{"with_ipam"}, }, }, - "volumes": map[string]interface{}{ - "hello": map[string]interface{}{ + "volumes": map[string]any{ + "hello": map[string]any{ "driver": "default", - "driver_opts": map[string]interface{}{ + "driver_opts": map[string]any{ "beep": "boop", }, }, }, - "networks": map[string]interface{}{ - "default": map[string]interface{}{ + "networks": map[string]any{ + "default": map[string]any{ "driver": "bridge", - "driver_opts": map[string]interface{}{ + "driver_opts": map[string]any{ "beep": "boop", }, }, - "with_ipam": map[string]interface{}{ - "ipam": map[string]interface{}{ + "with_ipam": map[string]any{ + "ipam": map[string]any{ "driver": "default", - "config": []interface{}{ - map[string]interface{}{ + "config": []any{ + map[string]any{ "subnet": "172.28.0.0/16", }, }, @@ -254,7 +254,7 @@ services: assert.Check(t, is.Len(actual.Services, 1)) service := actual.Services[0] assert.Check(t, is.Equal("busybox", service.Image)) - extras := map[string]interface{}{ + extras := map[string]any{ "x-foo": "bar", } assert.Check(t, is.DeepEqual(extras, service.Extras)) @@ -1342,9 +1342,9 @@ func TestLoadVolumesWarnOnDeprecatedExternalNameVersion34(t *testing.T) { buf, cleanup := patchLogrus() defer cleanup() - source := map[string]interface{}{ - "foo": map[string]interface{}{ - "external": map[string]interface{}{ + source := map[string]any{ + "foo": map[string]any{ + "external": map[string]any{ "name": "oops", }, }, @@ -1372,9 +1372,9 @@ func TestLoadVolumesWarnOnDeprecatedExternalNameVersion33(t *testing.T) { buf, cleanup := patchLogrus() defer cleanup() - source := map[string]interface{}{ - "foo": map[string]interface{}{ - "external": map[string]interface{}{ + source := map[string]any{ + "foo": map[string]any{ + "external": map[string]any{ "name": "oops", }, }, @@ -1455,9 +1455,9 @@ func TestLoadSecretsWarnOnDeprecatedExternalNameVersion35(t *testing.T) { buf, cleanup := patchLogrus() defer cleanup() - source := map[string]interface{}{ - "foo": map[string]interface{}{ - "external": map[string]interface{}{ + source := map[string]any{ + "foo": map[string]any{ + "external": map[string]any{ "name": "oops", }, }, @@ -1481,9 +1481,9 @@ func TestLoadNetworksWarnOnDeprecatedExternalNameVersion35(t *testing.T) { buf, cleanup := patchLogrus() defer cleanup() - source := map[string]interface{}{ - "foo": map[string]interface{}{ - "external": map[string]interface{}{ + source := map[string]any{ + "foo": map[string]any{ + "external": map[string]any{ "name": "oops", }, }, @@ -1504,9 +1504,9 @@ func TestLoadNetworksWarnOnDeprecatedExternalNameVersion34(t *testing.T) { buf, cleanup := patchLogrus() defer cleanup() - source := map[string]interface{}{ - "foo": map[string]interface{}{ - "external": map[string]interface{}{ + source := map[string]any{ + "foo": map[string]any{ + "external": map[string]any{ "name": "oops", }, }, @@ -1665,17 +1665,17 @@ services: } func TestTransform(t *testing.T) { - source := []interface{}{ + source := []any{ "80-82:8080-8082", "90-92:8090-8092/udp", "85:8500", 8600, - map[string]interface{}{ + map[string]any{ "protocol": "udp", "target": 53, "published": 10053, }, - map[string]interface{}{ + map[string]any{ "mode": "host", "target": 22, "published": 10022, diff --git a/cli/compose/loader/merge.go b/cli/compose/loader/merge.go index e72b6d5e30..624a0a2592 100644 --- a/cli/compose/loader/merge.go +++ b/cli/compose/loader/merge.go @@ -83,55 +83,55 @@ func mergeServices(base, override []types.ServiceConfig) ([]types.ServiceConfig, return services, nil } -func toServiceSecretConfigsMap(s interface{}) (map[interface{}]interface{}, error) { +func toServiceSecretConfigsMap(s any) (map[any]any, error) { secrets, ok := s.([]types.ServiceSecretConfig) if !ok { return nil, errors.Errorf("not a serviceSecretConfig: %v", s) } - m := map[interface{}]interface{}{} + m := map[any]any{} for _, secret := range secrets { m[secret.Source] = secret } return m, nil } -func toServiceConfigObjConfigsMap(s interface{}) (map[interface{}]interface{}, error) { +func toServiceConfigObjConfigsMap(s any) (map[any]any, error) { secrets, ok := s.([]types.ServiceConfigObjConfig) if !ok { return nil, errors.Errorf("not a serviceSecretConfig: %v", s) } - m := map[interface{}]interface{}{} + m := map[any]any{} for _, secret := range secrets { m[secret.Source] = secret } return m, nil } -func toServicePortConfigsMap(s interface{}) (map[interface{}]interface{}, error) { +func toServicePortConfigsMap(s any) (map[any]any, error) { ports, ok := s.([]types.ServicePortConfig) if !ok { return nil, errors.Errorf("not a servicePortConfig slice: %v", s) } - m := map[interface{}]interface{}{} + m := map[any]any{} for _, p := range ports { m[p.Published] = p } return m, nil } -func toServiceVolumeConfigsMap(s interface{}) (map[interface{}]interface{}, error) { +func toServiceVolumeConfigsMap(s any) (map[any]any, error) { volumes, ok := s.([]types.ServiceVolumeConfig) if !ok { return nil, errors.Errorf("not a serviceVolumeConfig slice: %v", s) } - m := map[interface{}]interface{}{} + m := map[any]any{} for _, v := range volumes { m[v.Target] = v } return m, nil } -func toServiceSecretConfigsSlice(dst reflect.Value, m map[interface{}]interface{}) error { +func toServiceSecretConfigsSlice(dst reflect.Value, m map[any]any) error { s := []types.ServiceSecretConfig{} for _, v := range m { s = append(s, v.(types.ServiceSecretConfig)) @@ -141,7 +141,7 @@ func toServiceSecretConfigsSlice(dst reflect.Value, m map[interface{}]interface{ return nil } -func toSServiceConfigObjConfigsSlice(dst reflect.Value, m map[interface{}]interface{}) error { +func toSServiceConfigObjConfigsSlice(dst reflect.Value, m map[any]any) error { s := []types.ServiceConfigObjConfig{} for _, v := range m { s = append(s, v.(types.ServiceConfigObjConfig)) @@ -151,7 +151,7 @@ func toSServiceConfigObjConfigsSlice(dst reflect.Value, m map[interface{}]interf return nil } -func toServicePortConfigsSlice(dst reflect.Value, m map[interface{}]interface{}) error { +func toServicePortConfigsSlice(dst reflect.Value, m map[any]any) error { s := []types.ServicePortConfig{} for _, v := range m { s = append(s, v.(types.ServicePortConfig)) @@ -161,7 +161,7 @@ func toServicePortConfigsSlice(dst reflect.Value, m map[interface{}]interface{}) return nil } -func toServiceVolumeConfigsSlice(dst reflect.Value, m map[interface{}]interface{}) error { +func toServiceVolumeConfigsSlice(dst reflect.Value, m map[any]any) error { s := []types.ServiceVolumeConfig{} for _, v := range m { s = append(s, v.(types.ServiceVolumeConfig)) @@ -172,8 +172,8 @@ func toServiceVolumeConfigsSlice(dst reflect.Value, m map[interface{}]interface{ } type ( - tomapFn func(s interface{}) (map[interface{}]interface{}, error) - writeValueFromMapFn func(reflect.Value, map[interface{}]interface{}) error + tomapFn func(s any) (map[any]any, error) + writeValueFromMapFn func(reflect.Value, map[any]any) error ) func safelyMerge(mergeFn func(dst, src reflect.Value) error) func(dst, src reflect.Value) error { @@ -206,7 +206,7 @@ func mergeSlice(tomap tomapFn, writeValue writeValueFromMapFn) func(dst, src ref } } -func sliceToMap(tomap tomapFn, v reflect.Value) (map[interface{}]interface{}, error) { +func sliceToMap(tomap tomapFn, v reflect.Value) (map[any]any, error) { // check if valid if !v.IsValid() { return nil, errors.Errorf("invalid value : %+v", v) diff --git a/cli/compose/loader/merge_test.go b/cli/compose/loader/merge_test.go index 02a819c964..f49e5ef6d3 100644 --- a/cli/compose/loader/merge_test.go +++ b/cli/compose/loader/merge_test.go @@ -12,10 +12,10 @@ import ( func TestLoadTwoDifferentVersion(t *testing.T) { configDetails := types.ConfigDetails{ ConfigFiles: []types.ConfigFile{ - {Filename: "base.yml", Config: map[string]interface{}{ + {Filename: "base.yml", Config: map[string]any{ "version": "3.1", }}, - {Filename: "override.yml", Config: map[string]interface{}{ + {Filename: "override.yml", Config: map[string]any{ "version": "3.4", }}, }, @@ -27,24 +27,24 @@ func TestLoadTwoDifferentVersion(t *testing.T) { func TestLoadLogging(t *testing.T) { loggingCases := []struct { name string - loggingBase map[string]interface{} - loggingOverride map[string]interface{} + loggingBase map[string]any + loggingOverride map[string]any expected *types.LoggingConfig }{ { name: "no_override_driver", - loggingBase: map[string]interface{}{ - "logging": map[string]interface{}{ + loggingBase: map[string]any{ + "logging": map[string]any{ "driver": "json-file", - "options": map[string]interface{}{ + "options": map[string]any{ "frequency": "2000", "timeout": "23", }, }, }, - loggingOverride: map[string]interface{}{ - "logging": map[string]interface{}{ - "options": map[string]interface{}{ + loggingOverride: map[string]any{ + "logging": map[string]any{ + "options": map[string]any{ "timeout": "360", "pretty-print": "on", }, @@ -61,19 +61,19 @@ func TestLoadLogging(t *testing.T) { }, { name: "override_driver", - loggingBase: map[string]interface{}{ - "logging": map[string]interface{}{ + loggingBase: map[string]any{ + "logging": map[string]any{ "driver": "json-file", - "options": map[string]interface{}{ + "options": map[string]any{ "frequency": "2000", "timeout": "23", }, }, }, - loggingOverride: map[string]interface{}{ - "logging": map[string]interface{}{ + loggingOverride: map[string]any{ + "logging": map[string]any{ "driver": "syslog", - "options": map[string]interface{}{ + "options": map[string]any{ "timeout": "360", "pretty-print": "on", }, @@ -89,18 +89,18 @@ func TestLoadLogging(t *testing.T) { }, { name: "no_base_driver", - loggingBase: map[string]interface{}{ - "logging": map[string]interface{}{ - "options": map[string]interface{}{ + loggingBase: map[string]any{ + "logging": map[string]any{ + "options": map[string]any{ "frequency": "2000", "timeout": "23", }, }, }, - loggingOverride: map[string]interface{}{ - "logging": map[string]interface{}{ + loggingOverride: map[string]any{ + "logging": map[string]any{ "driver": "json-file", - "options": map[string]interface{}{ + "options": map[string]any{ "timeout": "360", "pretty-print": "on", }, @@ -117,17 +117,17 @@ func TestLoadLogging(t *testing.T) { }, { name: "no_driver", - loggingBase: map[string]interface{}{ - "logging": map[string]interface{}{ - "options": map[string]interface{}{ + loggingBase: map[string]any{ + "logging": map[string]any{ + "options": map[string]any{ "frequency": "2000", "timeout": "23", }, }, }, - loggingOverride: map[string]interface{}{ - "logging": map[string]interface{}{ - "options": map[string]interface{}{ + loggingOverride: map[string]any{ + "logging": map[string]any{ + "options": map[string]any{ "timeout": "360", "pretty-print": "on", }, @@ -143,17 +143,17 @@ func TestLoadLogging(t *testing.T) { }, { name: "no_override_options", - loggingBase: map[string]interface{}{ - "logging": map[string]interface{}{ + loggingBase: map[string]any{ + "logging": map[string]any{ "driver": "json-file", - "options": map[string]interface{}{ + "options": map[string]any{ "frequency": "2000", "timeout": "23", }, }, }, - loggingOverride: map[string]interface{}{ - "logging": map[string]interface{}{ + loggingOverride: map[string]any{ + "logging": map[string]any{ "driver": "syslog", }, }, @@ -163,11 +163,11 @@ func TestLoadLogging(t *testing.T) { }, { name: "no_base", - loggingBase: map[string]interface{}{}, - loggingOverride: map[string]interface{}{ - "logging": map[string]interface{}{ + loggingBase: map[string]any{}, + loggingOverride: map[string]any{ + "logging": map[string]any{ "driver": "json-file", - "options": map[string]interface{}{ + "options": map[string]any{ "frequency": "2000", }, }, @@ -187,18 +187,18 @@ func TestLoadLogging(t *testing.T) { ConfigFiles: []types.ConfigFile{ { Filename: "base.yml", - Config: map[string]interface{}{ + Config: map[string]any{ "version": "3.4", - "services": map[string]interface{}{ + "services": map[string]any{ "foo": tc.loggingBase, }, }, }, { Filename: "override.yml", - Config: map[string]interface{}{ + Config: map[string]any{ "version": "3.4", - "services": map[string]interface{}{ + "services": map[string]any{ "foo": tc.loggingOverride, }, }, @@ -229,18 +229,18 @@ func TestLoadLogging(t *testing.T) { func TestLoadMultipleServicePorts(t *testing.T) { portsCases := []struct { name string - portBase map[string]interface{} - portOverride map[string]interface{} + portBase map[string]any + portOverride map[string]any expected []types.ServicePortConfig }{ { name: "no_override", - portBase: map[string]interface{}{ - "ports": []interface{}{ + portBase: map[string]any{ + "ports": []any{ "8080:80", }, }, - portOverride: map[string]interface{}{}, + portOverride: map[string]any{}, expected: []types.ServicePortConfig{ { Mode: "ingress", @@ -252,13 +252,13 @@ func TestLoadMultipleServicePorts(t *testing.T) { }, { name: "override_different_published", - portBase: map[string]interface{}{ - "ports": []interface{}{ + portBase: map[string]any{ + "ports": []any{ "8080:80", }, }, - portOverride: map[string]interface{}{ - "ports": []interface{}{ + portOverride: map[string]any{ + "ports": []any{ "8081:80", }, }, @@ -279,13 +279,13 @@ func TestLoadMultipleServicePorts(t *testing.T) { }, { name: "override_same_published", - portBase: map[string]interface{}{ - "ports": []interface{}{ + portBase: map[string]any{ + "ports": []any{ "8080:80", }, }, - portOverride: map[string]interface{}{ - "ports": []interface{}{ + portOverride: map[string]any{ + "ports": []any{ "8080:81", }, }, @@ -306,18 +306,18 @@ func TestLoadMultipleServicePorts(t *testing.T) { ConfigFiles: []types.ConfigFile{ { Filename: "base.yml", - Config: map[string]interface{}{ + Config: map[string]any{ "version": "3.4", - "services": map[string]interface{}{ + "services": map[string]any{ "foo": tc.portBase, }, }, }, { Filename: "override.yml", - Config: map[string]interface{}{ + Config: map[string]any{ "version": "3.4", - "services": map[string]interface{}{ + "services": map[string]any{ "foo": tc.portOverride, }, }, @@ -348,18 +348,18 @@ func TestLoadMultipleServicePorts(t *testing.T) { func TestLoadMultipleSecretsConfig(t *testing.T) { portsCases := []struct { name string - secretBase map[string]interface{} - secretOverride map[string]interface{} + secretBase map[string]any + secretOverride map[string]any expected []types.ServiceSecretConfig }{ { name: "no_override", - secretBase: map[string]interface{}{ - "secrets": []interface{}{ + secretBase: map[string]any{ + "secrets": []any{ "my_secret", }, }, - secretOverride: map[string]interface{}{}, + secretOverride: map[string]any{}, expected: []types.ServiceSecretConfig{ { Source: "my_secret", @@ -368,13 +368,13 @@ func TestLoadMultipleSecretsConfig(t *testing.T) { }, { name: "override_simple", - secretBase: map[string]interface{}{ - "secrets": []interface{}{ + secretBase: map[string]any{ + "secrets": []any{ "foo_secret", }, }, - secretOverride: map[string]interface{}{ - "secrets": []interface{}{ + secretOverride: map[string]any{ + "secrets": []any{ "bar_secret", }, }, @@ -389,22 +389,22 @@ func TestLoadMultipleSecretsConfig(t *testing.T) { }, { name: "override_same_source", - secretBase: map[string]interface{}{ - "secrets": []interface{}{ + secretBase: map[string]any{ + "secrets": []any{ "foo_secret", - map[string]interface{}{ + map[string]any{ "source": "bar_secret", "target": "waw_secret", }, }, }, - secretOverride: map[string]interface{}{ - "secrets": []interface{}{ - map[string]interface{}{ + secretOverride: map[string]any{ + "secrets": []any{ + map[string]any{ "source": "bar_secret", "target": "bof_secret", }, - map[string]interface{}{ + map[string]any{ "source": "baz_secret", "target": "waw_secret", }, @@ -432,18 +432,18 @@ func TestLoadMultipleSecretsConfig(t *testing.T) { ConfigFiles: []types.ConfigFile{ { Filename: "base.yml", - Config: map[string]interface{}{ + Config: map[string]any{ "version": "3.4", - "services": map[string]interface{}{ + "services": map[string]any{ "foo": tc.secretBase, }, }, }, { Filename: "override.yml", - Config: map[string]interface{}{ + Config: map[string]any{ "version": "3.4", - "services": map[string]interface{}{ + "services": map[string]any{ "foo": tc.secretOverride, }, }, @@ -474,18 +474,18 @@ func TestLoadMultipleSecretsConfig(t *testing.T) { func TestLoadMultipleConfigobjsConfig(t *testing.T) { portsCases := []struct { name string - configBase map[string]interface{} - configOverride map[string]interface{} + configBase map[string]any + configOverride map[string]any expected []types.ServiceConfigObjConfig }{ { name: "no_override", - configBase: map[string]interface{}{ - "configs": []interface{}{ + configBase: map[string]any{ + "configs": []any{ "my_config", }, }, - configOverride: map[string]interface{}{}, + configOverride: map[string]any{}, expected: []types.ServiceConfigObjConfig{ { Source: "my_config", @@ -494,13 +494,13 @@ func TestLoadMultipleConfigobjsConfig(t *testing.T) { }, { name: "override_simple", - configBase: map[string]interface{}{ - "configs": []interface{}{ + configBase: map[string]any{ + "configs": []any{ "foo_config", }, }, - configOverride: map[string]interface{}{ - "configs": []interface{}{ + configOverride: map[string]any{ + "configs": []any{ "bar_config", }, }, @@ -515,22 +515,22 @@ func TestLoadMultipleConfigobjsConfig(t *testing.T) { }, { name: "override_same_source", - configBase: map[string]interface{}{ - "configs": []interface{}{ + configBase: map[string]any{ + "configs": []any{ "foo_config", - map[string]interface{}{ + map[string]any{ "source": "bar_config", "target": "waw_config", }, }, }, - configOverride: map[string]interface{}{ - "configs": []interface{}{ - map[string]interface{}{ + configOverride: map[string]any{ + "configs": []any{ + map[string]any{ "source": "bar_config", "target": "bof_config", }, - map[string]interface{}{ + map[string]any{ "source": "baz_config", "target": "waw_config", }, @@ -558,18 +558,18 @@ func TestLoadMultipleConfigobjsConfig(t *testing.T) { ConfigFiles: []types.ConfigFile{ { Filename: "base.yml", - Config: map[string]interface{}{ + Config: map[string]any{ "version": "3.4", - "services": map[string]interface{}{ + "services": map[string]any{ "foo": tc.configBase, }, }, }, { Filename: "override.yml", - Config: map[string]interface{}{ + Config: map[string]any{ "version": "3.4", - "services": map[string]interface{}{ + "services": map[string]any{ "foo": tc.configOverride, }, }, @@ -600,18 +600,18 @@ func TestLoadMultipleConfigobjsConfig(t *testing.T) { func TestLoadMultipleUlimits(t *testing.T) { ulimitCases := []struct { name string - ulimitBase map[string]interface{} - ulimitOverride map[string]interface{} + ulimitBase map[string]any + ulimitOverride map[string]any expected map[string]*types.UlimitsConfig }{ { name: "no_override", - ulimitBase: map[string]interface{}{ - "ulimits": map[string]interface{}{ + ulimitBase: map[string]any{ + "ulimits": map[string]any{ "noproc": 65535, }, }, - ulimitOverride: map[string]interface{}{}, + ulimitOverride: map[string]any{}, expected: map[string]*types.UlimitsConfig{ "noproc": { Single: 65535, @@ -620,13 +620,13 @@ func TestLoadMultipleUlimits(t *testing.T) { }, { name: "override_simple", - ulimitBase: map[string]interface{}{ - "ulimits": map[string]interface{}{ + ulimitBase: map[string]any{ + "ulimits": map[string]any{ "noproc": 65535, }, }, - ulimitOverride: map[string]interface{}{ - "ulimits": map[string]interface{}{ + ulimitOverride: map[string]any{ + "ulimits": map[string]any{ "noproc": 44444, }, }, @@ -638,19 +638,19 @@ func TestLoadMultipleUlimits(t *testing.T) { }, { name: "override_different_notation", - ulimitBase: map[string]interface{}{ - "ulimits": map[string]interface{}{ - "nofile": map[string]interface{}{ + ulimitBase: map[string]any{ + "ulimits": map[string]any{ + "nofile": map[string]any{ "soft": 11111, "hard": 99999, }, "noproc": 44444, }, }, - ulimitOverride: map[string]interface{}{ - "ulimits": map[string]interface{}{ + ulimitOverride: map[string]any{ + "ulimits": map[string]any{ "nofile": 55555, - "noproc": map[string]interface{}{ + "noproc": map[string]any{ "soft": 22222, "hard": 33333, }, @@ -674,18 +674,18 @@ func TestLoadMultipleUlimits(t *testing.T) { ConfigFiles: []types.ConfigFile{ { Filename: "base.yml", - Config: map[string]interface{}{ + Config: map[string]any{ "version": "3.4", - "services": map[string]interface{}{ + "services": map[string]any{ "foo": tc.ulimitBase, }, }, }, { Filename: "override.yml", - Config: map[string]interface{}{ + Config: map[string]any{ "version": "3.4", - "services": map[string]interface{}{ + "services": map[string]any{ "foo": tc.ulimitOverride, }, }, @@ -716,19 +716,19 @@ func TestLoadMultipleUlimits(t *testing.T) { func TestLoadMultipleServiceNetworks(t *testing.T) { networkCases := []struct { name string - networkBase map[string]interface{} - networkOverride map[string]interface{} + networkBase map[string]any + networkOverride map[string]any expected map[string]*types.ServiceNetworkConfig }{ { name: "no_override", - networkBase: map[string]interface{}{ - "networks": []interface{}{ + networkBase: map[string]any{ + "networks": []any{ "net1", "net2", }, }, - networkOverride: map[string]interface{}{}, + networkOverride: map[string]any{}, expected: map[string]*types.ServiceNetworkConfig{ "net1": nil, "net2": nil, @@ -736,14 +736,14 @@ func TestLoadMultipleServiceNetworks(t *testing.T) { }, { name: "override_simple", - networkBase: map[string]interface{}{ - "networks": []interface{}{ + networkBase: map[string]any{ + "networks": []any{ "net1", "net2", }, }, - networkOverride: map[string]interface{}{ - "networks": []interface{}{ + networkOverride: map[string]any{ + "networks": []any{ "net1", "net3", }, @@ -756,25 +756,25 @@ func TestLoadMultipleServiceNetworks(t *testing.T) { }, { name: "override_with_aliases", - networkBase: map[string]interface{}{ - "networks": map[string]interface{}{ - "net1": map[string]interface{}{ - "aliases": []interface{}{ + networkBase: map[string]any{ + "networks": map[string]any{ + "net1": map[string]any{ + "aliases": []any{ "alias1", }, }, "net2": nil, }, }, - networkOverride: map[string]interface{}{ - "networks": map[string]interface{}{ - "net1": map[string]interface{}{ - "aliases": []interface{}{ + networkOverride: map[string]any{ + "networks": map[string]any{ + "net1": map[string]any{ + "aliases": []any{ "alias2", "alias3", }, }, - "net3": map[string]interface{}{}, + "net3": map[string]any{}, }, }, expected: map[string]*types.ServiceNetworkConfig{ @@ -793,18 +793,18 @@ func TestLoadMultipleServiceNetworks(t *testing.T) { ConfigFiles: []types.ConfigFile{ { Filename: "base.yml", - Config: map[string]interface{}{ + Config: map[string]any{ "version": "3.4", - "services": map[string]interface{}{ + "services": map[string]any{ "foo": tc.networkBase, }, }, }, { Filename: "override.yml", - Config: map[string]interface{}{ + Config: map[string]any{ "version": "3.4", - "services": map[string]interface{}{ + "services": map[string]any{ "foo": tc.networkOverride, }, }, @@ -833,65 +833,65 @@ func TestLoadMultipleServiceNetworks(t *testing.T) { } func TestLoadMultipleConfigs(t *testing.T) { - base := map[string]interface{}{ + base := map[string]any{ "version": "3.4", - "services": map[string]interface{}{ - "foo": map[string]interface{}{ + "services": map[string]any{ + "foo": map[string]any{ "image": "foo", - "build": map[string]interface{}{ + "build": map[string]any{ "context": ".", "dockerfile": "bar.Dockerfile", }, - "ports": []interface{}{ + "ports": []any{ "8080:80", "9090:90", }, - "labels": []interface{}{ + "labels": []any{ "foo=bar", }, - "cap_add": []interface{}{ + "cap_add": []any{ "NET_ADMIN", }, }, }, - "volumes": map[string]interface{}{}, - "networks": map[string]interface{}{}, - "secrets": map[string]interface{}{}, - "configs": map[string]interface{}{}, + "volumes": map[string]any{}, + "networks": map[string]any{}, + "secrets": map[string]any{}, + "configs": map[string]any{}, } - override := map[string]interface{}{ + override := map[string]any{ "version": "3.4", - "services": map[string]interface{}{ - "foo": map[string]interface{}{ + "services": map[string]any{ + "foo": map[string]any{ "image": "baz", - "build": map[string]interface{}{ + "build": map[string]any{ "dockerfile": "foo.Dockerfile", - "args": []interface{}{ + "args": []any{ "buildno=1", "password=secret", }, }, - "ports": []interface{}{ - map[string]interface{}{ + "ports": []any{ + map[string]any{ "target": 81, "published": 8080, }, }, - "labels": map[string]interface{}{ + "labels": map[string]any{ "foo": "baz", }, - "cap_add": []interface{}{ + "cap_add": []any{ "SYS_ADMIN", }, }, - "bar": map[string]interface{}{ + "bar": map[string]any{ "image": "bar", }, }, - "volumes": map[string]interface{}{}, - "networks": map[string]interface{}{}, - "secrets": map[string]interface{}{}, - "configs": map[string]interface{}{}, + "volumes": map[string]any{}, + "networks": map[string]any{}, + "secrets": map[string]any{}, + "configs": map[string]any{}, } configDetails := types.ConfigDetails{ ConfigFiles: []types.ConfigFile{ @@ -949,43 +949,43 @@ func TestLoadMultipleConfigs(t *testing.T) { // Issue#972 func TestLoadMultipleNetworks(t *testing.T) { - base := map[string]interface{}{ + base := map[string]any{ "version": "3.4", - "services": map[string]interface{}{ - "foo": map[string]interface{}{ + "services": map[string]any{ + "foo": map[string]any{ "image": "baz", }, }, - "volumes": map[string]interface{}{}, - "networks": map[string]interface{}{ - "hostnet": map[string]interface{}{ + "volumes": map[string]any{}, + "networks": map[string]any{ + "hostnet": map[string]any{ "driver": "overlay", - "ipam": map[string]interface{}{ + "ipam": map[string]any{ "driver": "default", - "config": []interface{}{ - map[string]interface{}{ + "config": []any{ + map[string]any{ "subnet": "10.0.0.0/20", }, }, }, }, }, - "secrets": map[string]interface{}{}, - "configs": map[string]interface{}{}, + "secrets": map[string]any{}, + "configs": map[string]any{}, } - override := map[string]interface{}{ + override := map[string]any{ "version": "3.4", - "services": map[string]interface{}{}, - "volumes": map[string]interface{}{}, - "networks": map[string]interface{}{ - "hostnet": map[string]interface{}{ - "external": map[string]interface{}{ + "services": map[string]any{}, + "volumes": map[string]any{}, + "networks": map[string]any{ + "hostnet": map[string]any{ + "external": map[string]any{ "name": "host", }, }, }, - "secrets": map[string]interface{}{}, - "configs": map[string]interface{}{}, + "secrets": map[string]any{}, + "configs": map[string]any{}, } configDetails := types.ConfigDetails{ ConfigFiles: []types.ConfigFile{ @@ -1020,31 +1020,31 @@ func TestLoadMultipleNetworks(t *testing.T) { } func TestLoadMultipleServiceCommands(t *testing.T) { - base := map[string]interface{}{ + base := map[string]any{ "version": "3.7", - "services": map[string]interface{}{ - "foo": map[string]interface{}{ + "services": map[string]any{ + "foo": map[string]any{ "image": "baz", "command": "foo bar", }, }, - "volumes": map[string]interface{}{}, - "networks": map[string]interface{}{}, - "secrets": map[string]interface{}{}, - "configs": map[string]interface{}{}, + "volumes": map[string]any{}, + "networks": map[string]any{}, + "secrets": map[string]any{}, + "configs": map[string]any{}, } - override := map[string]interface{}{ + override := map[string]any{ "version": "3.7", - "services": map[string]interface{}{ - "foo": map[string]interface{}{ + "services": map[string]any{ + "foo": map[string]any{ "image": "baz", "command": "foo baz", }, }, - "volumes": map[string]interface{}{}, - "networks": map[string]interface{}{}, - "secrets": map[string]interface{}{}, - "configs": map[string]interface{}{}, + "volumes": map[string]any{}, + "networks": map[string]any{}, + "secrets": map[string]any{}, + "configs": map[string]any{}, } configDetails := types.ConfigDetails{ ConfigFiles: []types.ConfigFile{ @@ -1073,13 +1073,13 @@ func TestLoadMultipleServiceCommands(t *testing.T) { } func TestLoadMultipleServiceVolumes(t *testing.T) { - base := map[string]interface{}{ + base := map[string]any{ "version": "3.7", - "services": map[string]interface{}{ - "foo": map[string]interface{}{ + "services": map[string]any{ + "foo": map[string]any{ "image": "baz", - "volumes": []interface{}{ - map[string]interface{}{ + "volumes": []any{ + map[string]any{ "type": "volume", "source": "sourceVolume", "target": "/var/app", @@ -1087,20 +1087,20 @@ func TestLoadMultipleServiceVolumes(t *testing.T) { }, }, }, - "volumes": map[string]interface{}{ - "sourceVolume": map[string]interface{}{}, + "volumes": map[string]any{ + "sourceVolume": map[string]any{}, }, - "networks": map[string]interface{}{}, - "secrets": map[string]interface{}{}, - "configs": map[string]interface{}{}, + "networks": map[string]any{}, + "secrets": map[string]any{}, + "configs": map[string]any{}, } - override := map[string]interface{}{ + override := map[string]any{ "version": "3.7", - "services": map[string]interface{}{ - "foo": map[string]interface{}{ + "services": map[string]any{ + "foo": map[string]any{ "image": "baz", - "volumes": []interface{}{ - map[string]interface{}{ + "volumes": []any{ + map[string]any{ "type": "volume", "source": "/local", "target": "/var/app", @@ -1108,10 +1108,10 @@ func TestLoadMultipleServiceVolumes(t *testing.T) { }, }, }, - "volumes": map[string]interface{}{}, - "networks": map[string]interface{}{}, - "secrets": map[string]interface{}{}, - "configs": map[string]interface{}{}, + "volumes": map[string]any{}, + "networks": map[string]any{}, + "secrets": map[string]any{}, + "configs": map[string]any{}, } configDetails := types.ConfigDetails{ ConfigFiles: []types.ConfigFile{ diff --git a/cli/compose/schema/schema.go b/cli/compose/schema/schema.go index 2ba477c192..7bf419cbc4 100644 --- a/cli/compose/schema/schema.go +++ b/cli/compose/schema/schema.go @@ -17,14 +17,14 @@ const ( type portsFormatChecker struct{} -func (checker portsFormatChecker) IsFormat(_ interface{}) bool { +func (checker portsFormatChecker) IsFormat(_ any) bool { // TODO: implement this return true } type durationFormatChecker struct{} -func (checker durationFormatChecker) IsFormat(input interface{}) bool { +func (checker durationFormatChecker) IsFormat(input any) bool { value, ok := input.(string) if !ok { return false @@ -42,7 +42,7 @@ func init() { // Version returns the version of the config, defaulting to the latest "3.x" // version (3.12). If only the major version "3" is specified, it is used as // version "3.x" and returns the default version (latest 3.x). -func Version(config map[string]interface{}) string { +func Version(config map[string]any) string { version, ok := config[versionField] if !ok { return defaultVersion @@ -63,7 +63,7 @@ func normalizeVersion(version string) string { var schemas embed.FS // Validate uses the jsonschema to validate the configuration -func Validate(config map[string]interface{}, version string) error { +func Validate(config map[string]any, version string) error { version = normalizeVersion(version) schemaData, err := schemas.ReadFile("data/config_schema_v" + version + ".json") if err != nil { diff --git a/cli/compose/schema/schema_test.go b/cli/compose/schema/schema_test.go index 548e57c8cd..7f66207cc0 100644 --- a/cli/compose/schema/schema_test.go +++ b/cli/compose/schema/schema_test.go @@ -7,7 +7,7 @@ import ( "gotest.tools/v3/assert" ) -type dict map[string]interface{} +type dict map[string]any func TestValidate(t *testing.T) { config := dict{ @@ -162,7 +162,7 @@ func TestValidateInvalidVersion(t *testing.T) { assert.ErrorContains(t, err, "unsupported Compose file version: 2.1") } -type array []interface{} +type array []any func TestValidatePlacement(t *testing.T) { config := dict{ diff --git a/cli/compose/template/template.go b/cli/compose/template/template.go index 23f059c9d4..37b764fe51 100644 --- a/cli/compose/template/template.go +++ b/cli/compose/template/template.go @@ -95,14 +95,14 @@ func Substitute(template string, mapping Mapping) (string, error) { // ExtractVariables returns a map of all the variables defined in the specified // composefile (dict representation) and their default value if any. -func ExtractVariables(configDict map[string]interface{}, pattern *regexp.Regexp) map[string]string { +func ExtractVariables(configDict map[string]any, pattern *regexp.Regexp) map[string]string { if pattern == nil { pattern = defaultPattern } return recurseExtract(configDict, pattern) } -func recurseExtract(value interface{}, pattern *regexp.Regexp) map[string]string { +func recurseExtract(value any, pattern *regexp.Regexp) map[string]string { m := map[string]string{} switch value := value.(type) { @@ -112,7 +112,7 @@ func recurseExtract(value interface{}, pattern *regexp.Regexp) map[string]string m[v.name] = v.value } } - case map[string]interface{}: + case map[string]any: for _, elem := range value { submap := recurseExtract(elem, pattern) for key, value := range submap { @@ -120,7 +120,7 @@ func recurseExtract(value interface{}, pattern *regexp.Regexp) map[string]string } } - case []interface{}: + case []any: for _, elem := range value { if values, is := extractVariable(elem, pattern); is { for _, v := range values { @@ -138,7 +138,7 @@ type extractedValue struct { value string } -func extractVariable(value interface{}, pattern *regexp.Regexp) ([]extractedValue, bool) { +func extractVariable(value any, pattern *regexp.Regexp) ([]extractedValue, bool) { sValue, ok := value.(string) if !ok { return []extractedValue{}, false diff --git a/cli/compose/template/template_test.go b/cli/compose/template/template_test.go index 0406969900..f67d6d7806 100644 --- a/cli/compose/template/template_test.go +++ b/cli/compose/template/template_test.go @@ -181,24 +181,24 @@ func TestSubstituteWithCustomFunc(t *testing.T) { func TestExtractVariables(t *testing.T) { testCases := []struct { name string - dict map[string]interface{} + dict map[string]any expected map[string]string }{ { name: "empty", - dict: map[string]interface{}{}, + dict: map[string]any{}, expected: map[string]string{}, }, { name: "no-variables", - dict: map[string]interface{}{ + dict: map[string]any{ "foo": "bar", }, expected: map[string]string{}, }, { name: "variable-without-curly-braces", - dict: map[string]interface{}{ + dict: map[string]any{ "foo": "$bar", }, expected: map[string]string{ @@ -207,7 +207,7 @@ func TestExtractVariables(t *testing.T) { }, { name: "variable", - dict: map[string]interface{}{ + dict: map[string]any{ "foo": "${bar}", }, expected: map[string]string{ @@ -216,7 +216,7 @@ func TestExtractVariables(t *testing.T) { }, { name: "required-variable", - dict: map[string]interface{}{ + dict: map[string]any{ "foo": "${bar?:foo}", }, expected: map[string]string{ @@ -225,7 +225,7 @@ func TestExtractVariables(t *testing.T) { }, { name: "required-variable2", - dict: map[string]interface{}{ + dict: map[string]any{ "foo": "${bar?foo}", }, expected: map[string]string{ @@ -234,7 +234,7 @@ func TestExtractVariables(t *testing.T) { }, { name: "default-variable", - dict: map[string]interface{}{ + dict: map[string]any{ "foo": "${bar:-foo}", }, expected: map[string]string{ @@ -243,7 +243,7 @@ func TestExtractVariables(t *testing.T) { }, { name: "default-variable2", - dict: map[string]interface{}{ + dict: map[string]any{ "foo": "${bar-foo}", }, expected: map[string]string{ @@ -252,13 +252,13 @@ func TestExtractVariables(t *testing.T) { }, { name: "multiple-values", - dict: map[string]interface{}{ + dict: map[string]any{ "foo": "${bar:-foo}", - "bar": map[string]interface{}{ + "bar": map[string]any{ "foo": "${fruit:-banana}", "bar": "vegetable", }, - "baz": []interface{}{ + "baz": []any{ "foo", "$docker:${project:-cli}", "$toto", diff --git a/cli/compose/types/types.go b/cli/compose/types/types.go index f606f9ea8a..992e79fff9 100644 --- a/cli/compose/types/types.go +++ b/cli/compose/types/types.go @@ -50,7 +50,7 @@ var ForbiddenProperties = map[string]string{ // ConfigFile is a filename and the contents of the file as a Dict type ConfigFile struct { Filename string - Config map[string]interface{} + Config map[string]any } // ConfigDetails are the details about a group of ConfigFiles @@ -83,7 +83,7 @@ func (d Duration) MarshalJSON() ([]byte, error) { } // MarshalYAML makes Duration implement yaml.Marshaler -func (d Duration) MarshalYAML() (interface{}, error) { +func (d Duration) MarshalYAML() (any, error) { return d.String(), nil } @@ -102,12 +102,12 @@ type Config struct { Volumes map[string]VolumeConfig `yaml:",omitempty" json:"volumes,omitempty"` Secrets map[string]SecretConfig `yaml:",omitempty" json:"secrets,omitempty"` Configs map[string]ConfigObjConfig `yaml:",omitempty" json:"configs,omitempty"` - Extras map[string]interface{} `yaml:",inline" json:"-"` + Extras map[string]any `yaml:",inline" json:"-"` } // MarshalJSON makes Config implement json.Marshaler func (c Config) MarshalJSON() ([]byte, error) { - m := map[string]interface{}{ + m := map[string]any{ "version": c.Version, "services": c.Services, } @@ -134,7 +134,7 @@ func (c Config) MarshalJSON() ([]byte, error) { type Services []ServiceConfig // MarshalYAML makes Services implement yaml.Marshaller -func (s Services) MarshalYAML() (interface{}, error) { +func (s Services) MarshalYAML() (any, error) { services := map[string]ServiceConfig{} for _, service := range s { services[service.Name] = service @@ -208,7 +208,7 @@ type ServiceConfig struct { Volumes []ServiceVolumeConfig `yaml:",omitempty" json:"volumes,omitempty"` WorkingDir string `mapstructure:"working_dir" yaml:"working_dir,omitempty" json:"working_dir,omitempty"` - Extras map[string]interface{} `yaml:",inline" json:"-"` + Extras map[string]any `yaml:",inline" json:"-"` } // BuildConfig is a type for build @@ -340,7 +340,7 @@ type DiscreteGenericResource struct { type UnitBytes int64 // MarshalYAML makes UnitBytes implement yaml.Marshaller -func (u UnitBytes) MarshalYAML() (interface{}, error) { +func (u UnitBytes) MarshalYAML() (any, error) { return fmt.Sprintf("%d", u), nil } @@ -439,7 +439,7 @@ type UlimitsConfig struct { } // MarshalYAML makes UlimitsConfig implement yaml.Marshaller -func (u *UlimitsConfig) MarshalYAML() (interface{}, error) { +func (u *UlimitsConfig) MarshalYAML() (any, error) { if u.Single != 0 { return u.Single, nil } @@ -458,15 +458,15 @@ func (u *UlimitsConfig) MarshalJSON() ([]byte, error) { // NetworkConfig for a network type NetworkConfig struct { - Name string `yaml:",omitempty" json:"name,omitempty"` - Driver string `yaml:",omitempty" json:"driver,omitempty"` - DriverOpts map[string]string `mapstructure:"driver_opts" yaml:"driver_opts,omitempty" json:"driver_opts,omitempty"` - Ipam IPAMConfig `yaml:",omitempty" json:"ipam,omitempty"` - External External `yaml:",omitempty" json:"external,omitempty"` - Internal bool `yaml:",omitempty" json:"internal,omitempty"` - Attachable bool `yaml:",omitempty" json:"attachable,omitempty"` - Labels Labels `yaml:",omitempty" json:"labels,omitempty"` - Extras map[string]interface{} `yaml:",inline" json:"-"` + Name string `yaml:",omitempty" json:"name,omitempty"` + Driver string `yaml:",omitempty" json:"driver,omitempty"` + DriverOpts map[string]string `mapstructure:"driver_opts" yaml:"driver_opts,omitempty" json:"driver_opts,omitempty"` + Ipam IPAMConfig `yaml:",omitempty" json:"ipam,omitempty"` + External External `yaml:",omitempty" json:"external,omitempty"` + Internal bool `yaml:",omitempty" json:"internal,omitempty"` + Attachable bool `yaml:",omitempty" json:"attachable,omitempty"` + Labels Labels `yaml:",omitempty" json:"labels,omitempty"` + Extras map[string]any `yaml:",inline" json:"-"` } // IPAMConfig for a network @@ -482,13 +482,13 @@ type IPAMPool struct { // VolumeConfig for a volume type VolumeConfig struct { - Name string `yaml:",omitempty" json:"name,omitempty"` - Driver string `yaml:",omitempty" json:"driver,omitempty"` - DriverOpts map[string]string `mapstructure:"driver_opts" yaml:"driver_opts,omitempty" json:"driver_opts,omitempty"` - External External `yaml:",omitempty" json:"external,omitempty"` - Labels Labels `yaml:",omitempty" json:"labels,omitempty"` - Extras map[string]interface{} `yaml:",inline" json:"-"` - Spec *ClusterVolumeSpec `mapstructure:"x-cluster-spec" yaml:"x-cluster-spec,omitempty" json:"x-cluster-spec,omitempty"` + Name string `yaml:",omitempty" json:"name,omitempty"` + Driver string `yaml:",omitempty" json:"driver,omitempty"` + DriverOpts map[string]string `mapstructure:"driver_opts" yaml:"driver_opts,omitempty" json:"driver_opts,omitempty"` + External External `yaml:",omitempty" json:"external,omitempty"` + Labels Labels `yaml:",omitempty" json:"labels,omitempty"` + Extras map[string]any `yaml:",inline" json:"-"` + Spec *ClusterVolumeSpec `mapstructure:"x-cluster-spec" yaml:"x-cluster-spec,omitempty" json:"x-cluster-spec,omitempty"` } // ClusterVolumeSpec defines all the configuration and options specific to a @@ -556,7 +556,7 @@ type External struct { } // MarshalYAML makes External implement yaml.Marshaller -func (e External) MarshalYAML() (interface{}, error) { +func (e External) MarshalYAML() (any, error) { if e.Name == "" { return e.External, nil } @@ -580,14 +580,14 @@ type CredentialSpecConfig struct { // FileObjectConfig is a config type for a file used by a service type FileObjectConfig struct { - Name string `yaml:",omitempty" json:"name,omitempty"` - File string `yaml:",omitempty" json:"file,omitempty"` - External External `yaml:",omitempty" json:"external,omitempty"` - Labels Labels `yaml:",omitempty" json:"labels,omitempty"` - Extras map[string]interface{} `yaml:",inline" json:"-"` - Driver string `yaml:",omitempty" json:"driver,omitempty"` - DriverOpts map[string]string `mapstructure:"driver_opts" yaml:"driver_opts,omitempty" json:"driver_opts,omitempty"` - TemplateDriver string `mapstructure:"template_driver" yaml:"template_driver,omitempty" json:"template_driver,omitempty"` + Name string `yaml:",omitempty" json:"name,omitempty"` + File string `yaml:",omitempty" json:"file,omitempty"` + External External `yaml:",omitempty" json:"external,omitempty"` + Labels Labels `yaml:",omitempty" json:"labels,omitempty"` + Extras map[string]any `yaml:",inline" json:"-"` + Driver string `yaml:",omitempty" json:"driver,omitempty"` + DriverOpts map[string]string `mapstructure:"driver_opts" yaml:"driver_opts,omitempty" json:"driver_opts,omitempty"` + TemplateDriver string `mapstructure:"template_driver" yaml:"template_driver,omitempty" json:"template_driver,omitempty"` } // SecretConfig for a secret diff --git a/cli/context/store/metadata_test.go b/cli/context/store/metadata_test.go index fcb46c54f5..5860ca96bd 100644 --- a/cli/context/store/metadata_test.go +++ b/cli/context/store/metadata_test.go @@ -12,7 +12,7 @@ import ( func testMetadata(name string) Metadata { return Metadata{ - Endpoints: map[string]interface{}{ + Endpoints: map[string]any{ "ep1": endpoint{Foo: "bar"}, }, Metadata: context{Bar: "baz"}, @@ -30,7 +30,7 @@ func TestMetadataCreateGetRemove(t *testing.T) { testDir := t.TempDir() testee := metadataStore{root: testDir, config: testCfg} expected2 := Metadata{ - Endpoints: map[string]interface{}{ + Endpoints: map[string]any{ "ep1": endpoint{Foo: "baz"}, "ep2": endpoint{Foo: "bee"}, }, @@ -114,7 +114,7 @@ type embeddedStruct struct { func TestWithEmbedding(t *testing.T) { testee := metadataStore{ root: t.TempDir(), - config: NewConfig(func() interface{} { return &contextWithEmbedding{} }), + config: NewConfig(func() any { return &contextWithEmbedding{} }), } testCtxMeta := contextWithEmbedding{ embeddedStruct: embeddedStruct{ diff --git a/cli/context/store/metadatastore.go b/cli/context/store/metadatastore.go index d004875696..01e6c0f21f 100644 --- a/cli/context/store/metadatastore.go +++ b/cli/context/store/metadatastore.go @@ -40,12 +40,12 @@ func (s *metadataStore) createOrUpdate(meta Metadata) error { return ioutils.AtomicWriteFile(filepath.Join(contextDir, metaFile), bytes, 0o644) } -func parseTypedOrMap(payload []byte, getter TypeGetter) (interface{}, error) { +func parseTypedOrMap(payload []byte, getter TypeGetter) (any, error) { if len(payload) == 0 || string(payload) == "null" { return nil, nil } if getter == nil { - var res map[string]interface{} + var res map[string]any if err := json.Unmarshal(payload, &res); err != nil { return nil, err } @@ -77,7 +77,7 @@ func (s *metadataStore) getByID(id contextdir) (Metadata, error) { } var untyped untypedContextMetadata r := Metadata{ - Endpoints: make(map[string]interface{}), + Endpoints: make(map[string]any), } if err := json.Unmarshal(bytes, &untyped); err != nil { return Metadata{}, fmt.Errorf("parsing %s: %v", fileName, err) diff --git a/cli/context/store/store.go b/cli/context/store/store.go index bff13665a7..2884150a95 100644 --- a/cli/context/store/store.go +++ b/cli/context/store/store.go @@ -70,9 +70,9 @@ type ReaderWriter interface { // Metadata contains metadata about a context and its endpoints type Metadata struct { - Name string `json:",omitempty"` - Metadata interface{} `json:",omitempty"` - Endpoints map[string]interface{} `json:",omitempty"` + Name string `json:",omitempty"` + Metadata any `json:",omitempty"` + Endpoints map[string]any `json:",omitempty"` } // StorageInfo contains data about where a given context is stored diff --git a/cli/context/store/store_test.go b/cli/context/store/store_test.go index 235870a954..ab180929d8 100644 --- a/cli/context/store/store_test.go +++ b/cli/context/store/store_test.go @@ -27,16 +27,16 @@ type context struct { Bar string `json:"another_very_recognizable_field_name"` } -var testCfg = NewConfig(func() interface{} { return &context{} }, - EndpointTypeGetter("ep1", func() interface{} { return &endpoint{} }), - EndpointTypeGetter("ep2", func() interface{} { return &endpoint{} }), +var testCfg = NewConfig(func() any { return &context{} }, + EndpointTypeGetter("ep1", func() any { return &endpoint{} }), + EndpointTypeGetter("ep2", func() any { return &endpoint{} }), ) func TestExportImport(t *testing.T) { s := New(t.TempDir(), testCfg) err := s.CreateOrUpdate( Metadata{ - Endpoints: map[string]interface{}{ + Endpoints: map[string]any{ "ep1": endpoint{Foo: "bar"}, }, Metadata: context{Bar: "baz"}, @@ -90,7 +90,7 @@ func TestRemove(t *testing.T) { s := New(t.TempDir(), testCfg) err := s.CreateOrUpdate( Metadata{ - Endpoints: map[string]interface{}{ + Endpoints: map[string]any{ "ep1": endpoint{Foo: "bar"}, }, Metadata: context{Bar: "baz"}, @@ -170,7 +170,7 @@ func TestImportZip(t *testing.T) { w := zip.NewWriter(f) meta, err := json.Marshal(Metadata{ - Endpoints: map[string]interface{}{ + Endpoints: map[string]any{ "ep1": endpoint{Foo: "bar"}, }, Metadata: context{Bar: "baz"}, @@ -238,7 +238,7 @@ func TestCorruptMetadata(t *testing.T) { s := New(tempDir, testCfg) err := s.CreateOrUpdate( Metadata{ - Endpoints: map[string]interface{}{ + Endpoints: map[string]any{ "ep1": endpoint{Foo: "bar"}, }, Metadata: context{Bar: "baz"}, diff --git a/cli/context/store/storeconfig.go b/cli/context/store/storeconfig.go index 9c93ecbab2..d6111d93e5 100644 --- a/cli/context/store/storeconfig.go +++ b/cli/context/store/storeconfig.go @@ -3,7 +3,7 @@ package store // TypeGetter is a func used to determine the concrete type of a context or // endpoint metadata by returning a pointer to an instance of the object // eg: for a context of type DockerContext, the corresponding TypeGetter should return new(DockerContext) -type TypeGetter func() interface{} +type TypeGetter func() any // NamedTypeGetter is a TypeGetter associated with a name type NamedTypeGetter struct { diff --git a/cli/context/store/storeconfig_test.go b/cli/context/store/storeconfig_test.go index e5b8c75686..bb4069b8d8 100644 --- a/cli/context/store/storeconfig_test.go +++ b/cli/context/store/storeconfig_test.go @@ -14,15 +14,15 @@ type ( ) func TestConfigModification(t *testing.T) { - cfg := NewConfig(func() interface{} { return &testCtx{} }, EndpointTypeGetter("ep1", func() interface{} { return &testEP1{} })) + cfg := NewConfig(func() any { return &testCtx{} }, EndpointTypeGetter("ep1", func() any { return &testEP1{} })) assert.Equal(t, &testCtx{}, cfg.contextType()) assert.Equal(t, &testEP1{}, cfg.endpointTypes["ep1"]()) cfgCopy := cfg // modify existing endpoint - cfg.SetEndpoint("ep1", func() interface{} { return &testEP2{} }) + cfg.SetEndpoint("ep1", func() any { return &testEP2{} }) // add endpoint - cfg.SetEndpoint("ep2", func() interface{} { return &testEP3{} }) + cfg.SetEndpoint("ep2", func() any { return &testEP3{} }) assert.Equal(t, &testCtx{}, cfg.contextType()) assert.Equal(t, &testEP2{}, cfg.endpointTypes["ep1"]()) assert.Equal(t, &testEP3{}, cfg.endpointTypes["ep2"]()) diff --git a/cmd/docker/builder_test.go b/cmd/docker/builder_test.go index 0ef79a65dd..774598b337 100644 --- a/cmd/docker/builder_test.go +++ b/cmd/docker/builder_test.go @@ -78,8 +78,8 @@ echo '{"SchemaVersion":"0.1.0","Vendor":"Docker Inc.","Version":"v0.6.3","ShortD if tt.context != command.DefaultContextName { assert.NilError(t, dockerCli.ContextStore().CreateOrUpdate(store.Metadata{ Name: tt.context, - Endpoints: map[string]interface{}{ - "docker": map[string]interface{}{ + Endpoints: map[string]any{ + "docker": map[string]any{ "host": "unix://" + filepath.Join(t.TempDir(), "docker.sock"), }, }, diff --git a/templates/templates.go b/templates/templates.go index deb043299d..fc86841876 100644 --- a/templates/templates.go +++ b/templates/templates.go @@ -10,7 +10,7 @@ import ( // basicFunctions are the set of initial // functions provided to every template. var basicFunctions = template.FuncMap{ - "json": func(v interface{}) string { + "json": func(v any) string { buf := &bytes.Buffer{} enc := json.NewEncoder(buf) enc.SetEscapeHTML(false) From 4e2477f85f52a382182e2f832a58d15c6257c49d Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Fri, 2 Sep 2022 21:50:18 +0200 Subject: [PATCH 18/19] golangci-lint: enable more linters fix some nolintlint false positives For some reason, nolintlint doesn't consider these used, but they seem to be legitimate cases where deprecated fields are used. templates/templates.go:27:29: directive `//nolint:staticcheck // strings.Title is deprecated, but we only use it for ASCII, so replacing with golang.org/x/text is out of scope` is unused for linter "staticcheck" (nolintlint) "title": strings.Title, //nolint:staticcheck // strings.Title is deprecated, but we only use it for ASCII, so replacing with golang.org/x/text is out of scope ^ cli/command/formatter/image_test.go:75:31: directive `//nolint:staticcheck // ignore SA1019: field is deprecated, but still set on API < v1.44.` is unused for linter "staticcheck" (nolintlint) call: ctx.VirtualSize, //nolint:staticcheck // ignore SA1019: field is deprecated, but still set on API < v1.44. ^ cli/command/registry/formatter_search.go:100:39: directive `//nolint:staticcheck // ignore SA1019 (IsAutomated is deprecated).` is unused for linter "staticcheck" (nolintlint) return c.formatBool(c.s.IsAutomated) //nolint:staticcheck // ignore SA1019 (IsAutomated is deprecated). ^ cli/command/registry/formatter_search_test.go:50:55: directive `//nolint:staticcheck // ignore SA1019 (IsAutomated is deprecated).` is unused for linter "staticcheck" (nolintlint) s: registrytypes.SearchResult{IsAutomated: true}, //nolint:staticcheck // ignore SA1019 (IsAutomated is deprecated). ^ cli/command/registry/formatter_search_test.go:53:31: directive `//nolint:staticcheck // ignore SA1019 (IsAutomated is deprecated).` is unused for linter "staticcheck" (nolintlint) call: ctx.IsAutomated, //nolint:staticcheck // ignore SA1019 (IsAutomated is deprecated). ^ cli/command/registry/formatter_search_test.go:59:27: directive `//nolint:staticcheck // ignore SA1019 (IsAutomated is deprecated).` is unused for linter "staticcheck" (nolintlint) call: ctx.IsAutomated, //nolint:staticcheck // ignore SA1019 (IsAutomated is deprecated). ^ cli/command/registry/formatter_search_test.go:202:84: directive `//nolint:staticcheck // ignore SA1019 (IsAutomated is deprecated).` is unused for linter "staticcheck" (nolintlint) {Name: "result2", Description: "Not official", StarCount: 5, IsAutomated: true}, //nolint:staticcheck // ignore SA1019 (IsAutomated is deprecated). ^ Signed-off-by: Sebastiaan van Stijn --- .golangci.yml | 38 ++++++++++++++----- cli/command/formatter/image_test.go | 2 +- cli/command/formatter/tabwriter/tabwriter.go | 2 +- cli/command/registry/formatter_search.go | 2 +- cli/command/registry/formatter_search_test.go | 8 ++-- cli/command/stack/loader/loader.go | 5 +-- .../commandconn/pdeathsig_nolinux.go | 3 +- templates/templates.go | 2 +- 8 files changed, 39 insertions(+), 23 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 89162cd8bc..c1ca4b920e 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -4,27 +4,39 @@ linters: - depguard - dogsled - dupword # Detects duplicate words. + - durationcheck + - exportloopref # Detects pointers to enclosing loop variables. + - gocritic # Metalinter; detects bugs, performance, and styling issues. - gocyclo - - gofumpt + - gofumpt # Detects whether code was gofumpt-ed. - goimports - - gosec + - gosec # Detects security problems. - gosimple - govet - ineffassign - lll - megacheck - - misspell + - misspell # Detects commonly misspelled English words in comments. - nakedret - nilerr # Detects code that returns nil even if it checks that the error is not nil. + - nolintlint # Detects ill-formed or insufficient nolint directives. - perfsprint # Detects fmt.Sprintf uses that can be replaced with a faster alternative. - - predeclared - - revive + - prealloc # Detects slice declarations that could potentially be pre-allocated. + - predeclared # Detects code that shadows one of Go's predeclared identifiers + - reassign + - revive # Metalinter; drop-in replacement for golint. - staticcheck - - thelper + - stylecheck # Replacement for golint + - tenv # Detects using os.Setenv instead of t.Setenv. + - thelper # Detects test helpers without t.Helper(). + - tparallel # Detects inappropriate usage of t.Parallel(). - typecheck - - unconvert + - unconvert # Detects unnecessary type conversions. - unparam - unused + - usestdlibvars + - vet + - wastedassign disable: - errcheck @@ -110,7 +122,7 @@ issues: - gosec # EXC0008 # TODO: evaluate these and fix where needed: G307: Deferring unsafe method "*os.File" on type "Close" (gosec) - - text: "(G104|G307)" + - text: "G307" linters: - gosec # EXC0009 @@ -124,10 +136,13 @@ issues: # G113 Potential uncontrolled memory consumption in Rat.SetString (CVE-2022-23772) # only affects gp < 1.16.14. and go < 1.17.7 - - text: "(G113)" + - 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" @@ -152,6 +167,9 @@ issues: linters: - errcheck - gosec + - text: "ST1000: at least one file in a package should have a package comment" + linters: + - stylecheck # Allow "err" and "ok" vars to shadow existing declarations, otherwise we get too many false positives. - text: '^shadow: declaration of "(err|ok)" shadows declaration' diff --git a/cli/command/formatter/image_test.go b/cli/command/formatter/image_test.go index d2388fd6c9..fcdf727c52 100644 --- a/cli/command/formatter/image_test.go +++ b/cli/command/formatter/image_test.go @@ -72,7 +72,7 @@ func TestImageContext(t *testing.T) { { imageCtx: imageContext{i: image.Summary{Size: 10000}}, expValue: "10kB", - call: ctx.VirtualSize, //nolint:staticcheck // ignore SA1019: field is deprecated, but still set on API < v1.44. + call: ctx.VirtualSize, //nolint:nolintlint,staticcheck // ignore SA1019: field is deprecated, but still set on API < v1.44. }, { imageCtx: imageContext{i: image.Summary{SharedSize: 10000}}, diff --git a/cli/command/formatter/tabwriter/tabwriter.go b/cli/command/formatter/tabwriter/tabwriter.go index fac1b96c58..bc155298f6 100644 --- a/cli/command/formatter/tabwriter/tabwriter.go +++ b/cli/command/formatter/tabwriter/tabwriter.go @@ -12,7 +12,7 @@ // based on https://github.com/golang/go/blob/master/src/text/tabwriter/tabwriter.go Last modified 690ac40 on 31 Jan -//nolint:gocyclo,nakedret,revive,stylecheck,unused // ignore linting errors, so that we can stick close to upstream +//nolint:gocyclo,nakedret,stylecheck,unused // ignore linting errors, so that we can stick close to upstream package tabwriter import ( diff --git a/cli/command/registry/formatter_search.go b/cli/command/registry/formatter_search.go index ec11298968..3f557dea6a 100644 --- a/cli/command/registry/formatter_search.go +++ b/cli/command/registry/formatter_search.go @@ -97,5 +97,5 @@ func (c *searchContext) IsOfficial() string { // // Deprecated: the "is_automated" field is deprecated and will always be "false" in the future. func (c *searchContext) IsAutomated() string { - return c.formatBool(c.s.IsAutomated) //nolint:staticcheck // ignore SA1019 (IsAutomated is deprecated). + return c.formatBool(c.s.IsAutomated) //nolint:nolintlint,staticcheck // ignore SA1019 (IsAutomated is deprecated). } diff --git a/cli/command/registry/formatter_search_test.go b/cli/command/registry/formatter_search_test.go index 53d9f01e18..fd50a87f23 100644 --- a/cli/command/registry/formatter_search_test.go +++ b/cli/command/registry/formatter_search_test.go @@ -47,16 +47,16 @@ func TestSearchContext(t *testing.T) { }, { searchCtx: searchContext{ - s: registrytypes.SearchResult{IsAutomated: true}, //nolint:staticcheck // ignore SA1019 (IsAutomated is deprecated). + s: registrytypes.SearchResult{IsAutomated: true}, //nolint:nolintlint,staticcheck // ignore SA1019 (IsAutomated is deprecated). }, expValue: "[OK]", - call: ctx.IsAutomated, //nolint:staticcheck // ignore SA1019 (IsAutomated is deprecated). + call: ctx.IsAutomated, //nolint:nolintlint,staticcheck // ignore SA1019 (IsAutomated is deprecated). }, { searchCtx: searchContext{ s: registrytypes.SearchResult{}, }, - call: ctx.IsAutomated, //nolint:staticcheck // ignore SA1019 (IsAutomated is deprecated). + call: ctx.IsAutomated, //nolint:nolintlint,staticcheck // ignore SA1019 (IsAutomated is deprecated). }, } @@ -199,7 +199,7 @@ result2 5 results := []registrytypes.SearchResult{ {Name: "result1", Description: "Official build", StarCount: 5000, IsOfficial: true}, - {Name: "result2", Description: "Not official", StarCount: 5, IsAutomated: true}, //nolint:staticcheck // ignore SA1019 (IsAutomated is deprecated). + {Name: "result2", Description: "Not official", StarCount: 5, IsAutomated: true}, } for _, tc := range cases { diff --git a/cli/command/stack/loader/loader.go b/cli/command/stack/loader/loader.go index 2f41655b19..692681b3d1 100644 --- a/cli/command/stack/loader/loader.go +++ b/cli/command/stack/loader/loader.go @@ -28,9 +28,8 @@ func LoadComposefile(dockerCli command.Cli, opts options.Deploy) (*composetypes. config, err := loader.Load(configDetails) if err != nil { if fpe, ok := err.(*loader.ForbiddenPropertiesError); ok { - //nolint:revive // ignore capitalization error; this error is intentionally formatted multi-line - return nil, errors.Errorf("Compose file contains unsupported options:\n\n%s\n", - propertyWarnings(fpe.Properties)) + // this error is intentionally formatted multi-line + return nil, errors.Errorf("Compose file contains unsupported options:\n\n%s\n", propertyWarnings(fpe.Properties)) } return nil, err diff --git a/cli/connhelper/commandconn/pdeathsig_nolinux.go b/cli/connhelper/commandconn/pdeathsig_nolinux.go index 758fd1dfc4..149349e982 100644 --- a/cli/connhelper/commandconn/pdeathsig_nolinux.go +++ b/cli/connhelper/commandconn/pdeathsig_nolinux.go @@ -6,5 +6,4 @@ import ( "os/exec" ) -func setPdeathsig(cmd *exec.Cmd) { -} +func setPdeathsig(*exec.Cmd) {} diff --git a/templates/templates.go b/templates/templates.go index fc86841876..f0b62260ee 100644 --- a/templates/templates.go +++ b/templates/templates.go @@ -20,7 +20,7 @@ var basicFunctions = template.FuncMap{ }, "split": strings.Split, "join": strings.Join, - "title": strings.Title, //nolint:staticcheck // strings.Title is deprecated, but we only use it for ASCII, so replacing with golang.org/x/text is out of scope + "title": strings.Title, //nolint:nolintlint,staticcheck // strings.Title is deprecated, but we only use it for ASCII, so replacing with golang.org/x/text is out of scope "lower": strings.ToLower, "upper": strings.ToUpper, "pad": padWithSpace, From 30d36e977ea7d3a8ec6fdc54037d92a1fc1e2e41 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Fri, 2 Sep 2022 23:49:14 +0200 Subject: [PATCH 19/19] templates: linting: fix "error return value is not checked (errchkjson) The linter is correct; given that these functions do not allow for an error to be returned, we panic. Alternatively, we could return the error string as output, or add a `//nolint:errchkjson` comment. templates/templates.go:17:3: Error return value of `(*encoding/json.Encoder).Encode` is not checked: unsafe type `interface{}` found (errchkjson) enc.Encode(v) ^ Signed-off-by: Sebastiaan van Stijn --- .golangci.yml | 1 + templates/templates.go | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.golangci.yml b/.golangci.yml index c1ca4b920e..b7be9e413a 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -5,6 +5,7 @@ linters: - dogsled - dupword # Detects duplicate words. - durationcheck + - errchkjson - exportloopref # Detects pointers to enclosing loop variables. - gocritic # Metalinter; detects bugs, performance, and styling issues. - gocyclo diff --git a/templates/templates.go b/templates/templates.go index f0b62260ee..c1366be1cd 100644 --- a/templates/templates.go +++ b/templates/templates.go @@ -14,7 +14,11 @@ var basicFunctions = template.FuncMap{ buf := &bytes.Buffer{} enc := json.NewEncoder(buf) enc.SetEscapeHTML(false) - enc.Encode(v) + err := enc.Encode(v) + if err != nil { + panic(err) + } + // Remove the trailing new line added by the encoder return strings.TrimSpace(buf.String()) },