Skip to content

Commit

Permalink
let resource loader compute a (possibly) relative path
Browse files Browse the repository at this point in the history
Signed-off-by: Nicolas De Loof <[email protected]>
  • Loading branch information
ndeloof authored and glours committed Jan 22, 2024
1 parent 466ad84 commit 0e8d665
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 11 deletions.
17 changes: 9 additions & 8 deletions loader/extends.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import (
"github.com/compose-spec/compose-go/v2/types"
)

func ApplyExtends(ctx context.Context, dict map[string]any, workingdir string, opts *Options, tracker *cycleTracker, post ...PostProcessor) error {
func ApplyExtends(ctx context.Context, dict map[string]any, opts *Options, tracker *cycleTracker, post ...PostProcessor) error {
a, ok := dict["services"]
if !ok {
return nil
Expand Down Expand Up @@ -71,14 +71,15 @@ func ApplyExtends(ctx context.Context, dict map[string]any, workingdir string, o
if err != nil {
return err
}
relworkingdir := filepath.Dir(local)
if !filepath.IsAbs(local) {
relworkingdir, err = filepath.Rel(workingdir, relworkingdir)
if err != nil {
return err
}
}
localdir := filepath.Dir(local)
relworkingdir := loader.Dir(path)

extendsOpts := opts.clone()
extendsOpts.ResourceLoaders = append([]ResourceLoader{}, opts.ResourceLoaders...)
// replace localResourceLoader with a new flavour, using extended file base path
extendsOpts.ResourceLoaders[len(opts.ResourceLoaders)-1] = localResourceLoader{
WorkingDir: localdir,
}
extendsOpts.ResolvePaths = true
extendsOpts.SkipNormalization = true
extendsOpts.SkipConsistencyCheck = true
Expand Down
27 changes: 27 additions & 0 deletions loader/extends_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,30 @@ services:
assert.NilError(t, err)
assert.Equal(t, p.Services["test"].Ulimits["nproc"].Single, 65535)
}

func TestExtendsRelativePath(t *testing.T) {
yaml := `
name: test-extends-port
services:
test:
extends:
file: testdata/extends/base.yaml
service: with-build
`
abs, err := filepath.Abs(".")
assert.NilError(t, err)

p, err := LoadWithContext(context.Background(), types.ConfigDetails{
ConfigFiles: []types.ConfigFile{
{
Content: []byte(yaml),
Filename: "(inline)",
},
},
WorkingDir: abs,
}, func(options *Options) {
options.ResolvePaths = false
})
assert.NilError(t, err)
assert.Equal(t, p.Services["test"].Build.Context, filepath.Join("testdata", "extends"))
}
13 changes: 12 additions & 1 deletion loader/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ type ResourceLoader interface {
Accept(path string) bool
// Load returns the path to a local copy of remote resource identified by `path`.
Load(ctx context.Context, path string) (string, error)
// Dir computes path to resource"s parent folder, made relative if possible
Dir(path string) string
}

type localResourceLoader struct {
Expand All @@ -105,6 +107,15 @@ func (l localResourceLoader) Load(_ context.Context, p string) (string, error) {
return l.abs(p), nil
}

func (l localResourceLoader) Dir(path string) string {
path = l.abs(filepath.Dir(path))
rel, err := filepath.Rel(l.WorkingDir, path)
if err != nil {
return path
}
return rel
}

func (o *Options) clone() *Options {
return &Options{
SkipValidation: o.SkipValidation,
Expand Down Expand Up @@ -313,7 +324,7 @@ func loadYamlModel(ctx context.Context, config types.ConfigDetails, opts *Option
fixEmptyNotNull(cfg)

if !opts.SkipExtends {
err = ApplyExtends(fctx, cfg, config.WorkingDir, opts, ct, processors...)
err = ApplyExtends(fctx, cfg, opts, ct, processors...)
if err != nil {
return err
}
Expand Down
10 changes: 9 additions & 1 deletion loader/loader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2636,15 +2636,23 @@ func (c customLoader) Accept(s string) bool {
return strings.HasPrefix(s, c.prefix+":")
}

func (c customLoader) path(s string) string {
return filepath.Join("testdata", c.prefix, s[len(c.prefix)+1:])
}

func (c customLoader) Load(_ context.Context, s string) (string, error) {
path := filepath.Join("testdata", c.prefix, s[len(c.prefix)+1:])
path := c.path(s)
_, err := os.Stat(path)
if err != nil {
return "", err
}
return filepath.Abs(path)
}

func (c customLoader) Dir(s string) string {
return filepath.Dir(c.path(s))
}

func TestLoadWithRemoteResources(t *testing.T) {
config := buildConfigDetails(`
name: test-remote-resources
Expand Down
7 changes: 6 additions & 1 deletion loader/testdata/extends/base.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,9 @@ services:
nofile:
soft: 20000
hard: 40000


with-build:
extends:
file: sibling.yaml
service: test

3 changes: 3 additions & 0 deletions loader/testdata/extends/sibling.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
services:
test:
build: .

0 comments on commit 0e8d665

Please sign in to comment.