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)