diff --git a/tools/env-loader/cmd/env-loader.go b/tools/env-loader/cmd/env-loader.go index d9d39ae4..273cf332 100644 --- a/tools/env-loader/cmd/env-loader.go +++ b/tools/env-loader/cmd/env-loader.go @@ -32,7 +32,7 @@ const EnvVarPrefix = "ENV_LOADER_" type config struct { Environment string - ValueSet string + ValueSets []string Values []string Writer string } @@ -49,7 +49,7 @@ func parseCLI() *config { kingpin.Flag("value-set", "Name of the value set to load"). Short('s'). Envar(EnvVarPrefix + "VALUE_SET"). - StringVar(&c.ValueSet) + StringsVar(&c.ValueSets) kingpin.Flag("values", "Name of the specific value to output"). Short('v'). @@ -69,7 +69,7 @@ func parseCLI() *config { func run(c *config) error { // Load in values - envValues, err := envloader.LoadEnvironmentValues(c.Environment, c.ValueSet) + envValues, err := envloader.LoadEnvironmentValues(c.Environment, c.ValueSets) if err != nil { return trace.Wrap(err, "failed to load all environment values") } diff --git a/tools/env-loader/pkg/envloader.go b/tools/env-loader/pkg/envloader.go index 2c51a1dc..daff636b 100644 --- a/tools/env-loader/pkg/envloader.go +++ b/tools/env-loader/pkg/envloader.go @@ -114,28 +114,37 @@ func findCommonFilesInPath(basePath, relativeSubdirectoryPath string) ([]string, // Finds environment value files for the given environment and value set, under the given directory. // File names will be returned in order of priority, with the lowest priority names first. // If the environment name includes '/', it is split and each component is searched for common files. -func FindEnvironmentFilesInDirectory(environmentsDirectoryPath, environmentName, valueSet string) ([]string, error) { - commonFilePaths, err := findCommonFilesInPath(environmentsDirectoryPath, environmentName) +func FindEnvironmentFilesInDirectory(environmentsDirectoryPath, environmentName string, valueSets []string) ([]string, error) { + filePaths, err := findCommonFilesInPath(environmentsDirectoryPath, environmentName) if err != nil { return nil, trace.Wrap(err, "failed to find all common files for environment %q", environmentName) } - if valueSet == "" { - return commonFilePaths, nil + if len(valueSets) == 0 { + return filePaths, nil } - valueSetFilePaths, err := filepath.Glob(filepath.Join(environmentsDirectoryPath, environmentName, valueSet+".*")) - if err != nil { - return nil, trace.Wrap(err, "failed to find %q value files", valueSet) + for _, valueSet := range valueSets { + globPath := filepath.Join(environmentsDirectoryPath, environmentName, valueSet+".*") + valueSetFilePaths, err := filepath.Glob(globPath) + if err != nil { + return nil, trace.Wrap(err, "failed to find %q value files", valueSet) + } + + if len(valueSetFilePaths) == 0 { + return nil, trace.Errorf("failed to find any value files for %q matching %q", valueSet, globPath) + } + + filePaths = append(filePaths, valueSetFilePaths...) } - return append(commonFilePaths, valueSetFilePaths...), nil + return filePaths, nil } // Finds environment value files for the given environment and value set, under the "environments" // directory in the repo root. File names will be returned in order of priority, with the lowest // priority names first. -func FindEnvironmentFiles(environment, valueSet string) ([]string, error) { +func FindEnvironmentFiles(environment string, valueSets []string) ([]string, error) { repoRoot, err := findGitRepoRoot() if err != nil { return nil, trace.Wrap(err, "failed to find repo root") @@ -146,7 +155,7 @@ func FindEnvironmentFiles(environment, valueSet string) ([]string, error) { return nil, trace.Wrap(err, "failed to find environments path at %q", environmentsPath) } - return FindEnvironmentFilesInDirectory(environmentsPath, environment, valueSet) + return FindEnvironmentFilesInDirectory(environmentsPath, environment, valueSets) } func loadEnvironmentValuesFromPaths(valueFilePaths []string, err error) (map[string]string, error) { @@ -176,14 +185,14 @@ func loadEnvironmentValuesFromPaths(valueFilePaths []string, err error) (map[str // Finds environment value files for the given environment and value set, under the "environments" // directory in the repo root, and loads them. Lower priority files (common files) will have values -// replaced by values from higher priority files (value set files). -func LoadEnvironmentValues(environment, valueSet string) (map[string]string, error) { - return loadEnvironmentValuesFromPaths(FindEnvironmentFiles(environment, valueSet)) +// replaced by values from higher priority files (value set files, last provided being highest priority). +func LoadEnvironmentValues(environment string, valueSets []string) (map[string]string, error) { + return loadEnvironmentValuesFromPaths(FindEnvironmentFiles(environment, valueSets)) } // Finds environment value files for the given environment and value set, under the given directory, // and loads them. Lower priority files (common files) will have values replaced by values from higher -// priority files (value set files). -func LoadEnvironmentValuesInDirectory(directory, environment, valueSet string) (map[string]string, error) { - return loadEnvironmentValuesFromPaths(FindEnvironmentFilesInDirectory(directory, environment, valueSet)) +// priority files (value set files, last provided being highest priority). +func LoadEnvironmentValuesInDirectory(directory, environment string, valueSets []string) (map[string]string, error) { + return loadEnvironmentValuesFromPaths(FindEnvironmentFilesInDirectory(directory, environment, valueSets)) } diff --git a/tools/env-loader/pkg/envloader_test.go b/tools/env-loader/pkg/envloader_test.go index 45a55990..30fce614 100644 --- a/tools/env-loader/pkg/envloader_test.go +++ b/tools/env-loader/pkg/envloader_test.go @@ -130,14 +130,15 @@ func TestFindEnvironmentFilesInDirectory(t *testing.T) { desc string // This will be prepended by the environments directory path (abs) environmentName string - valueSet string + valueSets []string // This will be prepended by the environments directory path (abs) expectedFileNames []string + checkError require.ErrorAssertionFunc }{ { desc: "only common file", environmentName: "", - valueSet: "", + valueSets: nil, expectedFileNames: []string{ "common.abc", }, @@ -145,7 +146,7 @@ func TestFindEnvironmentFilesInDirectory(t *testing.T) { { desc: "only environment common file", environmentName: "env2", - valueSet: "", + valueSets: nil, expectedFileNames: []string{ "common.abc", filepath.Join("env2", "common.abc"), @@ -154,16 +155,22 @@ func TestFindEnvironmentFilesInDirectory(t *testing.T) { { desc: "single file", environmentName: "env1", - valueSet: "testing", + valueSets: []string{"testing"}, expectedFileNames: []string{ "common.abc", filepath.Join("env1", "testing.abc"), }, }, + { + desc: "missing file", + environmentName: "env1", + valueSets: []string{"non existent set"}, + checkError: require.Error, + }, { desc: "multiple value sets in path", environmentName: "env2", - valueSet: "testing1", + valueSets: []string{"testing1"}, expectedFileNames: []string{ "common.abc", filepath.Join("env2", "common.abc"), @@ -173,7 +180,7 @@ func TestFindEnvironmentFilesInDirectory(t *testing.T) { { desc: "multiple files for value set", environmentName: "env2", - valueSet: "testing2", + valueSets: []string{"testing2"}, expectedFileNames: []string{ "common.abc", filepath.Join("env2", "common.abc"), @@ -184,7 +191,7 @@ func TestFindEnvironmentFilesInDirectory(t *testing.T) { { desc: "multiple file extensions", environmentName: "env2", - valueSet: "testing3", + valueSets: []string{"testing3"}, expectedFileNames: []string{ "common.abc", filepath.Join("env2", "common.abc"), @@ -192,18 +199,27 @@ func TestFindEnvironmentFilesInDirectory(t *testing.T) { }, }, { - desc: "no file extension", + desc: "multiple value sets", environmentName: "env2", - valueSet: "testing4", + valueSets: []string{"testing2", "testing3"}, expectedFileNames: []string{ "common.abc", filepath.Join("env2", "common.abc"), + filepath.Join("env2", "testing2.abc"), + filepath.Join("env2", "testing2.def"), + filepath.Join("env2", "testing3.abc.def"), }, }, + { + desc: "no file extension", + environmentName: "env2", + valueSets: []string{"testing4"}, + checkError: require.Error, + }, { desc: "common file exists", environmentName: "env3", - valueSet: "testing", + valueSets: []string{"testing"}, expectedFileNames: []string{ "common.abc", filepath.Join("env3", "common.abc"), @@ -219,8 +235,12 @@ func TestFindEnvironmentFilesInDirectory(t *testing.T) { testCase.expectedFileNames[i] = filepath.Join(environmentsDirPath, expectedFileName) } - actualFileNames, err := FindEnvironmentFilesInDirectory(environmentsDirPath, testCase.environmentName, testCase.valueSet) - require.NoError(t, err, testCase.desc) + if testCase.checkError == nil { + testCase.checkError = require.NoError + } + + actualFileNames, err := FindEnvironmentFilesInDirectory(environmentsDirPath, testCase.environmentName, testCase.valueSets) + testCase.checkError(t, err, testCase.desc) require.Equal(t, testCase.expectedFileNames, actualFileNames, testCase.desc) } } @@ -231,20 +251,20 @@ func TestFindEnvironmentFiles(t *testing.T) { // This will be prepended by the testdata directory path (abs) workingDir string environmentName string - valueSet string + valueSets []string // This will be prepended by the testdata directory path (abs) expectedFileNames []string }{ { desc: "in repo", workingDir: filepath.Join("repos", "basic repo", "subdirectory 1", "subdirectory 2"), - environmentName: "env1", - valueSet: "testing1", + environmentName: "env2", + valueSets: []string{"testing2", "testing1"}, expectedFileNames: []string{ // Order is important here filepath.Join("repos", "basic repo", ".environments", "common.def"), - filepath.Join("repos", "basic repo", ".environments", "env1", "common.abc"), - filepath.Join("repos", "basic repo", ".environments", "env1", "testing1.abc"), + filepath.Join("repos", "basic repo", ".environments", "env2", "testing2.abc"), + filepath.Join("repos", "basic repo", ".environments", "env2", "testing1.abc"), }, }, } @@ -265,7 +285,7 @@ func TestFindEnvironmentFiles(t *testing.T) { require.NoError(t, err, "unable to get change to test working directory") // Run the tests - actualFileNames, err := FindEnvironmentFiles(testCase.environmentName, testCase.valueSet) + actualFileNames, err := FindEnvironmentFiles(testCase.environmentName, testCase.valueSets) require.NoError(t, err, testCase.desc) require.Equal(t, testCase.expectedFileNames, actualFileNames, testCase.desc) @@ -281,19 +301,20 @@ func TestLoadEnvironmentValues(t *testing.T) { // This will be prepended by the testdata directory path (abs) workingDir string environmentName string - valueSet string + valueSets []string expectedValues map[string]string }{ { desc: "lower priority values are overwritten", workingDir: filepath.Join("repos", "basic repo", "subdirectory 1"), environmentName: "env1", - valueSet: "testing1", + valueSets: []string{"testing2", "testing1"}, expectedValues: map[string]string{ "topLevelCommon1": "top level", "topLevelCommon2": "env level", "envLevelCommon1": "env level", "envLevelCommon2": "set level", + "setLevelCommon": "testing1 level", "setLevel": "set level", }, }, @@ -311,7 +332,7 @@ func TestLoadEnvironmentValues(t *testing.T) { require.NoError(t, err, "unable to get change to test working directory") // Run the tests - actualValues, err := LoadEnvironmentValues(testCase.environmentName, testCase.valueSet) + actualValues, err := LoadEnvironmentValues(testCase.environmentName, testCase.valueSets) require.NoError(t, err, testCase.desc) require.Equal(t, testCase.expectedValues, actualValues, testCase.desc) diff --git a/tools/env-loader/pkg/testdata/repos/basic repo/.environments/env1/testing1.abc b/tools/env-loader/pkg/testdata/repos/basic repo/.environments/env1/testing1.abc index b49808fb..52572650 100644 --- a/tools/env-loader/pkg/testdata/repos/basic repo/.environments/env1/testing1.abc +++ b/tools/env-loader/pkg/testdata/repos/basic repo/.environments/env1/testing1.abc @@ -1,3 +1,4 @@ --- envLevelCommon2: set level +setLevelCommon: testing1 level setLevel: set level diff --git a/tools/env-loader/pkg/testdata/repos/basic repo/.environments/env1/testing2.abc b/tools/env-loader/pkg/testdata/repos/basic repo/.environments/env1/testing2.abc index e69de29b..4aad82cd 100644 --- a/tools/env-loader/pkg/testdata/repos/basic repo/.environments/env1/testing2.abc +++ b/tools/env-loader/pkg/testdata/repos/basic repo/.environments/env1/testing2.abc @@ -0,0 +1,2 @@ +--- +setLevelCommon: testing2 level diff --git a/tools/env-loader/pkg/testdata/repos/basic repo/.environments/env2/testing2.abc b/tools/env-loader/pkg/testdata/repos/basic repo/.environments/env2/testing2.abc new file mode 100644 index 00000000..e69de29b