Skip to content

Commit

Permalink
Merge pull request #466 from glours/include-check-same-service
Browse files Browse the repository at this point in the history
avoid to fail if a duplicate resource is the same as a previous added ones
  • Loading branch information
ndeloof authored Sep 29, 2023
2 parents 09fd935 + f989a73 commit 4b1e1a4
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 10 deletions.
31 changes: 25 additions & 6 deletions loader/include.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"context"
"fmt"
"path/filepath"
"reflect"

"github.com/compose-spec/compose-go/dotenv"
interp "github.com/compose-spec/compose-go/interpolation"
Expand Down Expand Up @@ -109,37 +110,55 @@ func loadInclude(ctx context.Context, filename string, configDetails types.Confi
func importResources(model *types.Config, imported *types.Project, path []string) error {
services := mapByName(model.Services)
for _, service := range imported.Services {
if _, ok := services[service.Name]; ok {
if present, ok := services[service.Name]; ok {
if reflect.DeepEqual(present, service) {
continue
}
return fmt.Errorf("imported compose file %s defines conflicting service %s", path, service.Name)
}
model.Services = append(model.Services, service)
}
for _, service := range imported.DisabledServices {
if _, ok := services[service.Name]; ok {
if disabled, ok := services[service.Name]; ok {
if reflect.DeepEqual(disabled, service) {
continue
}
return fmt.Errorf("imported compose file %s defines conflicting service %s", path, service.Name)
}
model.Services = append(model.Services, service)
}
for n, network := range imported.Networks {
if _, ok := model.Networks[n]; ok {
if present, ok := model.Networks[n]; ok {
if reflect.DeepEqual(present, network) {
continue
}
return fmt.Errorf("imported compose file %s defines conflicting network %s", path, n)
}
model.Networks[n] = network
}
for n, volume := range imported.Volumes {
if _, ok := model.Volumes[n]; ok {
if present, ok := model.Volumes[n]; ok {
if reflect.DeepEqual(present, volume) {
continue
}
return fmt.Errorf("imported compose file %s defines conflicting volume %s", path, n)
}
model.Volumes[n] = volume
}
for n, secret := range imported.Secrets {
if _, ok := model.Secrets[n]; ok {
if present, ok := model.Secrets[n]; ok {
if reflect.DeepEqual(present, secret) {
continue
}
return fmt.Errorf("imported compose file %s defines conflicting secret %s", path, n)
}
model.Secrets[n] = secret
}
for n, config := range imported.Configs {
if _, ok := model.Configs[n]; ok {
if present, ok := model.Configs[n]; ok {
if reflect.DeepEqual(present, config) {
continue
}
return fmt.Errorf("imported compose file %s defines conflicting config %s", path, n)
}
model.Configs[n] = config
Expand Down
45 changes: 44 additions & 1 deletion loader/loader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2604,13 +2604,56 @@ func TestLoadWithIncludeCycle(t *testing.T) {
WorkingDir: filepath.Join(workingDir, "testdata"),
ConfigFiles: []types.ConfigFile{
{
Filename: filepath.Join(workingDir, "testdata", "compose-include.yaml"),
Filename: filepath.Join(workingDir, "testdata", "compose-include-cycle.yaml"),
},
},
})
assert.Check(t, strings.HasPrefix(err.Error(), "include cycle detected"))
}

func TestLoadWithMultipleInclude(t *testing.T) {
// include same service twice should not trigger an error
p, err := Load(buildConfigDetails(`
name: 'test-multi-include'
include:
- path: ./testdata/subdir/compose-test-extends-imported.yaml
env_file: ./testdata/subdir/extra.env
- path: ./testdata/compose-include.yaml
services:
foo:
image: busybox
depends_on:
- imported
`, map[string]string{"SOURCE": "override"}), func(options *Options) {
options.SkipNormalization = true
options.ResolvePaths = true
})
assert.NilError(t, err)
assert.Equal(t, p.Services[1].ContainerName, "override")

// include 2 different services with same name should trigger an error
p, err = Load(buildConfigDetails(`
name: 'test-multi-include'
include:
- path: ./testdata/subdir/compose-test-extends-imported.yaml
env_file: ./testdata/subdir/extra.env
- path: ./testdata/compose-include.yaml
env_file: ./testdata/subdir/extra.env
services:
bar:
image: busybox
`, map[string]string{"SOURCE": "override"}), func(options *Options) {
options.SkipNormalization = true
options.ResolvePaths = true
})
assert.ErrorContains(t, err, "defines conflicting service bar", err)
}

func TestLoadWithDependsOn(t *testing.T) {
p, err := loadYAML(`
name: test-depends-on
Expand Down
6 changes: 6 additions & 0 deletions loader/testdata/compose-include-cycle.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
include:
- compose-include-cycle.yaml

services:
foo:
image: foo
6 changes: 3 additions & 3 deletions loader/testdata/compose-include.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
include:
- compose-include.yaml
- path: ./subdir/compose-test-extends-imported.yaml

services:
foo:
image: foo
bar:
image: bar

0 comments on commit 4b1e1a4

Please sign in to comment.