Skip to content

Commit 673a299

Browse files
committed
Merge pull request #259 from joshwget/parsing-options
Add options to make parsing more customizable
2 parents 8792767 + 38b319c commit 673a299

File tree

10 files changed

+187
-60
lines changed

10 files changed

+187
-60
lines changed

Diff for: cli/docker/app/factory.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,5 @@ func (p *ProjectFactory) Create(c *cli.Context) (project.APIProject, error) {
3030

3131
context.ProjectName = c.GlobalString("project-name")
3232

33-
return docker.NewProject(context)
33+
return docker.NewProject(context, nil)
3434
}

Diff for: config/merge.go

+21-5
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,18 @@ var (
1515
"links",
1616
"volumes_from",
1717
}
18+
defaultParseOptions = ParseOptions{
19+
Interpolate: true,
20+
Validate: true,
21+
}
1822
)
1923

2024
// Merge merges a compose file into an existing set of service configs
21-
func Merge(existingServices *ServiceConfigs, environmentLookup EnvironmentLookup, resourceLookup ResourceLookup, file string, bytes []byte) (map[string]*ServiceConfig, map[string]*VolumeConfig, map[string]*NetworkConfig, error) {
25+
func Merge(existingServices *ServiceConfigs, environmentLookup EnvironmentLookup, resourceLookup ResourceLookup, file string, bytes []byte, options *ParseOptions) (map[string]*ServiceConfig, map[string]*VolumeConfig, map[string]*NetworkConfig, error) {
26+
if options == nil {
27+
options = &defaultParseOptions
28+
}
29+
2230
var config Config
2331
if err := yaml.Unmarshal(bytes, &config); err != nil {
2432
return nil, nil, nil, err
@@ -29,20 +37,20 @@ func Merge(existingServices *ServiceConfigs, environmentLookup EnvironmentLookup
2937
var networkConfigs map[string]*NetworkConfig
3038
if config.Version == "2" {
3139
var err error
32-
serviceConfigs, err = MergeServicesV2(existingServices, environmentLookup, resourceLookup, file, bytes)
40+
serviceConfigs, err = MergeServicesV2(existingServices, environmentLookup, resourceLookup, file, bytes, options)
3341
if err != nil {
3442
return nil, nil, nil, err
3543
}
36-
volumeConfigs, err = ParseVolumes(environmentLookup, resourceLookup, file, bytes)
44+
volumeConfigs, err = ParseVolumes(bytes)
3745
if err != nil {
3846
return nil, nil, nil, err
3947
}
40-
networkConfigs, err = ParseNetworks(environmentLookup, resourceLookup, file, bytes)
48+
networkConfigs, err = ParseNetworks(bytes)
4149
if err != nil {
4250
return nil, nil, nil, err
4351
}
4452
} else {
45-
serviceConfigsV1, err := MergeServicesV1(existingServices, environmentLookup, resourceLookup, file, bytes)
53+
serviceConfigsV1, err := MergeServicesV1(existingServices, environmentLookup, resourceLookup, file, bytes, options)
4654
if err != nil {
4755
return nil, nil, nil, err
4856
}
@@ -54,6 +62,14 @@ func Merge(existingServices *ServiceConfigs, environmentLookup EnvironmentLookup
5462

5563
adjustValues(serviceConfigs)
5664

65+
if options.Postprocess != nil {
66+
var err error
67+
serviceConfigs, err = options.Postprocess(serviceConfigs)
68+
if err != nil {
69+
return nil, nil, nil, err
70+
}
71+
}
72+
5773
return serviceConfigs, volumeConfigs, networkConfigs, nil
5874
}
5975

Diff for: config/merge_test.go

+75-12
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ parent:
2020
child:
2121
extends:
2222
service: parent
23-
`))
23+
`), nil)
2424
if err != nil {
2525
t.Fatal(err)
2626
}
@@ -33,7 +33,7 @@ services:
3333
child:
3434
extends:
3535
service: parent
36-
`))
36+
`), nil)
3737
if err != nil {
3838
t.Fatal(err)
3939
}
@@ -63,7 +63,7 @@ parent:
6363
child:
6464
extends:
6565
service: parent
66-
`))
66+
`), nil)
6767
if err != nil {
6868
t.Fatal(err)
6969
}
@@ -77,7 +77,7 @@ services:
7777
child:
7878
extends:
7979
service: parent
80-
`))
80+
`), nil)
8181
if err != nil {
8282
t.Fatal(err)
8383
}
@@ -108,7 +108,7 @@ child:
108108
build: .
109109
extends:
110110
service: parent
111-
`))
111+
`), nil)
112112
if err != nil {
113113
t.Fatal(err)
114114
}
@@ -123,7 +123,7 @@ services:
123123
context: .
124124
extends:
125125
service: parent
126-
`))
126+
`), nil)
127127
if err != nil {
128128
t.Fatal(err)
129129
}
@@ -154,7 +154,7 @@ child:
154154
image: foo
155155
extends:
156156
service: parent
157-
`))
157+
`), nil)
158158
if err != nil {
159159
t.Fatal(err)
160160
}
@@ -169,7 +169,7 @@ services:
169169
image: foo
170170
extends:
171171
service: parent
172-
`))
172+
`), nil)
173173
if err != nil {
174174
t.Fatal(err)
175175
}
@@ -201,7 +201,7 @@ func TestRestartNo(t *testing.T) {
201201
test:
202202
restart: "no"
203203
image: foo
204-
`))
204+
`), nil)
205205
if err != nil {
206206
t.Fatal(err)
207207
}
@@ -212,7 +212,7 @@ services:
212212
test:
213213
restart: "no"
214214
image: foo
215-
`))
215+
`), nil)
216216
if err != nil {
217217
t.Fatal(err)
218218
}
@@ -231,7 +231,7 @@ func TestRestartAlways(t *testing.T) {
231231
test:
232232
restart: always
233233
image: foo
234-
`))
234+
`), nil)
235235
if err != nil {
236236
t.Fatal(err)
237237
}
@@ -242,7 +242,7 @@ services:
242242
test:
243243
restart: always
244244
image: foo
245-
`))
245+
`), nil)
246246
if err != nil {
247247
t.Fatal(err)
248248
}
@@ -288,3 +288,66 @@ func TestIsValidRemote(t *testing.T) {
288288
}
289289
}
290290
}
291+
292+
func preprocess(services RawServiceMap) (RawServiceMap, error) {
293+
for name := range services {
294+
services[name]["image"] = "foo2"
295+
}
296+
return services, nil
297+
}
298+
299+
func postprocess(services map[string]*ServiceConfig) (map[string]*ServiceConfig, error) {
300+
for name := range services {
301+
services[name].ContainerName = "cname"
302+
}
303+
return services, nil
304+
}
305+
306+
func TestParseOptions(t *testing.T) {
307+
parseOptions := ParseOptions{
308+
Interpolate: false,
309+
Validate: false,
310+
Preprocess: preprocess,
311+
Postprocess: postprocess,
312+
}
313+
314+
configV1, _, _, err := Merge(NewServiceConfigs(), nil, &NullLookup{}, "", []byte(`
315+
test:
316+
image: foo
317+
labels:
318+
x: $X
319+
test2:
320+
invalid_key: true
321+
`), &parseOptions)
322+
if err != nil {
323+
t.Fatal(err)
324+
}
325+
326+
configV2, _, _, err := Merge(NewServiceConfigs(), nil, &NullLookup{}, "", []byte(`
327+
version: '2'
328+
services:
329+
test:
330+
image: foo
331+
labels:
332+
x: $X
333+
test2:
334+
invalid_key: true
335+
`), &parseOptions)
336+
if err != nil {
337+
t.Fatal(err)
338+
}
339+
340+
for _, config := range []map[string]*ServiceConfig{configV1, configV2} {
341+
test := config["test"]
342+
343+
if test.Image != "foo2" {
344+
t.Fatal("Preprocess failed to change image", test.Image)
345+
}
346+
if test.ContainerName != "cname" {
347+
t.Fatal("Postprocess failed to change container name", test.ContainerName)
348+
}
349+
if test.Labels["x"] != "$X" {
350+
t.Fatal("Failed to disable interpolation")
351+
}
352+
}
353+
}

Diff for: config/merge_v1.go

+44-18
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,34 @@ import (
1010
)
1111

1212
// MergeServicesV1 merges a v1 compose file into an existing set of service configs
13-
func MergeServicesV1(existingServices *ServiceConfigs, environmentLookup EnvironmentLookup, resourceLookup ResourceLookup, file string, bytes []byte) (map[string]*ServiceConfigV1, error) {
13+
func MergeServicesV1(existingServices *ServiceConfigs, environmentLookup EnvironmentLookup, resourceLookup ResourceLookup, file string, bytes []byte, options *ParseOptions) (map[string]*ServiceConfigV1, error) {
1414
datas := make(RawServiceMap)
1515
if err := yaml.Unmarshal(bytes, &datas); err != nil {
1616
return nil, err
1717
}
1818

19-
if err := Interpolate(environmentLookup, &datas); err != nil {
20-
return nil, err
19+
if options.Interpolate {
20+
if err := Interpolate(environmentLookup, &datas); err != nil {
21+
return nil, err
22+
}
2123
}
2224

23-
if err := validate(datas); err != nil {
24-
return nil, err
25+
if options.Preprocess != nil {
26+
var err error
27+
datas, err = options.Preprocess(datas)
28+
if err != nil {
29+
return nil, err
30+
}
31+
}
32+
33+
if options.Validate {
34+
if err := validate(datas); err != nil {
35+
return nil, err
36+
}
2537
}
2638

2739
for name, data := range datas {
28-
data, err := parseV1(resourceLookup, environmentLookup, file, data, datas)
40+
data, err := parseV1(resourceLookup, environmentLookup, file, data, datas, options)
2941
if err != nil {
3042
logrus.Errorf("Failed to parse service %s: %v", name, err)
3143
return nil, err
@@ -43,10 +55,12 @@ func MergeServicesV1(existingServices *ServiceConfigs, environmentLookup Environ
4355
datas[name] = data
4456
}
4557

46-
for name, data := range datas {
47-
err := validateServiceConstraints(data, name)
48-
if err != nil {
49-
return nil, err
58+
if options.Validate {
59+
for name, data := range datas {
60+
err := validateServiceConstraints(data, name)
61+
if err != nil {
62+
return nil, err
63+
}
5064
}
5165
}
5266

@@ -58,7 +72,7 @@ func MergeServicesV1(existingServices *ServiceConfigs, environmentLookup Environ
5872
return serviceConfigs, nil
5973
}
6074

61-
func parseV1(resourceLookup ResourceLookup, environmentLookup EnvironmentLookup, inFile string, serviceData RawService, datas RawServiceMap) (RawService, error) {
75+
func parseV1(resourceLookup ResourceLookup, environmentLookup EnvironmentLookup, inFile string, serviceData RawService, datas RawServiceMap, options *ParseOptions) (RawService, error) {
6276
serviceData, err := readEnvFile(resourceLookup, inFile, serviceData)
6377
if err != nil {
6478
return nil, err
@@ -91,7 +105,7 @@ func parseV1(resourceLookup ResourceLookup, environmentLookup EnvironmentLookup,
91105

92106
if file == "" {
93107
if serviceData, ok := datas[service]; ok {
94-
baseService, err = parseV1(resourceLookup, environmentLookup, inFile, serviceData, datas)
108+
baseService, err = parseV1(resourceLookup, environmentLookup, inFile, serviceData, datas, options)
95109
} else {
96110
return nil, fmt.Errorf("Failed to find service %s to extend", service)
97111
}
@@ -107,21 +121,33 @@ func parseV1(resourceLookup ResourceLookup, environmentLookup EnvironmentLookup,
107121
return nil, err
108122
}
109123

110-
err = Interpolate(environmentLookup, &baseRawServices)
111-
if err != nil {
112-
return nil, err
124+
if options.Interpolate {
125+
err = Interpolate(environmentLookup, &baseRawServices)
126+
if err != nil {
127+
return nil, err
128+
}
113129
}
114130

115-
if err := validate(baseRawServices); err != nil {
116-
return nil, err
131+
if options.Preprocess != nil {
132+
var err error
133+
baseRawServices, err = options.Preprocess(baseRawServices)
134+
if err != nil {
135+
return nil, err
136+
}
137+
}
138+
139+
if options.Validate {
140+
if err := validate(baseRawServices); err != nil {
141+
return nil, err
142+
}
117143
}
118144

119145
baseService, ok = baseRawServices[service]
120146
if !ok {
121147
return nil, fmt.Errorf("Failed to find service %s in file %s", service, file)
122148
}
123149

124-
baseService, err = parseV1(resourceLookup, environmentLookup, resolved, baseService, baseRawServices)
150+
baseService, err = parseV1(resourceLookup, environmentLookup, resolved, baseService, baseRawServices, options)
125151
}
126152

127153
if err != nil {

0 commit comments

Comments
 (0)