Skip to content

Commit

Permalink
mange properly include.project_directory when including files
Browse files Browse the repository at this point in the history
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
  • Loading branch information
glours committed Apr 2, 2024
1 parent 00e000c commit 27a3a6a
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 6 deletions.
16 changes: 12 additions & 4 deletions loader/include.go
Expand Up @@ -29,7 +29,7 @@ import (
"github.com/compose-spec/compose-go/v2/types"
)

// loadIncludeConfig parse the require config from raw yaml
// loadIncludeConfig parse the required config from raw yaml
func loadIncludeConfig(source any) ([]types.IncludeConfig, error) {
if source == nil {
return nil, nil
Expand Down Expand Up @@ -76,11 +76,19 @@ func ApplyInclude(ctx context.Context, configDetails types.ConfigDetails, model
p = path

if i == 0 { // This is the "main" file, used to define project-directory. Others are overrides
relworkingdir = loader.Dir(path)
if r.ProjectDirectory == "" {

switch {
case r.ProjectDirectory == "":
relworkingdir = loader.Dir(path)
r.ProjectDirectory = filepath.Dir(path)
}
case !filepath.IsAbs(r.ProjectDirectory):
relworkingdir = loader.Dir(r.ProjectDirectory)
r.ProjectDirectory = filepath.Join(configDetails.WorkingDir, r.ProjectDirectory)

default:
relworkingdir = r.ProjectDirectory

}
for _, f := range included {
if f == path {
included = append(included, path)
Expand Down
62 changes: 62 additions & 0 deletions loader/include_test.go
Expand Up @@ -20,6 +20,7 @@ import (
"context"
"os"
"path/filepath"
"runtime"
"testing"

"github.com/compose-spec/compose-go/v2/types"
Expand Down Expand Up @@ -162,6 +163,67 @@ services:

}

func TestIncludeWithProjectDirectory(t *testing.T) {
var envs map[string]string
if runtime.GOOS == "windows" {
envs = map[string]string{"COMPOSE_CONVERT_WINDOWS_PATHS": "1"}
}
p, err := LoadWithContext(context.Background(), types.ConfigDetails{
WorkingDir: "testdata/include",
Environment: envs,
ConfigFiles: []types.ConfigFile{
{
Filename: "testdata/include/project-directory.yaml",
},
},
}, withProjectName("test-load-project-directory", true))
assert.NilError(t, err)
assert.Equal(t, filepath.ToSlash(p.Services["service"].Build.Context), "testdata/subdir")
assert.Equal(t, filepath.ToSlash(p.Services["service"].Volumes[0].Source), "testdata/subdir/compose-test-extends-imported.yaml")
assert.Equal(t, filepath.ToSlash(p.Services["service"].EnvFiles[0].Path), "testdata/subdir/extra.env")

}

func TestNestedIncludeAndExtends(t *testing.T) {
fileName := "compose.yml"
yaml := `
include:
- project_directory: .
path: dir/included.yaml
`
tmpdir := t.TempDir()
path := createFile(t, tmpdir, yaml, fileName)

yaml = `
services:
included:
extends:
file: dir/extended.yaml
service: extended
`
createFileSubDir(t, tmpdir, "dir", yaml, "included.yaml")

yaml = `
services:
extended:
image: alpine
`
createFile(t, filepath.Join(tmpdir, "dir"), yaml, "extended.yaml")
p, err := Load(types.ConfigDetails{
WorkingDir: tmpdir,
ConfigFiles: []types.ConfigFile{{
Filename: path,
}},
Environment: nil,
}, func(options *Options) {
options.SkipNormalization = true
options.ResolvePaths = true
options.SetProjectName("project", true)
})
assert.NilError(t, err)
assert.Equal(t, p.Services["included"].Image, "alpine")
}

func createFile(t *testing.T, rootDir, content, fileName string) string {
path := filepath.Join(rootDir, fileName)
assert.NilError(t, os.WriteFile(path, []byte(content), 0o600))
Expand Down
15 changes: 13 additions & 2 deletions loader/loader.go
Expand Up @@ -148,15 +148,26 @@ 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))
func (l localResourceLoader) Dir(originalPath string) string {
path := l.abs(originalPath)
if !l.isDir(path) {
path = l.abs(filepath.Dir(originalPath))
}
rel, err := filepath.Rel(l.WorkingDir, path)
if err != nil {
return path
}
return rel
}

func (l localResourceLoader) isDir(path string) bool {
fileInfo, err := os.Stat(path)
if err != nil {
return false
}
return fileInfo.IsDir()
}

func (o *Options) clone() *Options {
return &Options{
SkipValidation: o.SkipValidation,
Expand Down
12 changes: 12 additions & 0 deletions loader/testdata/include/dir/compose.yaml
@@ -0,0 +1,12 @@
services:
service:
build:
dockerfile_inline: |
FROM busybox
COPY compose-test-extends-imported.yaml compose.yaml
volumes:
- type: bind
source: compose-test-extends-imported.yaml
target: /mnt/bind/compose.yaml
env_file:
- extra.env
3 changes: 3 additions & 0 deletions loader/testdata/include/project-directory.yaml
@@ -0,0 +1,3 @@
include:
- project_directory: ../subdir
path: ./dir/compose.yaml

0 comments on commit 27a3a6a

Please sign in to comment.