Skip to content

Commit f989a73

Browse files
committed
avoid to fail if a duplicate resource is the same as a previous added one
Signed-off-by: Guillaume Lours <[email protected]>
1 parent 09fd935 commit f989a73

File tree

4 files changed

+78
-10
lines changed

4 files changed

+78
-10
lines changed

loader/include.go

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"context"
2121
"fmt"
2222
"path/filepath"
23+
"reflect"
2324

2425
"github.com/compose-spec/compose-go/dotenv"
2526
interp "github.com/compose-spec/compose-go/interpolation"
@@ -109,37 +110,55 @@ func loadInclude(ctx context.Context, filename string, configDetails types.Confi
109110
func importResources(model *types.Config, imported *types.Project, path []string) error {
110111
services := mapByName(model.Services)
111112
for _, service := range imported.Services {
112-
if _, ok := services[service.Name]; ok {
113+
if present, ok := services[service.Name]; ok {
114+
if reflect.DeepEqual(present, service) {
115+
continue
116+
}
113117
return fmt.Errorf("imported compose file %s defines conflicting service %s", path, service.Name)
114118
}
115119
model.Services = append(model.Services, service)
116120
}
117121
for _, service := range imported.DisabledServices {
118-
if _, ok := services[service.Name]; ok {
122+
if disabled, ok := services[service.Name]; ok {
123+
if reflect.DeepEqual(disabled, service) {
124+
continue
125+
}
119126
return fmt.Errorf("imported compose file %s defines conflicting service %s", path, service.Name)
120127
}
121128
model.Services = append(model.Services, service)
122129
}
123130
for n, network := range imported.Networks {
124-
if _, ok := model.Networks[n]; ok {
131+
if present, ok := model.Networks[n]; ok {
132+
if reflect.DeepEqual(present, network) {
133+
continue
134+
}
125135
return fmt.Errorf("imported compose file %s defines conflicting network %s", path, n)
126136
}
127137
model.Networks[n] = network
128138
}
129139
for n, volume := range imported.Volumes {
130-
if _, ok := model.Volumes[n]; ok {
140+
if present, ok := model.Volumes[n]; ok {
141+
if reflect.DeepEqual(present, volume) {
142+
continue
143+
}
131144
return fmt.Errorf("imported compose file %s defines conflicting volume %s", path, n)
132145
}
133146
model.Volumes[n] = volume
134147
}
135148
for n, secret := range imported.Secrets {
136-
if _, ok := model.Secrets[n]; ok {
149+
if present, ok := model.Secrets[n]; ok {
150+
if reflect.DeepEqual(present, secret) {
151+
continue
152+
}
137153
return fmt.Errorf("imported compose file %s defines conflicting secret %s", path, n)
138154
}
139155
model.Secrets[n] = secret
140156
}
141157
for n, config := range imported.Configs {
142-
if _, ok := model.Configs[n]; ok {
158+
if present, ok := model.Configs[n]; ok {
159+
if reflect.DeepEqual(present, config) {
160+
continue
161+
}
143162
return fmt.Errorf("imported compose file %s defines conflicting config %s", path, n)
144163
}
145164
model.Configs[n] = config

loader/loader_test.go

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2604,13 +2604,56 @@ func TestLoadWithIncludeCycle(t *testing.T) {
26042604
WorkingDir: filepath.Join(workingDir, "testdata"),
26052605
ConfigFiles: []types.ConfigFile{
26062606
{
2607-
Filename: filepath.Join(workingDir, "testdata", "compose-include.yaml"),
2607+
Filename: filepath.Join(workingDir, "testdata", "compose-include-cycle.yaml"),
26082608
},
26092609
},
26102610
})
26112611
assert.Check(t, strings.HasPrefix(err.Error(), "include cycle detected"))
26122612
}
26132613

2614+
func TestLoadWithMultipleInclude(t *testing.T) {
2615+
// include same service twice should not trigger an error
2616+
p, err := Load(buildConfigDetails(`
2617+
name: 'test-multi-include'
2618+
2619+
include:
2620+
- path: ./testdata/subdir/compose-test-extends-imported.yaml
2621+
env_file: ./testdata/subdir/extra.env
2622+
- path: ./testdata/compose-include.yaml
2623+
2624+
services:
2625+
foo:
2626+
image: busybox
2627+
depends_on:
2628+
- imported
2629+
`, map[string]string{"SOURCE": "override"}), func(options *Options) {
2630+
options.SkipNormalization = true
2631+
options.ResolvePaths = true
2632+
})
2633+
assert.NilError(t, err)
2634+
assert.Equal(t, p.Services[1].ContainerName, "override")
2635+
2636+
// include 2 different services with same name should trigger an error
2637+
p, err = Load(buildConfigDetails(`
2638+
name: 'test-multi-include'
2639+
2640+
include:
2641+
- path: ./testdata/subdir/compose-test-extends-imported.yaml
2642+
env_file: ./testdata/subdir/extra.env
2643+
- path: ./testdata/compose-include.yaml
2644+
env_file: ./testdata/subdir/extra.env
2645+
2646+
2647+
services:
2648+
bar:
2649+
image: busybox
2650+
`, map[string]string{"SOURCE": "override"}), func(options *Options) {
2651+
options.SkipNormalization = true
2652+
options.ResolvePaths = true
2653+
})
2654+
assert.ErrorContains(t, err, "defines conflicting service bar", err)
2655+
}
2656+
26142657
func TestLoadWithDependsOn(t *testing.T) {
26152658
p, err := loadYAML(`
26162659
name: test-depends-on
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
include:
2+
- compose-include-cycle.yaml
3+
4+
services:
5+
foo:
6+
image: foo
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
include:
2-
- compose-include.yaml
2+
- path: ./subdir/compose-test-extends-imported.yaml
33

44
services:
5-
foo:
6-
image: foo
5+
bar:
6+
image: bar

0 commit comments

Comments
 (0)