diff options
author | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2016-07-10 19:37:27 +0200 |
---|---|---|
committer | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2016-09-11 20:00:38 +0200 |
commit | 364e69ab7f54ab7a9901644647125f21cd39e98c (patch) | |
tree | dcc48331b2a7d14c885696bfc5b844a206be0bad /helpers/path.go | |
parent | e70cf1ace45498366d029e699af39441fab6bd0f (diff) |
Handle symlink change event
Hugo 0.16 announced support for symbolic links for the root folders, /content, /static etc., but this got broken pretty fast.
The main problem this commit tries to solve is the matching of file change events to "what changed".
An example:
ContentDir: /mysites/site/content where /mysites/site/content is a symlink to /mycontent
/mycontent:
/mypost1.md
/post/mypost2.md
* A change to mypost1.md (on OS X) will trigger a file change event with name "/mycontent/mypost1.md"
* A change to mypost2.md gives event with name "/mysites/site/content/mypost2.md"
The first change will not trigger a correct update of Hugo before this commit. This commit fixes this by doing a two-step check:
1. Check if "/mysites/site/content/mypost2.md" is within /mysites/site/content
2. Check if "/mysites/site/content/mypost2.md" is within the real path that /mysites/site/content points to
Fixes #2265
Closes #2273
Diffstat (limited to 'helpers/path.go')
-rw-r--r-- | helpers/path.go | 40 |
1 files changed, 37 insertions, 3 deletions
diff --git a/helpers/path.go b/helpers/path.go index a8a50aab3..478512efa 100644 --- a/helpers/path.go +++ b/helpers/path.go @@ -481,17 +481,17 @@ func SymbolicWalk(fs afero.Fs, root string, walker filepath.WalkFunc) error { } // Handle the root first - fileInfo, err := lstatIfOs(fs, root) + fileInfo, realPath, err := getRealFileInfo(fs, root) if err != nil { return walker(root, nil, err) } if !fileInfo.IsDir() { - return nil + return fmt.Errorf("Cannot walk regular file %s", root) } - if err := walker(root, fileInfo, err); err != nil && err != filepath.SkipDir { + if err := walker(realPath, fileInfo, err); err != nil && err != filepath.SkipDir { return err } @@ -511,6 +511,40 @@ func SymbolicWalk(fs afero.Fs, root string, walker filepath.WalkFunc) error { } +func getRealFileInfo(fs afero.Fs, path string) (os.FileInfo, string, error) { + fileInfo, err := lstatIfOs(fs, path) + realPath := path + + if err != nil { + return nil, "", err + } + + if fileInfo.Mode()&os.ModeSymlink == os.ModeSymlink { + link, err := filepath.EvalSymlinks(path) + if err != nil { + return nil, "", fmt.Errorf("Cannot read symbolic link '%s', error was: %s", path, err) + } + fileInfo, err = lstatIfOs(fs, link) + if err != nil { + return nil, "", fmt.Errorf("Cannot stat '%s', error was: %s", link, err) + } + realPath = link + } + return fileInfo, realPath, nil +} + +// GetRealPath returns the real file path for the given path, whether it is a +// symlink or not. +func GetRealPath(fs afero.Fs, path string) (string, error) { + _, realPath, err := getRealFileInfo(fs, path) + + if err != nil { + return "", err + } + + return realPath, nil +} + // Code copied from Afero's path.go // if the filesystem is OsFs use Lstat, else use fs.Stat func lstatIfOs(fs afero.Fs, path string) (info os.FileInfo, err error) { |