Browse code

Remove compose types.Dict alias

It is just an alias type and make the code a little bit more complex
and hard to use from outside `compose` package.

Signed-off-by: Vincent Demeester <vincent@sbr.pm>

Vincent Demeester authored on 2017/03/22 23:42:03
Showing 5 changed files
... ...
@@ -4,19 +4,18 @@ import (
4 4
 	"fmt"
5 5
 
6 6
 	"github.com/docker/docker/cli/compose/template"
7
-	"github.com/docker/docker/cli/compose/types"
8 7
 )
9 8
 
10 9
 // Interpolate replaces variables in a string with the values from a mapping
11
-func Interpolate(config types.Dict, section string, mapping template.Mapping) (types.Dict, error) {
12
-	out := types.Dict{}
10
+func Interpolate(config map[string]interface{}, section string, mapping template.Mapping) (map[string]interface{}, error) {
11
+	out := map[string]interface{}{}
13 12
 
14 13
 	for name, item := range config {
15 14
 		if item == nil {
16 15
 			out[name] = nil
17 16
 			continue
18 17
 		}
19
-		interpolatedItem, err := interpolateSectionItem(name, item.(types.Dict), section, mapping)
18
+		interpolatedItem, err := interpolateSectionItem(name, item.(map[string]interface{}), section, mapping)
20 19
 		if err != nil {
21 20
 			return nil, err
22 21
 		}
... ...
@@ -28,12 +27,12 @@ func Interpolate(config types.Dict, section string, mapping template.Mapping) (t
28 28
 
29 29
 func interpolateSectionItem(
30 30
 	name string,
31
-	item types.Dict,
31
+	item map[string]interface{},
32 32
 	section string,
33 33
 	mapping template.Mapping,
34
-) (types.Dict, error) {
34
+) (map[string]interface{}, error) {
35 35
 
36
-	out := types.Dict{}
36
+	out := map[string]interface{}{}
37 37
 
38 38
 	for key, value := range item {
39 39
 		interpolatedValue, err := recursiveInterpolate(value, mapping)
... ...
@@ -60,8 +59,8 @@ func recursiveInterpolate(
60 60
 	case string:
61 61
 		return template.Substitute(value, mapping)
62 62
 
63
-	case types.Dict:
64
-		out := types.Dict{}
63
+	case map[string]interface{}:
64
+		out := map[string]interface{}{}
65 65
 		for key, elem := range value {
66 66
 			interpolatedElem, err := recursiveInterpolate(elem, mapping)
67 67
 			if err != nil {
... ...
@@ -4,8 +4,6 @@ import (
4 4
 	"testing"
5 5
 
6 6
 	"github.com/stretchr/testify/assert"
7
-
8
-	"github.com/docker/docker/cli/compose/types"
9 7
 )
10 8
 
11 9
 var defaults = map[string]string{
... ...
@@ -19,25 +17,25 @@ func defaultMapping(name string) (string, bool) {
19 19
 }
20 20
 
21 21
 func TestInterpolate(t *testing.T) {
22
-	services := types.Dict{
23
-		"servicea": types.Dict{
22
+	services := map[string]interface{}{
23
+		"servicea": map[string]interface{}{
24 24
 			"image":   "example:${USER}",
25 25
 			"volumes": []interface{}{"$FOO:/target"},
26
-			"logging": types.Dict{
26
+			"logging": map[string]interface{}{
27 27
 				"driver": "${FOO}",
28
-				"options": types.Dict{
28
+				"options": map[string]interface{}{
29 29
 					"user": "$USER",
30 30
 				},
31 31
 			},
32 32
 		},
33 33
 	}
34
-	expected := types.Dict{
35
-		"servicea": types.Dict{
34
+	expected := map[string]interface{}{
35
+		"servicea": map[string]interface{}{
36 36
 			"image":   "example:jenny",
37 37
 			"volumes": []interface{}{"bar:/target"},
38
-			"logging": types.Dict{
38
+			"logging": map[string]interface{}{
39 39
 				"driver": "bar",
40
-				"options": types.Dict{
40
+				"options": map[string]interface{}{
41 41
 					"user": "jenny",
42 42
 				},
43 43
 			},
... ...
@@ -49,8 +47,8 @@ func TestInterpolate(t *testing.T) {
49 49
 }
50 50
 
51 51
 func TestInvalidInterpolation(t *testing.T) {
52
-	services := types.Dict{
53
-		"servicea": types.Dict{
52
+	services := map[string]interface{}{
53
+		"servicea": map[string]interface{}{
54 54
 			"image": "${",
55 55
 		},
56 56
 	}
... ...
@@ -28,7 +28,7 @@ var (
28 28
 
29 29
 // ParseYAML reads the bytes from a file, parses the bytes into a mapping
30 30
 // structure, and returns it.
31
-func ParseYAML(source []byte) (types.Dict, error) {
31
+func ParseYAML(source []byte) (map[string]interface{}, error) {
32 32
 	var cfg interface{}
33 33
 	if err := yaml.Unmarshal(source, &cfg); err != nil {
34 34
 		return nil, err
... ...
@@ -41,7 +41,7 @@ func ParseYAML(source []byte) (types.Dict, error) {
41 41
 	if err != nil {
42 42
 		return nil, err
43 43
 	}
44
-	return converted.(types.Dict), nil
44
+	return converted.(map[string]interface{}), nil
45 45
 }
46 46
 
47 47
 // Load reads a ConfigDetails and returns a fully loaded configuration
... ...
@@ -56,7 +56,7 @@ func Load(configDetails types.ConfigDetails) (*types.Config, error) {
56 56
 	configDict := getConfigDict(configDetails)
57 57
 
58 58
 	if services, ok := configDict["services"]; ok {
59
-		if servicesDict, ok := services.(types.Dict); ok {
59
+		if servicesDict, ok := services.(map[string]interface{}); ok {
60 60
 			forbidden := getProperties(servicesDict, types.ForbiddenProperties)
61 61
 
62 62
 			if len(forbidden) > 0 {
... ...
@@ -75,7 +75,7 @@ func Load(configDetails types.ConfigDetails) (*types.Config, error) {
75 75
 		return v, ok
76 76
 	}
77 77
 	if services, ok := configDict["services"]; ok {
78
-		servicesConfig, err := interpolation.Interpolate(services.(types.Dict), "service", lookupEnv)
78
+		servicesConfig, err := interpolation.Interpolate(services.(map[string]interface{}), "service", lookupEnv)
79 79
 		if err != nil {
80 80
 			return nil, err
81 81
 		}
... ...
@@ -89,7 +89,7 @@ func Load(configDetails types.ConfigDetails) (*types.Config, error) {
89 89
 	}
90 90
 
91 91
 	if networks, ok := configDict["networks"]; ok {
92
-		networksConfig, err := interpolation.Interpolate(networks.(types.Dict), "network", lookupEnv)
92
+		networksConfig, err := interpolation.Interpolate(networks.(map[string]interface{}), "network", lookupEnv)
93 93
 		if err != nil {
94 94
 			return nil, err
95 95
 		}
... ...
@@ -103,7 +103,7 @@ func Load(configDetails types.ConfigDetails) (*types.Config, error) {
103 103
 	}
104 104
 
105 105
 	if volumes, ok := configDict["volumes"]; ok {
106
-		volumesConfig, err := interpolation.Interpolate(volumes.(types.Dict), "volume", lookupEnv)
106
+		volumesConfig, err := interpolation.Interpolate(volumes.(map[string]interface{}), "volume", lookupEnv)
107 107
 		if err != nil {
108 108
 			return nil, err
109 109
 		}
... ...
@@ -117,7 +117,7 @@ func Load(configDetails types.ConfigDetails) (*types.Config, error) {
117 117
 	}
118 118
 
119 119
 	if secrets, ok := configDict["secrets"]; ok {
120
-		secretsConfig, err := interpolation.Interpolate(secrets.(types.Dict), "secret", lookupEnv)
120
+		secretsConfig, err := interpolation.Interpolate(secrets.(map[string]interface{}), "secret", lookupEnv)
121 121
 		if err != nil {
122 122
 			return nil, err
123 123
 		}
... ...
@@ -139,7 +139,7 @@ func GetUnsupportedProperties(configDetails types.ConfigDetails) []string {
139 139
 	unsupported := map[string]bool{}
140 140
 
141 141
 	for _, service := range getServices(getConfigDict(configDetails)) {
142
-		serviceDict := service.(types.Dict)
142
+		serviceDict := service.(map[string]interface{})
143 143
 		for _, property := range types.UnsupportedProperties {
144 144
 			if _, isSet := serviceDict[property]; isSet {
145 145
 				unsupported[property] = true
... ...
@@ -165,11 +165,11 @@ func GetDeprecatedProperties(configDetails types.ConfigDetails) map[string]strin
165 165
 	return getProperties(getServices(getConfigDict(configDetails)), types.DeprecatedProperties)
166 166
 }
167 167
 
168
-func getProperties(services types.Dict, propertyMap map[string]string) map[string]string {
168
+func getProperties(services map[string]interface{}, propertyMap map[string]string) map[string]string {
169 169
 	output := map[string]string{}
170 170
 
171 171
 	for _, service := range services {
172
-		if serviceDict, ok := service.(types.Dict); ok {
172
+		if serviceDict, ok := service.(map[string]interface{}); ok {
173 173
 			for property, description := range propertyMap {
174 174
 				if _, isSet := serviceDict[property]; isSet {
175 175
 					output[property] = description
... ...
@@ -192,18 +192,18 @@ func (e *ForbiddenPropertiesError) Error() string {
192 192
 }
193 193
 
194 194
 // TODO: resolve multiple files into a single config
195
-func getConfigDict(configDetails types.ConfigDetails) types.Dict {
195
+func getConfigDict(configDetails types.ConfigDetails) map[string]interface{} {
196 196
 	return configDetails.ConfigFiles[0].Config
197 197
 }
198 198
 
199
-func getServices(configDict types.Dict) types.Dict {
199
+func getServices(configDict map[string]interface{}) map[string]interface{} {
200 200
 	if services, ok := configDict["services"]; ok {
201
-		if servicesDict, ok := services.(types.Dict); ok {
201
+		if servicesDict, ok := services.(map[string]interface{}); ok {
202 202
 			return servicesDict
203 203
 		}
204 204
 	}
205 205
 
206
-	return types.Dict{}
206
+	return map[string]interface{}{}
207 207
 }
208 208
 
209 209
 func transform(source map[string]interface{}, target interface{}) error {
... ...
@@ -265,10 +265,9 @@ func transformHook(
265 265
 }
266 266
 
267 267
 // keys needs to be converted to strings for jsonschema
268
-// TODO: don't use types.Dict
269 268
 func convertToStringKeysRecursive(value interface{}, keyPrefix string) (interface{}, error) {
270 269
 	if mapping, ok := value.(map[interface{}]interface{}); ok {
271
-		dict := make(types.Dict)
270
+		dict := make(map[string]interface{})
272 271
 		for key, entry := range mapping {
273 272
 			str, ok := key.(string)
274 273
 			if !ok {
... ...
@@ -315,11 +314,11 @@ func formatInvalidKeyError(keyPrefix string, key interface{}) error {
315 315
 
316 316
 // LoadServices produces a ServiceConfig map from a compose file Dict
317 317
 // the servicesDict is not validated if directly used. Use Load() to enable validation
318
-func LoadServices(servicesDict types.Dict, workingDir string, lookupEnv template.Mapping) ([]types.ServiceConfig, error) {
318
+func LoadServices(servicesDict map[string]interface{}, workingDir string, lookupEnv template.Mapping) ([]types.ServiceConfig, error) {
319 319
 	var services []types.ServiceConfig
320 320
 
321 321
 	for name, serviceDef := range servicesDict {
322
-		serviceConfig, err := LoadService(name, serviceDef.(types.Dict), workingDir, lookupEnv)
322
+		serviceConfig, err := LoadService(name, serviceDef.(map[string]interface{}), workingDir, lookupEnv)
323 323
 		if err != nil {
324 324
 			return nil, err
325 325
 		}
... ...
@@ -331,7 +330,7 @@ func LoadServices(servicesDict types.Dict, workingDir string, lookupEnv template
331 331
 
332 332
 // LoadService produces a single ServiceConfig from a compose file Dict
333 333
 // the serviceDict is not validated if directly used. Use Load() to enable validation
334
-func LoadService(name string, serviceDict types.Dict, workingDir string, lookupEnv template.Mapping) (*types.ServiceConfig, error) {
334
+func LoadService(name string, serviceDict map[string]interface{}, workingDir string, lookupEnv template.Mapping) (*types.ServiceConfig, error) {
335 335
 	serviceConfig := &types.ServiceConfig{}
336 336
 	if err := transform(serviceDict, serviceConfig); err != nil {
337 337
 		return nil, err
... ...
@@ -409,7 +408,7 @@ func transformUlimits(data interface{}) (interface{}, error) {
409 409
 	switch value := data.(type) {
410 410
 	case int:
411 411
 		return types.UlimitsConfig{Single: value}, nil
412
-	case types.Dict:
412
+	case map[string]interface{}:
413 413
 		ulimit := types.UlimitsConfig{}
414 414
 		ulimit.Soft = value["soft"].(int)
415 415
 		ulimit.Hard = value["hard"].(int)
... ...
@@ -421,7 +420,7 @@ func transformUlimits(data interface{}) (interface{}, error) {
421 421
 
422 422
 // LoadNetworks produces a NetworkConfig map from a compose file Dict
423 423
 // the source Dict is not validated if directly used. Use Load() to enable validation
424
-func LoadNetworks(source types.Dict) (map[string]types.NetworkConfig, error) {
424
+func LoadNetworks(source map[string]interface{}) (map[string]types.NetworkConfig, error) {
425 425
 	networks := make(map[string]types.NetworkConfig)
426 426
 	err := transform(source, &networks)
427 427
 	if err != nil {
... ...
@@ -438,7 +437,7 @@ func LoadNetworks(source types.Dict) (map[string]types.NetworkConfig, error) {
438 438
 
439 439
 // LoadVolumes produces a VolumeConfig map from a compose file Dict
440 440
 // the source Dict is not validated if directly used. Use Load() to enable validation
441
-func LoadVolumes(source types.Dict) (map[string]types.VolumeConfig, error) {
441
+func LoadVolumes(source map[string]interface{}) (map[string]types.VolumeConfig, error) {
442 442
 	volumes := make(map[string]types.VolumeConfig)
443 443
 	err := transform(source, &volumes)
444 444
 	if err != nil {
... ...
@@ -467,7 +466,7 @@ func LoadVolumes(source types.Dict) (map[string]types.VolumeConfig, error) {
467 467
 
468 468
 // LoadSecrets produces a SecretConfig map from a compose file Dict
469 469
 // the source Dict is not validated if directly used. Use Load() to enable validation
470
-func LoadSecrets(source types.Dict, workingDir string) (map[string]types.SecretConfig, error) {
470
+func LoadSecrets(source map[string]interface{}, workingDir string) (map[string]types.SecretConfig, error) {
471 471
 	secrets := make(map[string]types.SecretConfig)
472 472
 	if err := transform(source, &secrets); err != nil {
473 473
 		return secrets, err
... ...
@@ -495,8 +494,6 @@ func transformMapStringString(data interface{}) (interface{}, error) {
495 495
 	switch value := data.(type) {
496 496
 	case map[string]interface{}:
497 497
 		return toMapStringString(value, false), nil
498
-	case types.Dict:
499
-		return toMapStringString(value, false), nil
500 498
 	case map[string]string:
501 499
 		return value, nil
502 500
 	default:
... ...
@@ -508,8 +505,6 @@ func transformExternal(data interface{}) (interface{}, error) {
508 508
 	switch value := data.(type) {
509 509
 	case bool:
510 510
 		return map[string]interface{}{"external": value}, nil
511
-	case types.Dict:
512
-		return map[string]interface{}{"external": true, "name": value["name"]}, nil
513 511
 	case map[string]interface{}:
514 512
 		return map[string]interface{}{"external": true, "name": value["name"]}, nil
515 513
 	default:
... ...
@@ -538,8 +533,6 @@ func transformServicePort(data interface{}) (interface{}, error) {
538 538
 					return data, err
539 539
 				}
540 540
 				ports = append(ports, v...)
541
-			case types.Dict:
542
-				ports = append(ports, value)
543 541
 			case map[string]interface{}:
544 542
 				ports = append(ports, value)
545 543
 			default:
... ...
@@ -556,8 +549,6 @@ func transformServiceSecret(data interface{}) (interface{}, error) {
556 556
 	switch value := data.(type) {
557 557
 	case string:
558 558
 		return map[string]interface{}{"source": value}, nil
559
-	case types.Dict:
560
-		return data, nil
561 559
 	case map[string]interface{}:
562 560
 		return data, nil
563 561
 	default:
... ...
@@ -569,8 +560,6 @@ func transformServiceVolumeConfig(data interface{}) (interface{}, error) {
569 569
 	switch value := data.(type) {
570 570
 	case string:
571 571
 		return parseVolume(value)
572
-	case types.Dict:
573
-		return data, nil
574 572
 	case map[string]interface{}:
575 573
 		return data, nil
576 574
 	default:
... ...
@@ -612,7 +601,7 @@ func transformStringList(data interface{}) (interface{}, error) {
612 612
 
613 613
 func transformMappingOrList(mappingOrList interface{}, sep string, allowNil bool) interface{} {
614 614
 	switch value := mappingOrList.(type) {
615
-	case types.Dict:
615
+	case map[string]interface{}:
616 616
 		return toMapStringString(value, allowNil)
617 617
 	case ([]interface{}):
618 618
 		result := make(map[string]interface{})
... ...
@@ -12,7 +12,7 @@ import (
12 12
 	"github.com/stretchr/testify/assert"
13 13
 )
14 14
 
15
-func buildConfigDetails(source types.Dict, env map[string]string) types.ConfigDetails {
15
+func buildConfigDetails(source map[string]interface{}, env map[string]string) types.ConfigDetails {
16 16
 	workingDir, err := os.Getwd()
17 17
 	if err != nil {
18 18
 		panic(err)
... ...
@@ -70,39 +70,39 @@ networks:
70 70
         - subnet: 172.28.0.0/16
71 71
 `
72 72
 
73
-var sampleDict = types.Dict{
73
+var sampleDict = map[string]interface{}{
74 74
 	"version": "3",
75
-	"services": types.Dict{
76
-		"foo": types.Dict{
75
+	"services": map[string]interface{}{
76
+		"foo": map[string]interface{}{
77 77
 			"image":    "busybox",
78
-			"networks": types.Dict{"with_me": nil},
78
+			"networks": map[string]interface{}{"with_me": nil},
79 79
 		},
80
-		"bar": types.Dict{
80
+		"bar": map[string]interface{}{
81 81
 			"image":       "busybox",
82 82
 			"environment": []interface{}{"FOO=1"},
83 83
 			"networks":    []interface{}{"with_ipam"},
84 84
 		},
85 85
 	},
86
-	"volumes": types.Dict{
87
-		"hello": types.Dict{
86
+	"volumes": map[string]interface{}{
87
+		"hello": map[string]interface{}{
88 88
 			"driver": "default",
89
-			"driver_opts": types.Dict{
89
+			"driver_opts": map[string]interface{}{
90 90
 				"beep": "boop",
91 91
 			},
92 92
 		},
93 93
 	},
94
-	"networks": types.Dict{
95
-		"default": types.Dict{
94
+	"networks": map[string]interface{}{
95
+		"default": map[string]interface{}{
96 96
 			"driver": "bridge",
97
-			"driver_opts": types.Dict{
97
+			"driver_opts": map[string]interface{}{
98 98
 				"beep": "boop",
99 99
 			},
100 100
 		},
101
-		"with_ipam": types.Dict{
102
-			"ipam": types.Dict{
101
+		"with_ipam": map[string]interface{}{
102
+			"ipam": map[string]interface{}{
103 103
 				"driver": "default",
104 104
 				"config": []interface{}{
105
-					types.Dict{
105
+					map[string]interface{}{
106 106
 						"subnet": "172.28.0.0/16",
107 107
 					},
108 108
 				},
... ...
@@ -50,13 +50,10 @@ var ForbiddenProperties = map[string]string{
50 50
 	"memswap_limit": "Set resource limits using deploy.resources",
51 51
 }
52 52
 
53
-// Dict is a mapping of strings to interface{}
54
-type Dict map[string]interface{}
55
-
56 53
 // ConfigFile is a filename and the contents of the file as a Dict
57 54
 type ConfigFile struct {
58 55
 	Filename string
59
-	Config   Dict
56
+	Config   map[string]interface{}
60 57
 }
61 58
 
62 59
 // ConfigDetails are the details about a group of ConfigFiles