diff --git a/chezmoi2/cmd/config.go b/chezmoi2/cmd/config.go index 087d6aaa9be..ded1f997e05 100644 --- a/chezmoi2/cmd/config.go +++ b/chezmoi2/cmd/config.go @@ -1056,11 +1056,11 @@ func (c *Config) sourcePaths(s *chezmoi.SourceState, args []string) ([]string, e func (c *Config) sourceState() (*chezmoi.SourceState, error) { s := chezmoi.NewSourceState( + chezmoi.WithDefaultTemplateDataFunc(c.defaultTemplateData), chezmoi.WithDestDir(c.normalizedDestDir), chezmoi.WithPriorityTemplateData(c.Data), chezmoi.WithSourceDir(c.normalizedSourceDir), chezmoi.WithSystem(c.sourceSystem), - chezmoi.WithTemplateData(c.defaultTemplateData()), chezmoi.WithTemplateFuncs(c.templateFuncs), chezmoi.WithTemplateOptions(c.Template.Options), ) diff --git a/chezmoi2/internal/chezmoi/chezmoi_unix.go b/chezmoi2/internal/chezmoi/chezmoi_unix.go index bda589a19ce..80b46a048ff 100644 --- a/chezmoi2/internal/chezmoi/chezmoi_unix.go +++ b/chezmoi2/internal/chezmoi/chezmoi_unix.go @@ -94,6 +94,8 @@ func etcHostsFQDNHostname(fs vfs.FS) (string, error) { text = text[:index] } fields := whitespaceRx.Split(text, -1) + if len(fields) >= 2 && fields[0] == "127.0.1.1" { + return fields[1], nil } } return "", s.Err() @@ -112,6 +114,8 @@ func isPrivate(info os.FileInfo) bool { // lookupAddrFQDNHostname returns the FQDN hostname by doing a reverse lookup of // 127.0.1.1. func lookupAddrFQDNHostname() (string, error) { + names, err := net.LookupAddr("127.0.1.1") + if err != nil { return "", err } if len(names) == 0 { diff --git a/chezmoi2/internal/chezmoi/sourcestate.go b/chezmoi2/internal/chezmoi/sourcestate.go index 12409926cce..96a5da047b6 100644 --- a/chezmoi2/internal/chezmoi/sourcestate.go +++ b/chezmoi2/internal/chezmoi/sourcestate.go @@ -25,19 +25,21 @@ type Lstater interface { // A SourceState is a source state. type SourceState struct { - entries map[string]SourceStateEntry - system System - sourceDir string - destDir string - umask os.FileMode - encryptionTool EncryptionTool - ignore *patternSet - minVersion semver.Version - priorityTemplateData map[string]interface{} - templateData map[string]interface{} - templateFuncs template.FuncMap - templateOptions []string - templates map[string]*template.Template + entries map[string]SourceStateEntry + system System + sourceDir string + destDir string + umask os.FileMode + encryptionTool EncryptionTool + ignore *patternSet + minVersion semver.Version + defaultTemplateDataFunc func() map[string]interface{} + templateData map[string]interface{} + priorityTemplateData map[string]interface{} + templateDataValue map[string]interface{} + templateFuncs template.FuncMap + templateOptions []string + templates map[string]*template.Template } // A SourceStateOption sets an option on a source state. @@ -61,7 +63,6 @@ func WithEncryptionTool(encryptionTool EncryptionTool) SourceStateOption { func WithPriorityTemplateData(priorityTemplateData map[string]interface{}) SourceStateOption { return func(s *SourceState) { recursiveMerge(s.priorityTemplateData, priorityTemplateData) - recursiveMerge(s.templateData, s.priorityTemplateData) } } @@ -79,11 +80,10 @@ func WithSystem(system System) SourceStateOption { } } -// WithTemplateData adds template data. -func WithTemplateData(templateData map[string]interface{}) SourceStateOption { +// WithDefaultTemplateDataFunc sets the default template data function. +func WithDefaultTemplateDataFunc(defaultTemplateDataFunc func() map[string]interface{}) SourceStateOption { return func(s *SourceState) { - recursiveMerge(s.templateData, templateData) - recursiveMerge(s.templateData, s.priorityTemplateData) + s.defaultTemplateDataFunc = defaultTemplateDataFunc } } @@ -634,7 +634,16 @@ func (s *SourceState) TargetNames() []string { // TemplateData returns s's template data. func (s *SourceState) TemplateData() map[string]interface{} { - return s.templateData + if s.templateDataValue == nil { + s.templateDataValue = make(map[string]interface{}) + if s.defaultTemplateDataFunc != nil { + recursiveMerge(s.templateDataValue, s.defaultTemplateDataFunc()) + s.defaultTemplateDataFunc = nil + } + recursiveMerge(s.templateDataValue, s.templateData) + recursiveMerge(s.templateDataValue, s.priorityTemplateData) + } + return s.templateDataValue } // addPatterns executes the template at sourcePath, interprets the result as a @@ -690,7 +699,6 @@ func (s *SourceState) addTemplateData(sourcePath string) error { return fmt.Errorf("%s: %w", sourcePath, err) } recursiveMerge(s.templateData, templateData) - recursiveMerge(s.templateData, s.priorityTemplateData) return nil } diff --git a/chezmoi2/internal/chezmoi/sourcestate_test.go b/chezmoi2/internal/chezmoi/sourcestate_test.go index 9c2e44b3451..4ad686f9795 100644 --- a/chezmoi2/internal/chezmoi/sourcestate_test.go +++ b/chezmoi2/internal/chezmoi/sourcestate_test.go @@ -439,7 +439,7 @@ func TestSourceStateApplyAll(t *testing.T) { }, }, sourceStateOptions: []SourceStateOption{ - WithTemplateData(map[string]interface{}{ + withTemplateData(map[string]interface{}{ "email": "you@example.com", }), }, @@ -512,7 +512,7 @@ func TestSourceStateApplyAll(t *testing.T) { }, }, sourceStateOptions: []SourceStateOption{ - WithTemplateData(map[string]interface{}{ + withTemplateData(map[string]interface{}{ "os": "linux", }), }, @@ -1028,6 +1028,7 @@ func TestSourceStateRead(t *testing.T) { tc.expectedSourceState.sourceDir = "/home/user/.local/share/chezmoi" require.NoError(t, tc.expectedSourceState.evaluateAll()) s.system = nil + s.templateDataValue = nil assert.Equal(t, tc.expectedSourceState, s) }) }) @@ -1122,6 +1123,13 @@ func withMinVersion(minVersion semver.Version) SourceStateOption { } } +// withTemplateData adds template data. +func withTemplateData(templateData map[string]interface{}) SourceStateOption { + return func(s *SourceState) { + recursiveMerge(s.templateData, templateData) + } +} + func withTemplates(templates map[string]*template.Template) SourceStateOption { return func(s *SourceState) { s.templates = templates