Skip to content

Commit

Permalink
Added support for loading multiple value sets
Browse files Browse the repository at this point in the history
  • Loading branch information
fheinecke committed Nov 4, 2024
1 parent ff09e6b commit 0966323
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 40 deletions.
6 changes: 3 additions & 3 deletions tools/env-loader/cmd/env-loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const EnvVarPrefix = "ENV_LOADER_"

type config struct {
Environment string
ValueSet string
ValueSets []string
Values []string
Writer string
}
Expand All @@ -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').
Expand All @@ -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")
}
Expand Down
41 changes: 25 additions & 16 deletions tools/env-loader/pkg/envloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -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) {
Expand Down Expand Up @@ -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))
}
63 changes: 42 additions & 21 deletions tools/env-loader/pkg/envloader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,22 +130,23 @@ 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",
},
},
{
desc: "only environment common file",
environmentName: "env2",
valueSet: "",
valueSets: nil,
expectedFileNames: []string{
"common.abc",
filepath.Join("env2", "common.abc"),
Expand All @@ -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"),
Expand All @@ -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"),
Expand All @@ -184,26 +191,35 @@ 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"),
filepath.Join("env2", "testing3.abc.def"),
},
},
{
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"),
Expand All @@ -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)
}
}
Expand All @@ -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"),
},
},
}
Expand All @@ -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)

Expand All @@ -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",
},
},
Expand All @@ -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)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
---
envLevelCommon2: set level
setLevelCommon: testing1 level
setLevel: set level
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
setLevelCommon: testing2 level
Empty file.

0 comments on commit 0966323

Please sign in to comment.