diff --git a/internal/chezmoi/sourcestate.go b/internal/chezmoi/sourcestate.go index f0aa8d82547..a5648d5fbd7 100644 --- a/internal/chezmoi/sourcestate.go +++ b/internal/chezmoi/sourcestate.go @@ -121,7 +121,7 @@ type SourceState struct { encryption Encryption ignore *patternSet remove *patternSet - interpreters map[string]*Interpreter + interpreters map[string]Interpreter httpClient *http.Client logger *slog.Logger version semver.Version @@ -187,7 +187,7 @@ func WithHTTPClient(httpClient *http.Client) SourceStateOption { } // WithInterpreters sets the interpreters. -func WithInterpreters(interpreters map[string]*Interpreter) SourceStateOption { +func WithInterpreters(interpreters map[string]Interpreter) SourceStateOption { return func(s *SourceState) { s.interpreters = interpreters } @@ -2023,27 +2023,31 @@ func (s *SourceState) newSourceStateFile( // If the target has an extension, determine if it indicates an // interpreter to use. extension := strings.ToLower(strings.TrimPrefix(targetRelPath.Ext(), ".")) - interpreter := s.interpreters[extension] - if interpreter != nil { + if interpreter, ok := s.interpreters[extension]; ok { // For modify scripts, the script extension is not considered part // of the target name, so remove it. targetRelPath = targetRelPath.Slice(0, targetRelPath.Len()-len(extension)-1) + targetStateEntryFunc = s.newModifyTargetStateEntryFunc(sourceRelPath, fileAttr, sourceLazyContents, &interpreter) + } else { + targetStateEntryFunc = s.newModifyTargetStateEntryFunc(sourceRelPath, fileAttr, sourceLazyContents, nil) } - targetStateEntryFunc = s.newModifyTargetStateEntryFunc(sourceRelPath, fileAttr, sourceLazyContents, interpreter) case SourceFileTypeRemove: targetStateEntryFunc = s.newRemoveTargetStateEntryFunc(sourceRelPath, fileAttr) case SourceFileTypeScript: // If the script has an extension, determine if it indicates an // interpreter to use. extension := strings.ToLower(strings.TrimPrefix(targetRelPath.Ext(), ".")) - interpreter := s.interpreters[extension] - targetStateEntryFunc = s.newScriptTargetStateEntryFunc( - sourceRelPath, - fileAttr, - targetRelPath, - sourceLazyContents, - interpreter, - ) + if interpreter, ok := s.interpreters[extension]; ok { + targetStateEntryFunc = s.newScriptTargetStateEntryFunc( + sourceRelPath, + fileAttr, + targetRelPath, + sourceLazyContents, + &interpreter, + ) + } else { + targetStateEntryFunc = s.newScriptTargetStateEntryFunc(sourceRelPath, fileAttr, targetRelPath, sourceLazyContents, nil) + } case SourceFileTypeSymlink: targetStateEntryFunc = s.newSymlinkTargetStateEntryFunc(sourceRelPath, fileAttr, sourceLazyContents) default: diff --git a/internal/cmd/config.go b/internal/cmd/config.go index 96daea78b4f..127dad37ea1 100644 --- a/internal/cmd/config.go +++ b/internal/cmd/config.go @@ -97,32 +97,32 @@ type warningsConfig struct { // ConfigFile contains all data settable in the config file. type ConfigFile struct { // Global configuration. - CacheDirAbsPath chezmoi.AbsPath `json:"cacheDir" mapstructure:"cacheDir" yaml:"cacheDir"` - Color autoBool `json:"color" mapstructure:"color" yaml:"color"` - Data map[string]any `json:"data" mapstructure:"data" yaml:"data"` - Env map[string]string `json:"env" mapstructure:"env" yaml:"env"` - Format writeDataFormat `json:"format" mapstructure:"format" yaml:"format"` - DestDirAbsPath chezmoi.AbsPath `json:"destDir" mapstructure:"destDir" yaml:"destDir"` - GitHub gitHubConfig `json:"gitHub" mapstructure:"gitHub" yaml:"gitHub"` - Hooks map[string]hookConfig `json:"hooks" mapstructure:"hooks" yaml:"hooks"` - Interpreters map[string]*chezmoi.Interpreter `json:"interpreters" mapstructure:"interpreters" yaml:"interpreters"` - Mode chezmoi.Mode `json:"mode" mapstructure:"mode" yaml:"mode"` - Pager string `json:"pager" mapstructure:"pager" yaml:"pager"` - PersistentStateAbsPath chezmoi.AbsPath `json:"persistentState" mapstructure:"persistentState" yaml:"persistentState"` - PINEntry pinEntryConfig `json:"pinentry" mapstructure:"pinentry" yaml:"pinentry"` - Progress autoBool `json:"progress" mapstructure:"progress" yaml:"progress"` - Safe bool `json:"safe" mapstructure:"safe" yaml:"safe"` - ScriptEnv map[string]string `json:"scriptEnv" mapstructure:"scriptEnv" yaml:"scriptEnv"` - ScriptTempDir chezmoi.AbsPath `json:"scriptTempDir" mapstructure:"scriptTempDir" yaml:"scriptTempDir"` - SourceDirAbsPath chezmoi.AbsPath `json:"sourceDir" mapstructure:"sourceDir" yaml:"sourceDir"` - Template templateConfig `json:"template" mapstructure:"template" yaml:"template"` - TextConv textConv `json:"textConv" mapstructure:"textConv" yaml:"textConv"` - Umask fs.FileMode `json:"umask" mapstructure:"umask" yaml:"umask"` - UseBuiltinAge autoBool `json:"useBuiltinAge" mapstructure:"useBuiltinAge" yaml:"useBuiltinAge"` - UseBuiltinGit autoBool `json:"useBuiltinGit" mapstructure:"useBuiltinGit" yaml:"useBuiltinGit"` - Verbose bool `json:"verbose" mapstructure:"verbose" yaml:"verbose"` - Warnings warningsConfig `json:"warnings" mapstructure:"warnings" yaml:"warnings"` - WorkingTreeAbsPath chezmoi.AbsPath `json:"workingTree" mapstructure:"workingTree" yaml:"workingTree"` + CacheDirAbsPath chezmoi.AbsPath `json:"cacheDir" mapstructure:"cacheDir" yaml:"cacheDir"` + Color autoBool `json:"color" mapstructure:"color" yaml:"color"` + Data map[string]any `json:"data" mapstructure:"data" yaml:"data"` + Env map[string]string `json:"env" mapstructure:"env" yaml:"env"` + Format writeDataFormat `json:"format" mapstructure:"format" yaml:"format"` + DestDirAbsPath chezmoi.AbsPath `json:"destDir" mapstructure:"destDir" yaml:"destDir"` + GitHub gitHubConfig `json:"gitHub" mapstructure:"gitHub" yaml:"gitHub"` + Hooks map[string]hookConfig `json:"hooks" mapstructure:"hooks" yaml:"hooks"` + Interpreters map[string]chezmoi.Interpreter `json:"interpreters" mapstructure:"interpreters" yaml:"interpreters"` + Mode chezmoi.Mode `json:"mode" mapstructure:"mode" yaml:"mode"` + Pager string `json:"pager" mapstructure:"pager" yaml:"pager"` + PersistentStateAbsPath chezmoi.AbsPath `json:"persistentState" mapstructure:"persistentState" yaml:"persistentState"` + PINEntry pinEntryConfig `json:"pinentry" mapstructure:"pinentry" yaml:"pinentry"` + Progress autoBool `json:"progress" mapstructure:"progress" yaml:"progress"` + Safe bool `json:"safe" mapstructure:"safe" yaml:"safe"` + ScriptEnv map[string]string `json:"scriptEnv" mapstructure:"scriptEnv" yaml:"scriptEnv"` + ScriptTempDir chezmoi.AbsPath `json:"scriptTempDir" mapstructure:"scriptTempDir" yaml:"scriptTempDir"` + SourceDirAbsPath chezmoi.AbsPath `json:"sourceDir" mapstructure:"sourceDir" yaml:"sourceDir"` + Template templateConfig `json:"template" mapstructure:"template" yaml:"template"` + TextConv textConv `json:"textConv" mapstructure:"textConv" yaml:"textConv"` + Umask fs.FileMode `json:"umask" mapstructure:"umask" yaml:"umask"` + UseBuiltinAge autoBool `json:"useBuiltinAge" mapstructure:"useBuiltinAge" yaml:"useBuiltinAge"` + UseBuiltinGit autoBool `json:"useBuiltinGit" mapstructure:"useBuiltinGit" yaml:"useBuiltinGit"` + Verbose bool `json:"verbose" mapstructure:"verbose" yaml:"verbose"` + Warnings warningsConfig `json:"warnings" mapstructure:"warnings" yaml:"warnings"` + WorkingTreeAbsPath chezmoi.AbsPath `json:"workingTree" mapstructure:"workingTree" yaml:"workingTree"` // Password manager configurations. AWSSecretsManager awsSecretsManagerConfig `json:"awsSecretsManager" mapstructure:"awsSecretsManager" yaml:"awsSecretsManager"` diff --git a/internal/cmd/config_test.go b/internal/cmd/config_test.go index 2569a6e20bf..b7f09fb08fe 100644 --- a/internal/cmd/config_test.go +++ b/internal/cmd/config_test.go @@ -39,7 +39,7 @@ func TestConfigFileFormatRoundTrip(t *testing.T) { Data: map[string]any{}, Env: map[string]string{}, Hooks: map[string]hookConfig{}, - Interpreters: map[string]*chezmoi.Interpreter{}, + Interpreters: map[string]chezmoi.Interpreter{}, Mode: chezmoi.ModeFile, PINEntry: pinEntryConfig{ Args: []string{}, diff --git a/internal/cmd/util_unix.go b/internal/cmd/util_unix.go index e9567934b40..f3548606d9d 100644 --- a/internal/cmd/util_unix.go +++ b/internal/cmd/util_unix.go @@ -11,7 +11,7 @@ import ( const defaultEditor = "vi" -var defaultInterpreters = make(map[string]*chezmoi.Interpreter) +var defaultInterpreters = make(map[string]chezmoi.Interpreter) func fileInfoUID(info fs.FileInfo) int { return int(info.Sys().(*syscall.Stat_t).Uid) //nolint:forcetypeassert diff --git a/internal/cmd/util_windows.go b/internal/cmd/util_windows.go index 73a417dd4a2..fc8e46e0cce 100644 --- a/internal/cmd/util_windows.go +++ b/internal/cmd/util_windows.go @@ -11,7 +11,7 @@ import ( const defaultEditor = "notepad.exe" -var defaultInterpreters = map[string]*chezmoi.Interpreter{ +var defaultInterpreters = map[string]chezmoi.Interpreter{ "bat": {}, "cmd": {}, "com": {},