diff --git a/pkg/ioutils/filepath.go b/pkg/ioutils/filepath.go index 1ba433601..d0ef305e3 100644 --- a/pkg/ioutils/filepath.go +++ b/pkg/ioutils/filepath.go @@ -46,45 +46,37 @@ func FTW(root string, walkFn FTWFunc) error { return walk(root, info, walkFn) } -// getRealName - gets the proper filename for sorting purposes -// Readdir() filters out directory names without separators, add -// them back for proper sorting results. -func getRealName(info os.FileInfo) string { - if info.IsDir() { - // Make sure directory has its end separator. - return info.Name() + string(os.PathSeparator) +// byName implements sort.Interface for sorting os.FileInfo list. +type byName []os.FileInfo + +func (f byName) Len() int { return len(f) } +func (f byName) Swap(i, j int) { f[i], f[j] = f[j], f[i] } +func (f byName) Less(i, j int) bool { + n1 := f[i].Name() + if f[i].IsDir() { + n1 = n1 + string(os.PathSeparator) } - return info.Name() -} -// readDirNames reads the directory named by dirname and returns -// a sorted list of directory entries. -func readDirNames(dirname string) ([]string, error) { - names, err := readDirUnsortedNames(dirname) - if err != nil { - return nil, err + n2 := f[j].Name() + if f[i].IsDir() { + n2 = n2 + string(os.PathSeparator) } - sort.Strings(names) - return names, nil + + return n1 < n2 } -func readDirUnsortedNames(dirname string) ([]string, error) { +// readDir reads the directory named by dirname and returns +// a sorted list of directory entries. +func readDir(dirname string) (fi []os.FileInfo, err error) { f, err := os.Open(dirname) - if err != nil { - return nil, err - } - nameInfos, err := f.Readdir(-1) - if err != nil { - return nil, err - } - if err = f.Close(); err != nil { - return nil, err - } - var names []string - for _, nameInfo := range nameInfos { - names = append(names, getRealName(nameInfo)) + if err == nil { + defer f.Close() + if fi, err = f.Readdir(-1); fi != nil { + sort.Sort(byName(fi)) + } } - return names, nil + + return } // FTWFunc is the type of the function called for each file or directory @@ -125,13 +117,12 @@ func walk(path string, info os.FileInfo, walkFn FTWFunc) error { return nil } - names, err := readDirNames(path) + fis, err := readDir(path) if err != nil { return walkFn(path, info, err) } - for _, name := range names { - filename := filepath.Join(path, name) - fileInfo, err := os.Lstat(filename) + for _, fileInfo := range fis { + filename := filepath.Join(path, fileInfo.Name()) if err != nil { if err := walkFn(filename, fileInfo, err); err != nil && err != ErrSkipDir && err != ErrSkipFile { return err