Skip to content

Commit

Permalink
Compute valueRegexp when needed
Browse files Browse the repository at this point in the history
  • Loading branch information
twpayne committed Jan 10, 2019
1 parent 4e07b0e commit 9219d3f
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 13 deletions.
20 changes: 11 additions & 9 deletions lib/chezmoi/autotemplate.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ import (
)

type templateVariable struct {
name string
value string
valueRegexp *regexp.Regexp
name string
value string
}

type byValueLength []templateVariable
Expand All @@ -33,9 +32,8 @@ func extractVariables(variables []templateVariable, parent []string, data map[st
switch value := value.(type) {
case string:
variables = append(variables, templateVariable{
name: strings.Join(append(parent, name), "."),
value: value,
valueRegexp: regexp.MustCompile(`\b` + regexp.QuoteMeta(value) + `\b`),
name: strings.Join(append(parent, name), "."),
value: value,
})
case map[string]interface{}:
variables = extractVariables(variables, append(parent, name), value)
Expand All @@ -44,14 +42,18 @@ func extractVariables(variables []templateVariable, parent []string, data map[st
return variables
}

func autoTemplate(contents []byte, data map[string]interface{}) []byte {
func autoTemplate(contents []byte, data map[string]interface{}) ([]byte, error) {
// FIXME this naive approach will generate incorrect templates if the
// variable names match variable values
variables := extractVariables(nil, nil, data)
sort.Sort(sort.Reverse(byValueLength(variables)))
contentsStr := string(contents)
for _, variable := range variables {
contentsStr = variable.valueRegexp.ReplaceAllString(contentsStr, "{{ ."+variable.name+" }}")
valueRegexp, err := regexp.Compile(`\b` + regexp.QuoteMeta(variable.value) + `\b`)
if err != nil {
return nil, err
}
contentsStr = valueRegexp.ReplaceAllString(contentsStr, "{{ ."+variable.name+" }}")
}
return []byte(contentsStr)
return []byte(contentsStr), nil
}
6 changes: 3 additions & 3 deletions lib/chezmoi/autotemplate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@ func TestAutoTemplate(t *testing.T) {
*/
} {
t.Run(tc.name, func(t *testing.T) {
got := autoTemplate([]byte(tc.contentsStr), tc.data)
got, gotErr := autoTemplate([]byte(tc.contentsStr), tc.data)
gotStr := string(got)
if gotStr != tc.wantStr {
t.Errorf("autoTemplate([]byte(%q), %v) == %q, want %q", tc.contentsStr, tc.data, gotStr, tc.wantStr)
if gotErr != nil || gotStr != tc.wantStr {
t.Errorf("autoTemplate([]byte(%q), %v) == %q, %v, want %q, <nil>", tc.contentsStr, tc.data, gotStr, gotErr, tc.wantStr)
}
})
}
Expand Down
5 changes: 4 additions & 1 deletion lib/chezmoi/target_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,10 @@ func (ts *TargetState) Add(fs vfs.FS, addOptions AddOptions, targetPath string,
return err
}
if addOptions.Template {
contents = autoTemplate(contents, ts.Data)
contents, err = autoTemplate(contents, ts.Data)
if err != nil {
return err
}
}
return ts.addFile(targetName, entries, parentDirSourceName, info, addOptions.Template, contents, mutator)
case info.Mode()&os.ModeType == os.ModeSymlink:
Expand Down

0 comments on commit 9219d3f

Please sign in to comment.