diff --git a/cli/options.go b/cli/options.go index 091a2aae..e16432d3 100644 --- a/cli/options.go +++ b/cli/options.go @@ -21,6 +21,7 @@ import ( "io" "os" "path/filepath" + "slices" "strconv" "strings" @@ -403,14 +404,13 @@ func (o *ProjectOptions) GetWorkingDir() (string, error) { } // ReadConfigFiles reads ConfigFiles and populates the content field -func (o *ProjectOptions) ReadConfigFiles(ctx context.Context, workingDir string, options *ProjectOptions) (*types.ConfigDetails, error) { - config, err := loader.LoadConfigFiles(ctx, options.ConfigPaths, workingDir, options.loadOptions...) +func (o *ProjectOptions) ReadConfigFiles(ctx context.Context, workingDir string) (*types.ConfigDetails, error) { + config, err := loader.LoadConfigFiles(ctx, o.ConfigPaths, workingDir, o.loadOptions...) if err != nil { return nil, err } - configs := make([][]byte, len(config.ConfigFiles)) - - for i, c := range config.ConfigFiles { + configs := make([]types.ConfigFile, 0, len(config.ConfigFiles)) + for _, c := range config.ConfigFiles { var err error var b []byte if c.IsStdin() { @@ -418,21 +418,44 @@ func (o *ProjectOptions) ReadConfigFiles(ctx context.Context, workingDir string, if err != nil { return nil, err } + + configs = append(configs, types.ConfigFile{ + Filename: "-", + Content: b, + Config: nil, + }) } else { f, err := filepath.Abs(c.Filename) if err != nil { return nil, err } - b, err = os.ReadFile(f) + + if stat, err := os.Stat(f); err == nil && stat.IsDir() { + f = filepath.Join(f, "*.yaml") + } + + matches, err := filepath.Glob(f) if err != nil { return nil, err } + + slices.Sort(matches) + + for _, match := range matches { + b, err = os.ReadFile(match) + if err != nil { + return nil, err + } + + configs = append(configs, types.ConfigFile{ + Filename: match, + Content: b, + Config: nil, + }) + } } - configs[i] = b - } - for i, c := range configs { - config.ConfigFiles[i].Content = c } + config.ConfigFiles = configs return config, nil } @@ -476,7 +499,7 @@ func (o *ProjectOptions) prepare(ctx context.Context) (*types.ConfigDetails, err return &types.ConfigDetails{}, err } - configDetails, err := o.ReadConfigFiles(ctx, defaultDir, o) + configDetails, err := o.ReadConfigFiles(ctx, defaultDir) if err != nil { return configDetails, err } diff --git a/cli/options_test.go b/cli/options_test.go index 9f03587d..b28fa4d2 100644 --- a/cli/options_test.go +++ b/cli/options_test.go @@ -384,3 +384,49 @@ func TestEnvVariablePrecedence(t *testing.T) { }) } } + +func TestWildcards(t *testing.T) { + options, err := NewProjectOptions([]string{"testdata/wildcards/compose-*.yaml"}) + assert.NilError(t, err) + files, err := options.ReadConfigFiles(context.TODO(), ".") + assert.NilError(t, err) + + abs, err := filepath.Abs("testdata/wildcards") + assert.NilError(t, err) + assert.DeepEqual(t, files, &types.ConfigDetails{ + WorkingDir: ".", + ConfigFiles: []types.ConfigFile{ + { + Filename: filepath.Join(abs, "compose-A.yaml"), + Content: []byte{}, + }, + { + Filename: filepath.Join(abs, "compose-B.yaml"), + Content: []byte{}, + }, + }, + }) +} + +func TestFolder(t *testing.T) { + options, err := NewProjectOptions([]string{"testdata/wildcards/"}) + assert.NilError(t, err) + files, err := options.ReadConfigFiles(context.TODO(), ".") + assert.NilError(t, err) + + abs, err := filepath.Abs("testdata/wildcards") + assert.NilError(t, err) + assert.DeepEqual(t, files, &types.ConfigDetails{ + WorkingDir: ".", + ConfigFiles: []types.ConfigFile{ + { + Filename: filepath.Join(abs, "compose-A.yaml"), + Content: []byte{}, + }, + { + Filename: filepath.Join(abs, "compose-B.yaml"), + Content: []byte{}, + }, + }, + }) +} diff --git a/cli/testdata/wildcards/compose-A.yaml b/cli/testdata/wildcards/compose-A.yaml new file mode 100644 index 00000000..e69de29b diff --git a/cli/testdata/wildcards/compose-B.yaml b/cli/testdata/wildcards/compose-B.yaml new file mode 100644 index 00000000..e69de29b