diff --git a/cmd/minify/main.go b/cmd/minify/main.go index 9e7641a05c..aeebc36093 100644 --- a/cmd/minify/main.go +++ b/cmd/minify/main.go @@ -4,6 +4,7 @@ import ( "bufio" "fmt" "io" + "io/fs" "io/ioutil" "log" "net/url" @@ -473,7 +474,7 @@ func sanitizePath(p string) string { } if isDir { p += "/" - } else if info, err := os.Lstat(p); err == nil && info.Mode().IsDir() && info.Mode()&os.ModeSymlink == 0 { + } else if info, err := os.Lstat(p); err == nil && info.Mode().IsDir() && info.Mode()&fs.ModeSymlink == 0 { p += "/" } if isCur { @@ -499,11 +500,23 @@ func fileMatches(filename string) bool { return true } +type DirEntry struct { + fs.FileInfo +} + +func (d DirEntry) Type() fs.FileMode { + return d.Mode().Type() +} + +func (d DirEntry) Info() (fs.FileInfo, error) { + return d.FileInfo, nil +} + func createTasks(inputs []string, output string) ([]Task, []string, error) { tasks := []Task{} roots := []string{} for _, input := range inputs { - var info os.FileInfo + var info fs.FileInfo var err error if !preserveSymlinks { info, err = os.Stat(input) @@ -514,7 +527,7 @@ func createTasks(inputs []string, output string) ([]Task, []string, error) { return nil, nil, err } - if info.Mode()&os.ModeSymlink != 0 { + if info.Mode()&fs.ModeSymlink != 0 { if !sync { Warning.Println("--sync not specified, omitting symbolic link", input) continue @@ -540,33 +553,33 @@ func createTasks(inputs []string, output string) ([]Task, []string, error) { } roots = append(roots, input) - var walkFn func(string, os.DirEntry, error) error - walkFn = func(path string, d os.DirEntry, err error) error { + var walkFn func(string, fs.DirEntry, error) error + walkFn = func(path string, d fs.DirEntry, err error) error { if err != nil { return err } else if d.Name() == "." || d.Name() == ".." { return nil } else if len(d.Name()) == 0 || !hidden && d.Name()[0] == '.' { if d.IsDir() { - return filepath.SkipDir + return fs.SkipDir } return nil } path = sanitizePath(path) - if !preserveSymlinks && d.Type()&os.ModeSymlink != 0 { + if !preserveSymlinks && d.Type()&fs.ModeSymlink != 0 { // follow and dereference symlinks info, err := os.Stat(path) if err != nil { return err } if info.IsDir() { - return WalkDir(input, path, walkFn) + return fs.WalkDir(os.DirFS(input), path, walkFn) } - d = &statDirEntry{info} + d = DirEntry{info} } - if preserveSymlinks && d.Type()&os.ModeSymlink != 0 { + if preserveSymlinks && d.Type()&fs.ModeSymlink != 0 { // copy symlinks as is if !sync { Warning.Println("--sync not specified, omitting symbolic link", path) @@ -589,7 +602,7 @@ func createTasks(inputs []string, output string) ([]Task, []string, error) { } return nil } - if err := WalkDir(".", input, walkFn); err != nil { + if err := fs.WalkDir(os.DirFS("."), input, walkFn); err != nil { return nil, nil, err } } else { @@ -656,7 +669,7 @@ func minify(t Task) bool { if t.sync { if t.srcs[0] == t.dst { return true - } else if info, err := os.Lstat(t.srcs[0]); preserveSymlinks && err == nil && info.Mode()&os.ModeSymlink != 0 { + } else if info, err := os.Lstat(t.srcs[0]); preserveSymlinks && err == nil && info.Mode()&fs.ModeSymlink != 0 { src, err := os.Readlink(t.srcs[0]) if err != nil { Error.Println(err) diff --git a/cmd/minify/walkdir.go b/cmd/minify/walkdir.go deleted file mode 100644 index 5cdc5eec41..0000000000 --- a/cmd/minify/walkdir.go +++ /dev/null @@ -1,119 +0,0 @@ -package main - -import ( - "os" - "path" - "path/filepath" -) - -// WalkDirFunc is the type of the function called by WalkDir to visit -// each file or directory. -// -// The path argument contains the argument to WalkDir as a prefix. -// That is, if WalkDir is called with root argument "dir" and finds a file -// named "a" in that directory, the walk function will be called with -// argument "dir/a". -// -// The d argument is the fs.DirEntry for the named path. -// -// The error result returned by the function controls how WalkDir -// continues. If the function returns the special value SkipDir, WalkDir -// skips the current directory (path if d.IsDir() is true, otherwise -// path's parent directory). Otherwise, if the function returns a non-nil -// error, WalkDir stops entirely and returns that error. -// -// The err argument reports an error related to path, signaling that -// WalkDir will not walk into that directory. The function can decide how -// to handle that error; as described earlier, returning the error will -// cause WalkDir to stop walking the entire tree. -// -// WalkDir calls the function with a non-nil err argument in two cases. -// -// First, if the initial fs.Stat on the root directory fails, WalkDir -// calls the function with path set to root, d set to nil, and err set to -// the error from fs.Stat. -// -// Second, if a directory's ReadDir method fails, WalkDir calls the -// function with path set to the directory's path, d set to an -// fs.DirEntry describing the directory, and err set to the error from -// ReadDir. In this second case, the function is called twice with the -// path of the directory: the first call is before the directory read is -// attempted and has err set to nil, giving the function a chance to -// return SkipDir and avoid the ReadDir entirely. The second call is -// after a failed ReadDir and reports the error from ReadDir. -// (If ReadDir succeeds, there is no second call.) -// -// The differences between WalkDirFunc compared to filepath.WalkFunc are: -// -// - The second argument has type fs.DirEntry instead of fs.FileInfo. -// - The function is called before reading a directory, to allow SkipDir -// to bypass the directory read entirely. -// - If a directory read fails, the function is called a second time -// for that directory to report the error. -// -type WalkDirFunc func(path string, d os.DirEntry, err error) error - -// walkDir recursively descends path, calling walkDirFn. -func walkDir(fsys string, name string, d os.DirEntry, walkDirFn WalkDirFunc) error { - if err := walkDirFn(name, d, nil); err != nil || !d.IsDir() { - if err == filepath.SkipDir && d.IsDir() { - // Successfully skipped directory. - err = nil - } - return err - } - - dirs, err := os.ReadDir(filepath.Join(fsys, name)) - if err != nil { - // Second call, to report ReadDir error. - err = walkDirFn(name, d, err) - if err != nil { - return err - } - } - - for _, d1 := range dirs { - name1 := path.Join(name, d1.Name()) - if err := walkDir(fsys, name1, d1, walkDirFn); err != nil { - if err == filepath.SkipDir { - break - } - return err - } - } - return nil -} - -// WalkDir walks the file tree rooted at root, calling fn for each file or -// directory in the tree, including root. -// -// All errors that arise visiting files and directories are filtered by fn: -// see the fs.WalkDirFunc documentation for details. -// -// The files are walked in lexical order, which makes the output deterministic -// but requires WalkDir to read an entire directory into memory before proceeding -// to walk that directory. -// -// WalkDir does not follow symbolic links found in directories, -// but if root itself is a symbolic link, its target will be walked. -func WalkDir(fsys string, root string, fn WalkDirFunc) error { - info, err := os.Stat(filepath.Join(fsys, root)) - if err != nil { - err = fn(root, nil, err) - } else { - err = walkDir(fsys, root, &statDirEntry{info}, fn) - } - if err == filepath.SkipDir { - return nil - } - return err -} - -type statDirEntry struct { - info os.FileInfo -} - -func (d *statDirEntry) Name() string { return d.info.Name() } -func (d *statDirEntry) IsDir() bool { return d.info.IsDir() } -func (d *statDirEntry) Type() os.FileMode { return d.info.Mode().Type() } -func (d *statDirEntry) Info() (os.FileInfo, error) { return d.info, nil } diff --git a/go.mod b/go.mod index 73f66006cf..1757659f38 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/tdewolff/minify/v2 -go 1.13 +go 1.16 require ( github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927 // indirect