diff --git a/ishidden.go b/ishidden.go new file mode 100644 index 0000000..0f242e8 --- /dev/null +++ b/ishidden.go @@ -0,0 +1,12 @@ +// +build !windows + +package watcher + +import ( + "path/filepath" + "strings" +) + +func isHiddenFile(path string) (bool, error) { + return strings.HasPrefix(filepath.Base(path), "."), nil +} diff --git a/ishidden_windows.go b/ishidden_windows.go new file mode 100644 index 0000000..306c6b7 --- /dev/null +++ b/ishidden_windows.go @@ -0,0 +1,21 @@ +// +build windows + +package watcher + +import ( + "syscall" +) + +func isHiddenFile(path string) (bool, error) { + pointer, err := syscall.UTF16PtrFromString(path) + if err != nil { + return false, err + } + + attributes, err := syscall.GetFileAttributes(pointer) + if err != nil { + return false, err + } + + return attributes&syscall.FILE_ATTRIBUTE_HIDDEN != 0, nil +} diff --git a/watcher.go b/watcher.go index 07ab8ea..e353296 100644 --- a/watcher.go +++ b/watcher.go @@ -197,7 +197,13 @@ func (w *Watcher) Add(name string) (err error) { // If name is on the ignored list or if hidden files are // ignored and name is a hidden file or directory, simply return. _, ignored := w.ignored[name] - if ignored || (w.ignoreHidden && strings.HasPrefix(name, ".")) { + + isHidden, err := isHiddenFile(name) + if err != nil { + return err + } + + if ignored || (w.ignoreHidden && isHidden) { return nil } @@ -244,7 +250,13 @@ outer: for _, fInfo := range fInfoList { path := filepath.Join(name, fInfo.Name()) _, ignored := w.ignored[path] - if ignored || (w.ignoreHidden && strings.HasPrefix(fInfo.Name(), ".")) { + + isHidden, err := isHiddenFile(path) + if err != nil { + return nil, err + } + + if ignored || (w.ignoreHidden && isHidden) { continue } @@ -308,7 +320,13 @@ func (w *Watcher) listRecursive(name string) (map[string]os.FileInfo, error) { // If path is ignored and it's a directory, skip the directory. If it's // ignored and it's a single file, skip the file. _, ignored := w.ignored[path] - if ignored || (w.ignoreHidden && strings.HasPrefix(info.Name(), ".")) { + + isHidden, err := isHiddenFile(path) + if err != nil { + return err + } + + if ignored || (w.ignoreHidden && isHidden) { if info.IsDir() { return filepath.SkipDir }