Skip to content

Commit

Permalink
feat: Set CHEZMOI_ and scriptEnv env vars for all invoked commands
Browse files Browse the repository at this point in the history
  • Loading branch information
twpayne committed Oct 10, 2023
1 parent 559b5e7 commit 7203d6b
Show file tree
Hide file tree
Showing 19 changed files with 22 additions and 94 deletions.
Expand Up @@ -39,7 +39,7 @@ sections:
description: Display progress bars
scriptEnv:
type: object
description: Extra environment variables for scripts
description: Extra environment variables for scripts and commands
scriptTempDir:
description: Temporary directory for scripts
sourceDir:
Expand Down
5 changes: 0 additions & 5 deletions internal/chezmoi/archivereadersystem.go
Expand Up @@ -109,8 +109,3 @@ func (s *ArchiveReaderSystem) Readlink(name AbsPath) (string, error) {
}
return "", fs.ErrNotExist
}

// UnderlyingSystem implements System.UnderlyingSystem.
func (s *ArchiveReaderSystem) UnderlyingSystem() System {
return s
}
5 changes: 0 additions & 5 deletions internal/chezmoi/debugsystem.go
Expand Up @@ -191,11 +191,6 @@ func (s *DebugSystem) UnderlyingFS() vfs.FS {
return s.system.UnderlyingFS()
}

// UnderlyingSystem implements System.UnderlyingSystem.
func (s *DebugSystem) UnderlyingSystem() System {
return s.system
}

// WriteFile implements System.WriteFile.
func (s *DebugSystem) WriteFile(name AbsPath, data []byte, perm fs.FileMode) error {
err := s.system.WriteFile(name, data, perm)
Expand Down
5 changes: 0 additions & 5 deletions internal/chezmoi/dryrunsystem.go
Expand Up @@ -127,11 +127,6 @@ func (s *DryRunSystem) UnderlyingFS() vfs.FS {
return s.system.UnderlyingFS()
}

// UnderlyingSystem implements System.UnderlyingSystem.
func (s *DryRunSystem) UnderlyingSystem() System {
return s.system
}

// WriteFile implements System.WriteFile.
func (s *DryRunSystem) WriteFile(AbsPath, []byte, fs.FileMode) error {
s.setModified()
Expand Down
5 changes: 0 additions & 5 deletions internal/chezmoi/dumpsystem.go
Expand Up @@ -124,11 +124,6 @@ func (s *DumpSystem) UnderlyingFS() vfs.FS {
return nil
}

// UnderlyingSystem implements System.UnderlyingSystem.
func (s *DumpSystem) UnderlyingSystem() System {
return s
}

// WriteFile implements System.WriteFile.
func (s *DumpSystem) WriteFile(filename AbsPath, data []byte, perm fs.FileMode) error {
return s.setData(filename.String(), &fileData{
Expand Down
5 changes: 0 additions & 5 deletions internal/chezmoi/erroronwritesystem.go
Expand Up @@ -114,11 +114,6 @@ func (s *ErrorOnWriteSystem) UnderlyingFS() vfs.FS {
return s.system.UnderlyingFS()
}

// UnderlyingSystem implements System.UnderlyingSystem.
func (s *ErrorOnWriteSystem) UnderlyingSystem() System {
return s.system
}

// WriteFile implements System.WriteFile.
func (s *ErrorOnWriteSystem) WriteFile(AbsPath, []byte, fs.FileMode) error {
return s.err
Expand Down
5 changes: 0 additions & 5 deletions internal/chezmoi/externaldiffsystem.go
Expand Up @@ -224,11 +224,6 @@ func (s *ExternalDiffSystem) UnderlyingFS() vfs.FS {
return s.system.UnderlyingFS()
}

// UnderlyingSystem implements System.UnderlyingSystem.
func (s *ExternalDiffSystem) UnderlyingSystem() System {
return s.system
}

// WriteFile implements System.WriteFile.
func (s *ExternalDiffSystem) WriteFile(filename AbsPath, data []byte, perm fs.FileMode) error {
if s.filter.IncludeEntryTypeBits(EntryTypeFiles) {
Expand Down
5 changes: 0 additions & 5 deletions internal/chezmoi/gitdiffsystem.go
Expand Up @@ -247,11 +247,6 @@ func (s *GitDiffSystem) UnderlyingFS() vfs.FS {
return s.system.UnderlyingFS()
}

// UnderlyingSystem implements System.UnderlyingSystem.
func (s *GitDiffSystem) UnderlyingSystem() System {
return s.system
}

// WriteFile implements System.WriteFile.
func (s *GitDiffSystem) WriteFile(filename AbsPath, data []byte, perm fs.FileMode) error {
if s.filter.IncludeEntryTypeBits(EntryTypeFiles) {
Expand Down
5 changes: 0 additions & 5 deletions internal/chezmoi/nullsystem.go
Expand Up @@ -4,8 +4,3 @@ type NullSystem struct {
emptySystemMixin
noUpdateSystemMixin
}

// UnderlyingSystem implements System.UnderlyingSystem.
func (s *NullSystem) UnderlyingSystem() System {
return s
}
5 changes: 0 additions & 5 deletions internal/chezmoi/readonlysystem.go
Expand Up @@ -58,8 +58,3 @@ func (s *ReadOnlySystem) Stat(name AbsPath) (fs.FileInfo, error) {
func (s *ReadOnlySystem) UnderlyingFS() vfs.FS {
return s.system.UnderlyingFS()
}

// UnderlyingSystem implements System.UnderlyingSystem.
func (s *ReadOnlySystem) UnderlyingSystem() System {
return s.system
}
11 changes: 0 additions & 11 deletions internal/chezmoi/realsystem.go
Expand Up @@ -128,19 +128,13 @@ func (s *RealSystem) RunScript(
if err != nil {
return err
}
cmd.Env = s.scriptEnv
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr

return s.RunCmd(cmd)
}

// SetScriptEnv sets the environment variables for scripts.
func (s *RealSystem) SetScriptEnv(scriptEnv []string) {
s.scriptEnv = scriptEnv
}

// Stat implements System.Stat.
func (s *RealSystem) Stat(name AbsPath) (fs.FileInfo, error) {
return s.fileSystem.Stat(name.String())
Expand All @@ -151,11 +145,6 @@ func (s *RealSystem) UnderlyingFS() vfs.FS {
return s.fileSystem
}

// UnderlyingSystem implements System.UnderlyingSystem.
func (s *RealSystem) UnderlyingSystem() System {
return s
}

// getScriptWorkingDir returns the script's working directory.
//
// If this is a before_ script then the requested working directory may not
Expand Down
1 change: 0 additions & 1 deletion internal/chezmoi/realsystem_unix.go
Expand Up @@ -21,7 +21,6 @@ type RealSystem struct {
safe bool
createScriptTempDirOnce sync.Once
scriptTempDir AbsPath
scriptEnv []string
devCache map[AbsPath]uint // devCache maps directories to device numbers.
tempDirCache map[uint]string // tempDirCache maps device numbers to renameio temporary directories.
}
Expand Down
9 changes: 0 additions & 9 deletions internal/chezmoi/sourcestate.go
Expand Up @@ -124,7 +124,6 @@ type SourceState struct {
defaultTemplateData map[string]any
userTemplateData map[string]any
priorityTemplateData map[string]any
scriptEnv []string
templateData map[string]any
templateFuncs template.FuncMap
templateOptions []string
Expand Down Expand Up @@ -213,13 +212,6 @@ func WithReadTemplateData(readTemplateData bool) SourceStateOption {
}
}

// WithScriptEnv sets the script environment variables.
func WithScriptEnv(scriptEnv []string) SourceStateOption {
return func(s *SourceState) {
s.scriptEnv = scriptEnv
}
}

// WithSourceDir sets the source directory.
func WithSourceDir(sourceDirAbsPath AbsPath) SourceStateOption {
return func(s *SourceState) {
Expand Down Expand Up @@ -1911,7 +1903,6 @@ func (s *SourceState) newModifyTargetStateEntryFunc(

// Run the modifier on the current contents.
cmd := interpreter.ExecCommand(tempFile.Name())
cmd.Env = s.scriptEnv
cmd.Stdin = bytes.NewReader(currentContents)
cmd.Stderr = os.Stderr
contents, err = chezmoilog.LogCmdOutput(cmd)
Expand Down
1 change: 0 additions & 1 deletion internal/chezmoi/system.go
Expand Up @@ -38,7 +38,6 @@ type System interface { //nolint:interfacebloat
RunScript(scriptname RelPath, dir AbsPath, data []byte, options RunScriptOptions) error
Stat(name AbsPath) (fs.FileInfo, error)
UnderlyingFS() vfs.FS
UnderlyingSystem() System
WriteFile(filename AbsPath, data []byte, perm fs.FileMode) error
WriteSymlink(oldname string, newname AbsPath) error
}
Expand Down
5 changes: 0 additions & 5 deletions internal/chezmoi/tarwritersystem.go
Expand Up @@ -52,11 +52,6 @@ func (s *TarWriterSystem) RunScript(
return s.WriteFile(NewAbsPath(scriptname.String()), data, 0o700)
}

// UnderlyingSystem implements System.UnderlyingSystem.
func (s *TarWriterSystem) UnderlyingSystem() System {
return s
}

// WriteFile implements System.WriteFile.
func (s *TarWriterSystem) WriteFile(filename AbsPath, data []byte, perm fs.FileMode) error {
header := s.headerTemplate
Expand Down
5 changes: 0 additions & 5 deletions internal/chezmoi/zipwritersystem.go
Expand Up @@ -57,11 +57,6 @@ func (s *ZIPWriterSystem) RunScript(
return s.WriteFile(NewAbsPath(scriptname.String()), data, 0o700)
}

// UnderlyingSystem implements System.UnderlyingSystem.
func (s *ZIPWriterSystem) UnderlyingSystem() System {
return s
}

// WriteFile implements System.WriteFile.
func (s *ZIPWriterSystem) WriteFile(filename AbsPath, data []byte, perm fs.FileMode) error {
fileHeader := zip.FileHeader{
Expand Down
3 changes: 2 additions & 1 deletion internal/cmd/cdcmd.go
Expand Up @@ -36,9 +36,10 @@ func (c *Config) newCDCmd() *cobra.Command {
}

func (c *Config) runCDCmd(cmd *cobra.Command, args []string) error {
if _, ok := os.LookupEnv("CHEZMOI"); ok {
if _, ok := os.LookupEnv("CHEZMOI_SUBSHELL"); ok {
return errors.New("already in a chezmoi subshell")
}
os.Setenv("CHEZMOI_SUBSHELL", "1")

cdCommand, cdArgs, err := c.cdCommand()
if err != nil {
Expand Down
22 changes: 7 additions & 15 deletions internal/cmd/config.go
Expand Up @@ -232,7 +232,6 @@ type Config struct {
sourceState *chezmoi.SourceState
sourceStateErr error
templateData *templateData
runEnv []string

stdin io.Reader
stdout io.Writer
Expand Down Expand Up @@ -710,9 +709,7 @@ func (c *Config) createAndReloadConfigFile(cmd *cobra.Command) error {
return err
}
c.templateData.sourceDir = sourceDirAbsPath
c.runEnv = append(c.runEnv, "CHEZMOI_SOURCE_DIR="+sourceDirAbsPath.String())
realSystem := c.baseSystem.UnderlyingSystem().(*chezmoi.RealSystem) //nolint:forcetypeassert
realSystem.SetScriptEnv(c.runEnv)
os.Setenv("CHEZMOI_SOURCE_DIR", sourceDirAbsPath.String())

// Find config template, execute it, and create config file.
configTemplate, err := c.findConfigTemplate()
Expand Down Expand Up @@ -1705,7 +1702,6 @@ func (c *Config) newSourceState(
chezmoi.WithLogger(&sourceStateLogger),
chezmoi.WithMode(c.Mode),
chezmoi.WithPriorityTemplateData(c.Data),
chezmoi.WithScriptEnv(c.runEnv),
chezmoi.WithSourceDir(c.SourceDirAbsPath),
chezmoi.WithSystem(c.sourceSystem),
chezmoi.WithTemplateFuncs(c.templateFuncs),
Expand Down Expand Up @@ -2091,9 +2087,8 @@ func (c *Config) persistentPreRunRootE(cmd *cobra.Command, args []string) error
}
}

scriptEnv := os.Environ()
templateData := c.getTemplateData(cmd)
scriptEnv = append(scriptEnv, "CHEZMOI=1")
os.Setenv("CHEZMOI", "1")
for key, value := range map[string]string{
"ARCH": templateData.arch,
"ARGS": strings.Join(templateData.args, " "),
Expand All @@ -2112,10 +2107,10 @@ func (c *Config) persistentPreRunRootE(cmd *cobra.Command, args []string) error
"USERNAME": templateData.username,
"WORKING_TREE": templateData.workingTree.String(),
} {
scriptEnv = append(scriptEnv, "CHEZMOI_"+key+"="+value)
os.Setenv("CHEZMOI_"+key, value)
}
if c.Verbose {
scriptEnv = append(scriptEnv, "CHEZMOI_VERBOSE=1")
os.Setenv("CHEZMOI_VERBOSE", "1")
}
for groupKey, group := range map[string]map[string]any{
"KERNEL": templateData.kernel,
Expand All @@ -2124,16 +2119,14 @@ func (c *Config) persistentPreRunRootE(cmd *cobra.Command, args []string) error
"WINDOWS_VERSION": templateData.windowsVersion,
} {
for key, value := range group {
upperSnakeCaseKey := camelCaseToUpperSnakeCase(key)
key := "CHEZMOI_" + groupKey + "_" + camelCaseToUpperSnakeCase(key)
valueStr := fmt.Sprintf("%s", value)
scriptEnv = append(scriptEnv, "CHEZMOI_"+groupKey+"_"+upperSnakeCaseKey+"="+valueStr)
os.Setenv(key, valueStr)
}
}
for key, value := range c.ScriptEnv {
scriptEnv = append(scriptEnv, key+"="+value)
os.Setenv(key, value)
}
c.runEnv = scriptEnv
realSystem.SetScriptEnv(scriptEnv)

if command := c.Hooks[cmd.Name()].Pre; command.Command != "" {
if err := c.run(c.homeDirAbsPath, command.Command, command.Args); err != nil {
Expand Down Expand Up @@ -2326,7 +2319,6 @@ func (c *Config) run(dir chezmoi.AbsPath, name string, args []string) error {
}
cmd.Dir = dirRawAbsPath.String()
}
cmd.Env = c.runEnv
cmd.Stdin = c.stdin
cmd.Stdout = c.stdout
cmd.Stderr = c.stderr
Expand Down
12 changes: 12 additions & 0 deletions internal/cmd/testdata/scripts/issue3268.txtar
@@ -0,0 +1,12 @@
[unix] chmod 755 bin/chezmoi-test-command

# test that chezmoi sets CHEZMOI_ environment variables
exec chezmoi execute-template '{{ output "chezmoi-test-command" }}'
stdout 'CHEZMOI_SOURCE_DIR=.*/\.local/share/chezmoi\s?$'

-- bin/chezmoi-test-command --
#!/bin/sh

echo CHEZMOI_SOURCE_DIR=${CHEZMOI_SOURCE_DIR}
-- bin/chezmoi-test-command.cmd --
@echo CHEZMOI_SOURCE_DIR=%CHEZMOI_SOURCE_DIR%

0 comments on commit 7203d6b

Please sign in to comment.