Skip to content

Commit

Permalink
Revert "run interpolation after merge, but for required attributes"
Browse files Browse the repository at this point in the history
Signed-off-by: Suleiman Dibirov <[email protected]>
  • Loading branch information
idsulik authored and ndeloof committed Jul 23, 2024
1 parent cf5a3d4 commit bfaf10b
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 106 deletions.
2 changes: 1 addition & 1 deletion cli/options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ func TestProjectWithDotEnv(t *testing.T) {
"compose-with-variables.yaml",
}, WithName("my_project"), WithEnvFiles(), WithDotEnv)
assert.NilError(t, err)
p, err := opts.LoadProject(context.TODO())
p, err := ProjectFromOptions(context.TODO(), opts)
assert.NilError(t, err)
service, err := p.GetService("simple")
assert.NilError(t, err)
Expand Down
1 change: 1 addition & 0 deletions cli/testdata/env-file/compose-with-env-files.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
version: "3"
services:
simple:
image: nginx
Expand Down
21 changes: 0 additions & 21 deletions loader/extends.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,8 @@ import (
"path/filepath"

"github.com/compose-spec/compose-go/v2/consts"
"github.com/compose-spec/compose-go/v2/interpolation"
"github.com/compose-spec/compose-go/v2/override"
"github.com/compose-spec/compose-go/v2/paths"
"github.com/compose-spec/compose-go/v2/template"
"github.com/compose-spec/compose-go/v2/transform"
"github.com/compose-spec/compose-go/v2/types"
)

Expand Down Expand Up @@ -71,22 +68,10 @@ func applyServiceExtends(ctx context.Context, name string, services map[string]a
)
switch v := extends.(type) {
case map[string]any:
if opts.Interpolate != nil {
v, err = interpolation.Interpolate(v, *opts.Interpolate)
if err != nil {
return nil, err
}
}
ref = v["service"].(string)
file = v["file"]
opts.ProcessEvent("extends", v)
case string:
if opts.Interpolate != nil {
v, err = opts.Interpolate.Substitute(v, template.Mapping(opts.Interpolate.LookupValue))
if err != nil {
return nil, err
}
}
ref = v
opts.ProcessEvent("extends", map[string]any{"service": ref})
}
Expand Down Expand Up @@ -190,12 +175,6 @@ func getExtendsBaseFromFile(
)
}

// Attempt to make a canonical model so ResolveRelativePaths can operate on source:target short syntax
source, err = transform.Canonical(source, true)
if err != nil {
return nil, nil, err
}

var remotes []paths.RemoteResource
for _, loader := range opts.RemoteResourceLoaders() {
remotes = append(remotes, loader.Accept)
Expand Down
14 changes: 2 additions & 12 deletions loader/include.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import (
)

// loadIncludeConfig parse the required config from raw yaml
func loadIncludeConfig(source any, options *Options) ([]types.IncludeConfig, error) {
func loadIncludeConfig(source any) ([]types.IncludeConfig, error) {
if source == nil {
return nil, nil
}
Expand All @@ -45,23 +45,13 @@ func loadIncludeConfig(source any, options *Options) ([]types.IncludeConfig, err
}
}
}
if options.Interpolate != nil {
for i, config := range configs {
interpolated, err := interp.Interpolate(config.(map[string]any), *options.Interpolate)
if err != nil {
return nil, err
}
configs[i] = interpolated
}
}

var requires []types.IncludeConfig
err := Transform(source, &requires)
return requires, err
}

func ApplyInclude(ctx context.Context, workingDir string, environment types.Mapping, model map[string]any, options *Options, included []string) error {
includeConfig, err := loadIncludeConfig(model["include"], options)
includeConfig, err := loadIncludeConfig(model["include"])
if err != nil {
return err
}
Expand Down
39 changes: 21 additions & 18 deletions loader/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -367,23 +367,6 @@ func loadYamlModel(ctx context.Context, config types.ConfigDetails, opts *Option
}
}

if opts.Interpolate != nil && !opts.SkipInterpolation {
dict, err = interp.Interpolate(dict, *opts.Interpolate)
if err != nil {
return nil, err
}
}

dict, err = transform.Canonical(dict, opts.SkipInterpolation)
if err != nil {
return nil, err
}

dict, err = override.EnforceUnicity(dict)
if err != nil {
return nil, err
}

if !opts.SkipDefaultValues {
dict, err = transform.SetDefaultValues(dict)
if err != nil {
Expand Down Expand Up @@ -432,6 +415,13 @@ func loadYamlFile(ctx context.Context, file types.ConfigFile, opts *Options, wor
return errors.New("Top-level object must be a mapping")
}

if opts.Interpolate != nil && !opts.SkipInterpolation {
cfg, err = interp.Interpolate(cfg, *opts.Interpolate)
if err != nil {
return err
}
}

fixEmptyNotNull(cfg)

if !opts.SkipExtends {
Expand Down Expand Up @@ -460,6 +450,11 @@ func loadYamlFile(ctx context.Context, file types.ConfigFile, opts *Options, wor
return err
}

dict, err = override.EnforceUnicity(dict)
if err != nil {
return err
}

if !opts.SkipValidation {
if err := schema.Validate(dict); err != nil {
return fmt.Errorf("validating %s: %w", file.Filename, err)
Expand All @@ -469,7 +464,15 @@ func loadYamlFile(ctx context.Context, file types.ConfigFile, opts *Options, wor
delete(dict, "version")
}
}
return nil

dict, err = transform.Canonical(dict, opts.SkipInterpolation)
if err != nil {
return err
}

// Canonical transformation can reveal duplicates, typically as ports can be a range and conflict with an override
dict, err = override.EnforceUnicity(dict)
return err
}

var processor PostProcessor
Expand Down
40 changes: 0 additions & 40 deletions loader/loader_yaml_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,46 +56,6 @@ services:
})
}

func TestParseYAMLFilesInterpolateAfterMerge(t *testing.T) {
model, err := loadYamlModel(
context.TODO(), types.ConfigDetails{
ConfigFiles: []types.ConfigFile{
{
Filename: "test.yaml",
Content: []byte(`
services:
test:
image: foo
environment:
my_env: ${my_env?my_env must be set}
`),
},
{
Filename: "override.yaml",
Content: []byte(`
services:
test:
image: bar
environment:
my_env: ${my_env:-default}
`),
},
},
}, &Options{}, &cycleTracker{}, nil,
)
assert.NilError(t, err)
assert.DeepEqual(
t, model, map[string]interface{}{
"services": map[string]interface{}{
"test": map[string]interface{}{
"image": "bar",
"environment": []any{"my_env=${my_env:-default}"},
},
},
},
)
}

func TestParseYAMLFilesMergeOverride(t *testing.T) {
model, err := loadYamlModel(context.TODO(), types.ConfigDetails{
ConfigFiles: []types.ConfigFile{
Expand Down
34 changes: 20 additions & 14 deletions schema/compose-spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,8 @@
},
"additionalProperties": false
},
"cap_add": {"type": "array", "items": {"type": "string"}},
"cap_drop": {"type": "array", "items": {"type": "string"}},
"cap_add": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"cap_drop": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"cgroup": {"type": "string", "enum": ["host", "private"]},
"cgroup_parent": {"type": "string"},
"command": {"$ref": "#/definitions/command"},
Expand Down Expand Up @@ -216,9 +216,9 @@
]
},
"device_cgroup_rules": {"$ref": "#/definitions/list_of_strings"},
"devices": {"type": "array", "items": {"type": "string"}},
"devices": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"dns": {"$ref": "#/definitions/string_or_list"},
"dns_opt": {"type": "array","items": {"type": "string"}},
"dns_opt": {"type": "array","items": {"type": "string"}, "uniqueItems": true},
"dns_search": {"$ref": "#/definitions/string_or_list"},
"domainname": {"type": "string"},
"entrypoint": {"$ref": "#/definitions/command"},
Expand All @@ -230,7 +230,8 @@
"items": {
"type": ["string", "number"],
"format": "expose"
}
},
"uniqueItems": true
},
"extends": {
"oneOf": [
Expand All @@ -247,13 +248,14 @@
}
]
},
"external_links": {"type": "array", "items": {"type": "string"}},
"external_links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"extra_hosts": {"$ref": "#/definitions/list_or_dict"},
"group_add": {
"type": "array",
"items": {
"type": ["string", "number"]
}
},
"uniqueItems": true
},
"healthcheck": {"$ref": "#/definitions/healthcheck"},
"hostname": {"type": "string"},
Expand All @@ -262,7 +264,7 @@
"ipc": {"type": "string"},
"isolation": {"type": "string"},
"labels": {"$ref": "#/definitions/list_or_dict"},
"links": {"type": "array", "items": {"type": "string"}},
"links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"logging": {
"type": "object",

Expand Down Expand Up @@ -348,7 +350,8 @@
"patternProperties": {"^x-": {}}
}
]
}
},
"uniqueItems": true
},
"privileged": {"type": ["boolean", "string"]},
"profiles": {"$ref": "#/definitions/list_of_strings"},
Expand All @@ -363,7 +366,7 @@
"scale": {
"type": ["integer", "string"]
},
"security_opt": {"type": "array", "items": {"type": "string"}},
"security_opt": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"shm_size": {"type": ["number", "string"]},
"secrets": {"$ref": "#/definitions/service_config_or_secret"},
"sysctls": {"$ref": "#/definitions/list_or_dict"},
Expand Down Expand Up @@ -429,11 +432,13 @@
"patternProperties": {"^x-": {}}
}
]
}
},
"uniqueItems": true
},
"volumes_from": {
"type": "array",
"items": {"type": "string"}
"items": {"type": "string"},
"uniqueItems": true
},
"working_dir": {"type": "string"}
},
Expand Down Expand Up @@ -828,7 +833,8 @@

"list_of_strings": {
"type": "array",
"items": {"type": "string"}
"items": {"type": "string"},
"uniqueItems": true
},

"list_or_dict": {
Expand All @@ -842,7 +848,7 @@
},
"additionalProperties": false
},
{"type": "array", "items": {"type": "string"}}
{"type": "array", "items": {"type": "string"}, "uniqueItems": true}
]
},

Expand Down

0 comments on commit bfaf10b

Please sign in to comment.