Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix reference lookup so it works with dependencies #36

Merged
merged 1 commit into from Jul 13, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
21 changes: 13 additions & 8 deletions config/get_variables.go
Expand Up @@ -60,23 +60,28 @@ func getUnmarshalledValueForVariable(variable variables.Variable, variablesInCon
return nil, errors.WithStackTrace(CyclicalReference{VariableName: variable.Name(), ReferenceName: variable.Reference()})
}

value, alreadyExists := alreadyUnmarshalledVariables[variable.Name()]
if alreadyExists {
return variables.UnmarshalValueForVariable(value, variable)
}

if variable.Reference() != "" {
value, alreadyExists := alreadyUnmarshalledVariables[variable.Reference()]
if alreadyExists {
return variables.UnmarshalValueForVariable(value, variable)
}

reference, containsReference := variablesInConfig[variable.Reference()]
if !containsReference {
return nil, errors.WithStackTrace(MissingReference{VariableName: variable.Name(), ReferenceName: variable.Reference()})
}
return getUnmarshalledValueForVariable(reference, variablesInConfig, alreadyUnmarshalledVariables, options, referenceDepth + 1)
}

value, alreadyExists := alreadyUnmarshalledVariables[variable.Name()]
if !alreadyExists {
variableValue, err := getVariable(variable, options)
if err != nil {
return nil, err
}
value = variableValue
value, err := getVariable(variable, options)
if err != nil {
return nil, err
}

return variables.UnmarshalValueForVariable(value, variable)
}

Expand Down
7 changes: 6 additions & 1 deletion examples/variables-recursive/boilerplate.yml
Expand Up @@ -27,4 +27,9 @@ variables:

- name: BarMap
type: map
reference: FooMap
reference: FooMap

dependencies:
- name: variables
template-folder: ../variables
output-folder: .
5 changes: 5 additions & 0 deletions examples/variables/boilerplate.yml
@@ -0,0 +1,5 @@
variables:
- name: BazMap
type: map
reference: FooMap

1 change: 1 addition & 0 deletions examples/variables/example.txt
@@ -0,0 +1 @@
BazMap = {{ range $index, $key := (.BazMap | keys) }}{{ if gt $index 0 }}, {{ end }}{{ $key }}: {{ index $.BazMap $key }}{{ end }}
44 changes: 29 additions & 15 deletions integration-tests/examples_test.go
Expand Up @@ -11,6 +11,7 @@ import (
"os"
"strings"
"github.com/gruntwork-io/boilerplate/config"
"github.com/gruntwork-io/boilerplate/util"
)

// Our integration tests run through all the examples in the /examples folder, generate them, and check that they
Expand All @@ -26,28 +27,41 @@ func TestExamples(t *testing.T) {
assert.Nil(t, err)
defer os.Remove(outputBasePath)

files, err := ioutil.ReadDir(examplesBasePath)
examples, err := ioutil.ReadDir(examplesBasePath)
assert.Nil(t, err)

app := cli.CreateBoilerplateCli("test")
for _, example := range examples {
if !example.IsDir() {
continue
}

templateFolder := path.Join(examplesBasePath, example.Name())
outputFolder := path.Join(outputBasePath, example.Name())
varFile := path.Join(examplesVarFilesBasePath, example.Name(), "vars.yml")
expectedOutputFolder := path.Join(examplesExpectedOutputBasePath, example.Name())

if !util.PathExists(varFile) || !util.PathExists(expectedOutputFolder) {
t.Logf("Skipping example %s because either the var file (%s) or expected output folder (%s) does not exist.", templateFolder, varFile, expectedOutputFolder)
continue
}

for _, file := range files {
if file.IsDir() {
for _, missingKeyAction := range config.ALL_MISSING_KEY_ACTIONS {
templateFolder := path.Join(examplesBasePath, file.Name())
outputFolder := path.Join(outputBasePath, file.Name())
varFile := path.Join(examplesVarFilesBasePath, file.Name(), "vars.yml")
expectedOutputFolder := path.Join(examplesExpectedOutputBasePath, file.Name())

command := fmt.Sprintf("boilerplate --template-folder %s --output-folder %s --var-file %s --non-interactive --missing-key-action %s", templateFolder, outputFolder, varFile, string(missingKeyAction))
err := app.Run(strings.Split(command, " "))
assert.Nil(t, err, "boilerplate exited with an error when trying to generate example %s: %s", templateFolder, err)
assertDirectoriesEqual(t, expectedOutputFolder, outputFolder)
}
for _, missingKeyAction := range config.ALL_MISSING_KEY_ACTIONS {
t.Run(fmt.Sprintf("%s-missing-key-%s", example.Name(), string(missingKeyAction)), func(t *testing.T) {
testExample(t, templateFolder, outputFolder, varFile, expectedOutputFolder, string(missingKeyAction))
})
}
}
}

func testExample(t *testing.T, templateFolder string, outputFolder string, varFile string, expectedOutputFolder string, missingKeyAction string) {
app := cli.CreateBoilerplateCli("test")

command := fmt.Sprintf("boilerplate --template-folder %s --output-folder %s --var-file %s --non-interactive --missing-key-action %s", templateFolder, outputFolder, varFile, missingKeyAction)
err := app.Run(strings.Split(command, " "))
assert.Nil(t, err, "boilerplate exited with an error when trying to generate example %s: %s", templateFolder, err)
assertDirectoriesEqual(t, expectedOutputFolder, outputFolder)
}

// Diffing two directories to ensure they have the exact same files, contents, etc and showing exactly what's different
// takes a lot of code. Why waste time on that when this functionality is already nicely implemented in the Unix/Linux
// "diff" command? We shell out to that command at test time.
Expand Down
@@ -0,0 +1 @@
BazMap = bar: 2, baz: 3, foo: 1
2 changes: 1 addition & 1 deletion variables/variables.go
Expand Up @@ -161,7 +161,7 @@ func (variable defaultVariable) WithDefault(value interface{}) Variable {
}

func (variable defaultVariable) String() string {
return fmt.Sprintf("Variable {Name: '%s', Description: '%s', Type: '%v', Default: '%v', Options: '%v'}", variable.Name(), variable.Description(), variable.Type(), variable.Default(), variable.Options())
return fmt.Sprintf("Variable {Name: '%s', Description: '%s', Type: '%v', Default: '%v', Options: '%v', Reference: '%v'}", variable.Name(), variable.Description(), variable.Type(), variable.Default(), variable.Options(), variable.Reference())
}

func (variable defaultVariable) ExampleValue() string {
Expand Down