Skip to content

Commit

Permalink
Allow source directory to be a symlink
Browse files Browse the repository at this point in the history
  • Loading branch information
twpayne committed Jul 14, 2021
1 parent 1e4940f commit 19500e0
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 6 deletions.
8 changes: 4 additions & 4 deletions internal/chezmoi/sourcestate.go
Original file line number Diff line number Diff line change
Expand Up @@ -540,8 +540,7 @@ func (s *SourceState) MustEntry(targetRelPath RelPath) SourceStateEntry {

// Read reads the source state from the source directory.
func (s *SourceState) Read() error {
info, err := s.system.Lstat(s.sourceDirAbsPath)
switch {
switch info, err := s.system.Stat(s.sourceDirAbsPath); {
case errors.Is(err, fs.ErrNotExist):
return nil
case err != nil:
Expand All @@ -552,7 +551,7 @@ func (s *SourceState) Read() error {

// Read all source entries.
allSourceStateEntries := make(map[RelPath][]SourceStateEntry)
if err := Walk(s.system, s.sourceDirAbsPath, func(sourceAbsPath AbsPath, info fs.FileInfo, err error) error {
if err := WalkDir(s.system, s.sourceDirAbsPath, func(sourceAbsPath AbsPath, info fs.FileInfo, err error) error {
if err != nil {
return err
}
Expand Down Expand Up @@ -714,6 +713,7 @@ func (s *SourceState) Read() error {
sort.Slice(targetRelPaths, func(i, j int) bool {
return targetRelPaths[i] < targetRelPaths[j]
})
var err error
for _, targetRelPath := range targetRelPaths {
sourceStateEntries := allSourceStateEntries[targetRelPath]
if len(sourceStateEntries) == 1 {
Expand Down Expand Up @@ -836,7 +836,7 @@ func (s *SourceState) addTemplateData(sourceAbsPath AbsPath) error {

// addTemplatesDir adds all templates in templateDir to s.
func (s *SourceState) addTemplatesDir(templatesDirAbsPath AbsPath) error {
return Walk(s.system, templatesDirAbsPath, func(templateAbsPath AbsPath, info fs.FileInfo, err error) error {
return WalkDir(s.system, templatesDirAbsPath, func(templateAbsPath AbsPath, info fs.FileInfo, err error) error {
if err != nil {
return err
}
Expand Down
20 changes: 19 additions & 1 deletion internal/chezmoi/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,27 @@ func MkdirAll(system System, absPath AbsPath, perm fs.FileMode) error {
}
}

// Walk walks rootAbsPath in s.
// Walk walks rootAbsPath in system, alling walkFn for each file or directory in
// the tree, including rootAbsPath.
//
// Walk does not follow symlinks.
func Walk(system System, rootAbsPath AbsPath, walkFn func(absPath AbsPath, info fs.FileInfo, err error) error) error {
return vfs.Walk(system.UnderlyingFS(), string(rootAbsPath), func(absPath string, info fs.FileInfo, err error) error {
return walkFn(AbsPath(filepath.ToSlash(absPath)), info, err)
})
}

// WalkDir walks the file tree rooted at rootAbsPath in system, calling walkFn
// for each file or directory in the tree, including rootAbsPath.
//
// WalkDir does not follow symbolic links found in directories, but if
// rootAbsPath itself is a symbolic link, its target will be walked.
func WalkDir(system System, rootAbsPath AbsPath, walkFn func(absPath AbsPath, info fs.FileInfo, err error) error) error {
return fs.WalkDir(system.UnderlyingFS(), string(rootAbsPath), func(path string, dirEntry fs.DirEntry, err error) error {
var info fs.FileInfo
if err == nil {
info, err = dirEntry.Info()
}
return walkFn(AbsPath(path), info, err)
})
}
11 changes: 11 additions & 0 deletions internal/cmd/testdata/scripts/edgecases.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,14 @@ chezmoi state dump
chezmoi apply $HOME${/}.file
chezmoi state dump
stdout 2e9dd6a2a8c15b20d4b0882d4c0fb8c7eea4e8ece46818090b387132f9f84c34 # sha256sum of "# contents of .file\n# edited\n"

# test that the source directory can be a symlink to another directory
chhome home2/user
symlink $HOME/.chezmoi -> $CHEZMOISOURCEDIR
chezmoi apply --source=$HOME${/}.chezmoi
cmp $HOME/.file golden/.file

-- golden/.file --
# contents of .file
-- home2/user/.local/share/chezmoi/dot_file --
# contents of .file
2 changes: 1 addition & 1 deletion internal/cmd/unmanagedcmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func (c *Config) newUnmanagedCmd() *cobra.Command {

func (c *Config) runUnmanagedCmd(cmd *cobra.Command, args []string, sourceState *chezmoi.SourceState) error {
sb := strings.Builder{}
if err := chezmoi.Walk(c.destSystem, c.DestDirAbsPath, func(destAbsPath chezmoi.AbsPath, info fs.FileInfo, err error) error {
if err := chezmoi.WalkDir(c.destSystem, c.DestDirAbsPath, func(destAbsPath chezmoi.AbsPath, info fs.FileInfo, err error) error {
if err != nil {
return err
}
Expand Down

0 comments on commit 19500e0

Please sign in to comment.