Skip to content

Commit

Permalink
fix TestMergeTopLevelExtensions
Browse files Browse the repository at this point in the history
Signed-off-by: Nicolas De Loof <[email protected]>
  • Loading branch information
ndeloof committed Oct 16, 2023
1 parent ece2e63 commit af73475
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 101 deletions.
2 changes: 1 addition & 1 deletion consts/consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ const (
ComposeProfiles = "COMPOSE_PROFILES"
)

const Extensions = "#Extensions" // Using # prefix, we prevent risk to conflict with an actual yaml key
const Extensions = "#extensions" // Using # prefix, we prevent risk to conflict with an actual yaml key
17 changes: 5 additions & 12 deletions loader/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -394,22 +394,14 @@ func load(ctx context.Context, configDetails types.ConfigDetails, opts *Options,
return nil, errors.New("empty compose file")
}

var model types.Config
err = Transform(dict, &model)
if err != nil {
return nil, err
}

project := &types.Project{
Name: opts.projectName,
WorkingDir: configDetails.WorkingDir,
Services: model.Services,
Networks: model.Networks,
Volumes: model.Volumes,
Secrets: model.Secrets,
Configs: model.Configs,
Environment: configDetails.Environment,
Extensions: model.Extensions,
}
err = Transform(dict, project)
if err != nil {
return nil, err
}

if len(includeRefs) != 0 {
Expand Down Expand Up @@ -557,6 +549,7 @@ func groupXFieldsIntoExtensions(dict map[string]interface{}) map[string]interfac
if strings.HasPrefix(key, "x-") {
extras[key] = value
delete(dict, key)
continue
}
switch v := value.(type) {
case map[string]interface{}:
Expand Down
41 changes: 11 additions & 30 deletions loader/merge_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -524,10 +524,10 @@ func TestLoadMultipleConfigobjsConfig(t *testing.T) {
},
expected: []types.ServiceConfigObjConfig{
{
Source: "bar_config",
Source: "foo_config",
},
{
Source: "foo_config",
Source: "bar_config",
},
},
},
Expand Down Expand Up @@ -556,15 +556,15 @@ func TestLoadMultipleConfigobjsConfig(t *testing.T) {
},
expected: []types.ServiceConfigObjConfig{
{
Source: "bar_config",
Target: "bof_config",
Source: "foo_config",
},
{
Source: "baz_config",
Target: "waw_config",
},
{
Source: "foo_config",
Source: "bar_config",
Target: "bof_config",
},
},
},
Expand Down Expand Up @@ -605,11 +605,6 @@ func TestLoadMultipleConfigobjsConfig(t *testing.T) {
Scale: 1,
},
},
Networks: types.Networks{},
Volumes: types.Volumes{},
Secrets: types.Secrets{},
Configs: types.Configs{},
Extensions: types.Extensions{},
}, config)
})
}
Expand Down Expand Up @@ -835,11 +830,6 @@ func TestLoadMultipleServiceNetworks(t *testing.T) {
Scale: 1,
},
},
Networks: types.Networks{},
Volumes: types.Volumes{},
Secrets: types.Secrets{},
Configs: types.Configs{},
Extensions: types.Extensions{},
}, config)
})
}
Expand Down Expand Up @@ -1096,22 +1086,13 @@ func TestMergeTopLevelExtensions(t *testing.T) {
}
config, err := loadTestProject(configDetails)
assert.NilError(t, err)
assert.DeepEqual(t, &types.Project{
Name: "",
WorkingDir: "",
Services: nil,
Networks: types.Networks{},
Volumes: types.Volumes{},
Secrets: types.Secrets{},
Configs: types.Configs{},
Extensions: types.Extensions{
"x-foo": "foo",
"x-bar": map[string]interface{}{
"base": "qix",
},
"x-zot": "zot",
assert.DeepEqual(t, types.Extensions{
"x-foo": "foo",
"x-bar": map[string]interface{}{
"base": "qix",
},
}, config)
"x-zot": "zot",
}, config.Extensions)
}

func TestMergeCommands(t *testing.T) {
Expand Down
49 changes: 18 additions & 31 deletions loader/paths_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,39 +47,26 @@ func TestResolveComposeFilePaths(t *testing.T) {
}

func TestResolveBuildContextPaths(t *testing.T) {
wd, _ := os.Getwd()
project := types.Project{
Name: "myProject",
WorkingDir: wd,
Services: []types.ServiceConfig{
{
Name: "foo",
Build: &types.BuildConfig{
Context: "./testdata",
Dockerfile: "Dockerfile-sample",
},
Scale: 1,
},
},
}

expected := types.Project{
Name: "myProject",
WorkingDir: wd,
Services: []types.ServiceConfig{
{
Name: "foo",
Build: &types.BuildConfig{
Context: filepath.Join(wd, "testdata"),
Dockerfile: "Dockerfile-sample",
},
Scale: 1,
},
},
}
err := ResolveRelativePaths(&project)
yaml := `
name: test-resolve-build-context-paths
services:
foo:
build:
context: ./testdata
dockerfile: Dockerfile-sample
`
project, err := loadYAML(yaml)
assert.NilError(t, err)
assert.DeepEqual(t, expected, project)

wd, err := os.Getwd()
assert.NilError(t, err)

expected := types.BuildConfig{
Context: filepath.Join(wd, "testdata"),
Dockerfile: "Dockerfile-sample",
}
assert.DeepEqual(t, expected, *project.Services[0].Build)
}

func TestResolveAdditionalContexts(t *testing.T) {
Expand Down
28 changes: 12 additions & 16 deletions override/merge.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package override

import (
"fmt"
"strings"

"github.com/compose-spec/compose-go/tree"
"golang.org/x/exp/slices"
Expand All @@ -44,6 +45,8 @@ func init() {
mergeSpecials["services.*.healthcheck.test"] = override
mergeSpecials["services.*.environment"] = mergeEnvironment
mergeSpecials["services.*.ulimits.*"] = mergeUlimit
mergeSpecials["services.*.configs.*"] = mergeMount
mergeSpecials["services.*.secrets.*"] = mergeMount
}

// mergeYaml merges map[string]any yaml trees handling special rules
Expand Down Expand Up @@ -77,14 +80,12 @@ func mergeYaml(e any, o any, p tree.Path) (any, error) {

func mergeMappings(mapping map[string]any, other map[string]any, p tree.Path) (map[string]any, error) {
for k, v := range other {
next := p.Next(k)
e, ok := mapping[k]
if !ok {
if !isEmpty(v) {
mapping[k] = v
}
if !ok || strings.HasPrefix(k, "x-") {
mapping[k] = v
continue
}
next := p.Next(k)
merged, err := mergeYaml(e, v, next)
if err != nil {
return nil, err
Expand All @@ -94,17 +95,6 @@ func mergeMappings(mapping map[string]any, other map[string]any, p tree.Path) (m
return mapping, nil
}

func isEmpty(value any) bool {
switch v := value.(type) {
case map[string]any:
return len(v) == 0
case []any:
return len(v) == 0
default:
return false
}
}

// logging driver options are merged only when both compose file define the same driver
func mergeLogging(c any, o any, p tree.Path) (any, error) {
config := c.(map[string]any)
Expand Down Expand Up @@ -133,6 +123,12 @@ func mergeUlimit(c any, o any, p tree.Path) (any, error) {
return o, nil
}

func mergeMount(c any, o any, path tree.Path) (any, error) {
right := convertIntoSequence(c)
left := convertIntoSequence(o)
return append(right, left...), nil
}

func convertIntoSequence(value any) []any {
switch v := value.(type) {
case map[string]any:
Expand Down
26 changes: 16 additions & 10 deletions override/uncity.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ func init() {
unique["services.*.environment"] = environmentIndexer
unique["services.*.volumes"] = volumeIndexer
unique["services.*.expose"] = exposeIndexer
unique["services.*.secrets"] = mountIndexer
unique["services.*.configs"] = mountIndexer
unique["services.*.secrets"] = mountIndexer("/run/secrets")
unique["services.*.configs"] = mountIndexer("")
}

// EnforceUnicity removes redefinition of elements declared in a sequence
Expand Down Expand Up @@ -120,13 +120,19 @@ func exposeIndexer(a any, path tree.Path) (string, error) {
}
}

func mountIndexer(a any, path tree.Path) (string, error) {
switch v := a.(type) {
case string:
return v, nil
case map[string]any:
return v["source"].(string), nil
default:
return "", fmt.Errorf("%s: unsupported expose value %s", path, a)
func mountIndexer(defaultPath string) indexer {
return func(a any, path tree.Path) (string, error) {
switch v := a.(type) {
case string:
return v, nil
case map[string]any:
t, ok := v["target"]
if ok {
return t.(string), nil
}
return fmt.Sprintf("%s/%s", defaultPath, v["source"]), nil
default:
return "", fmt.Errorf("%s: unsupported expose value %s", path, a)
}
}
}
2 changes: 1 addition & 1 deletion transform/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func makeServicesSlice(data any, p tree.Path) (any, error) {
servicesAsSlice[i] = canonical
i++
}
return servicesAsSlice, nil
return servicesAsSlice, nil //TODO(ndeloof) required for loading but not actually canonical. Shall we change compose-go types?
}

func transformServiceNetworks(data any, p tree.Path) (any, error) {
Expand Down

0 comments on commit af73475

Please sign in to comment.