Skip to content

Commit

Permalink
re-implemented ResetProcessor to apply on map[string]any
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 10, 2023
1 parent 963c38b commit 00f65e8
Show file tree
Hide file tree
Showing 26 changed files with 723 additions and 232 deletions.
77 changes: 45 additions & 32 deletions loader/extends.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,59 +19,72 @@ package loader
import (
"context"
"fmt"
"path/filepath"

"github.com/compose-spec/compose-go/override"
"github.com/compose-spec/compose-go/types"
)

func ApplyExtends(ctx context.Context, dict map[string]interface{}, opts *Options) error {
services := dict["services"].(map[string]interface{})
func ApplyExtends(ctx context.Context, dict map[string]any, opts *Options, post ...PostProcessor) error {
services := dict["services"].(map[string]any)
for name, s := range services {
service := s.(map[string]interface{})
service := s.(map[string]any)
x, ok := service["extends"]
if !ok {
continue
}
extends := x.(map[string]interface{})
var base interface{}
extends := x.(map[string]any)
var base any
ref := extends["service"].(string)
if file, ok := extends["file"]; ok {
path := file.(string)
for _, loader := range opts.ResourceLoaders {
if loader.Accept(path) {
local, err := loader.Load(ctx, path)
if err != nil {
return err
}
source, err := loadYamlModel(ctx, []types.ConfigFile{
if !loader.Accept(path) {
continue
}
local, err := loader.Load(ctx, path)
if err != nil {
return err
}
source, err := loadYamlModel(ctx, types.ConfigDetails{
WorkingDir: filepath.Dir(path),
ConfigFiles: []types.ConfigFile{
{Filename: local},
}, opts)
if err != nil {
return err
}
services := source["services"].([]interface{})
for _, s := range services {
service := s.(map[string]interface{})
if service["name"] == ref {
base = service
break
}
}
if base == nil {
return fmt.Errorf("cannot extend service %q in %s: service not found", name, path)
},
}, opts)
if err != nil {
return err
}
services := source["services"].([]any)
for _, s := range services {
service := s.(map[string]any)
if service["name"] == ref {
base = service
break
}
}
if base == nil {
return fmt.Errorf("cannot extend service %q in %s: service not found", name, path)
}
}
if base == nil {
return fmt.Errorf("cannot read %s", path)
}
} else {
base, ok = services[ref]
if !ok {
return fmt.Errorf("cannot extend service %q in %s: service not found", name, "filename") //TODO track filename
return fmt.Errorf("cannot extend service %q in %s: service not found", name, "filename") // TODO track filename
}
}
merged, err := override.ExtendService(deepClone(base).(map[string]interface{}), service)
source := deepClone(base).(map[string]any)
for _, processor := range post {
processor.Apply(map[string]any{
"services": map[string]any{
name: source,
},
})
}
merged, err := override.ExtendService(source, service)
if err != nil {
return err
}
Expand All @@ -81,16 +94,16 @@ func ApplyExtends(ctx context.Context, dict map[string]interface{}, opts *Option
return nil
}

func deepClone(value interface{}) interface{} {
func deepClone(value any) any {
switch v := value.(type) {
case []interface{}:
cp := make([]interface{}, len(v))
case []any:
cp := make([]any, len(v))
for i, e := range v {
cp[i] = deepClone(e)
}
return cp
case map[string]interface{}:
cp := make(map[string]interface{}, len(v))
case map[string]any:
cp := make(map[string]any, len(v))
for k, e := range v {
cp[k] = deepClone(e)
}
Expand Down
36 changes: 36 additions & 0 deletions loader/fix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
Copyright 2020 The Compose Specification Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package loader

// fixEmptyNotNull is a workaround for https://github.com/xeipuuv/gojsonschema/issues/141
// as go-yaml `[]` will load as a `[]any(nil)`, which is not the same as an empty array
func fixEmptyNotNull(value any) interface{} {
switch v := value.(type) {
case []any:
if v == nil {
return []any{}
}
for i, e := range v {
v[i] = fixEmptyNotNull(e)
}
case map[string]any:
for k, e := range v {
v[k] = fixEmptyNotNull(e)
}
}
return value
}
Loading

0 comments on commit 00f65e8

Please sign in to comment.