func TestIsIgnoredFile(t *testing.T) { home := osutil.HomeDir() fullpath := filepath.Join(home, "Downloads", "pony.jpg") var wantIgnored = map[string]bool{ filepath.Join(home, filepath.FromSlash("Downloads/pony.jpg")): true, filepath.Join(home, filepath.FromSlash("Downloads/pony.*")): true, filepath.Join(home, filepath.FromSlash("Downloads/*.jpg")): true, filepath.Join(home, filepath.FromSlash("Downloads/*")): true, "*.jpg": true, "pony.*": true, "*.foo": false, "foo.*": false, filepath.Join(home, "Downloads"): true, filepath.Join(home, "Down"): false, filepath.FromSlash("~/Downloads/pony.jpg"): true, filepath.FromSlash("~/Downloads/pony.*"): true, filepath.FromSlash("~/Downloads/*.jpg"): true, filepath.FromSlash("~/Downloads"): true, filepath.FromSlash("~/Down"): false, filepath.FromSlash("~/DownloadsAndMore"): false, home: true, "Downloads": true, "Down": false, } for pattern, want := range wantIgnored { ignoreChecker := newIgnoreChecker([]string{pattern}) if ignoreChecker(fullpath) != want { t.Errorf("%v not ignored; did not match %v", fullpath, pattern) } } }
// newIgnoreChecker uses ignoredFiles to build and return a func that returns whether the file path argument should be ignored. See IsIgnoredFile for the ignore rules. func newIgnoreChecker(ignoredFiles []string) func(path string) (shouldIgnore bool) { var fns []func(string) bool home := osutil.HomeDir() // copy of ignoredFiles for us to mutate ignFiles := append([]string(nil), ignoredFiles...) for k, v := range ignFiles { if strings.HasPrefix(v, filepath.FromSlash("~/")) { ignFiles[k] = filepath.Join(home, v[2:]) } } // We cache the ignoredFiles patterns in 3 categories (not necessarily exclusive): // 1) shell patterns // 3) absolute paths // 4) paths components for _, pattern := range ignFiles { _, err := filepath.Match(pattern, "whatever") if err == nil { fns = append(fns, func(v string) bool { return isShellPatternMatch(pattern, v) }) } } for _, pattern := range ignFiles { if filepath.IsAbs(pattern) { fns = append(fns, func(v string) bool { return hasDirPrefix(filepath.Clean(pattern), v) }) } else { fns = append(fns, func(v string) bool { return hasComponent(filepath.Clean(pattern), v) }) } } return func(path string) bool { for _, fn := range fns { if fn(path) { return true } } return false } }