-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
174 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
doe |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
package utils | ||
|
||
import ( | ||
"io" | ||
"net/http" | ||
"os" | ||
pathpkg "path" | ||
"path/filepath" | ||
"sort" | ||
) | ||
|
||
// Walk walks the filesystem rooted at root, calling walkFn for each file or | ||
// directory in the filesystem, including root. All errors that arise visiting files | ||
// and directories are filtered by walkFn. The files are walked in lexical | ||
// order. | ||
func Walk(fs http.FileSystem, root string, walkFn filepath.WalkFunc) error { | ||
info, err := stat(fs, root) | ||
if err != nil { | ||
return walkFn(root, nil, err) | ||
} | ||
return walk(fs, root, info, walkFn) | ||
} | ||
|
||
// #nosec G304 | ||
// ReadFile returns the raw content of a file | ||
func ReadFile(path string, fs http.FileSystem) ([]byte, error) { | ||
if fs != nil { | ||
file, err := fs.Open(path) | ||
if err != nil { | ||
return nil, err | ||
} | ||
defer file.Close() | ||
return io.ReadAll(file) | ||
} | ||
return os.ReadFile(path) | ||
} | ||
|
||
// readDirNames reads the directory named by dirname and returns | ||
// a sorted list of directory entries. | ||
func readDirNames(fs http.FileSystem, dirname string) ([]string, error) { | ||
fis, err := readDir(fs, dirname) | ||
if err != nil { | ||
return nil, err | ||
} | ||
names := make([]string, len(fis)) | ||
for i := range fis { | ||
names[i] = fis[i].Name() | ||
} | ||
sort.Strings(names) | ||
return names, nil | ||
} | ||
|
||
// walk recursively descends path, calling walkFn. | ||
func walk(fs http.FileSystem, path string, info os.FileInfo, walkFn filepath.WalkFunc) error { | ||
err := walkFn(path, info, nil) | ||
if err != nil { | ||
if info.IsDir() && err == filepath.SkipDir { | ||
return nil | ||
} | ||
return err | ||
} | ||
|
||
if !info.IsDir() { | ||
return nil | ||
} | ||
|
||
names, err := readDirNames(fs, path) | ||
if err != nil { | ||
return walkFn(path, info, err) | ||
} | ||
|
||
for _, name := range names { | ||
filename := pathpkg.Join(path, name) | ||
fileInfo, err := stat(fs, filename) | ||
if err != nil { | ||
if err := walkFn(filename, fileInfo, err); err != nil && err != filepath.SkipDir { | ||
return err | ||
} | ||
} else { | ||
err = walk(fs, filename, fileInfo, walkFn) | ||
if err != nil { | ||
if !fileInfo.IsDir() || err != filepath.SkipDir { | ||
return err | ||
} | ||
} | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
// readDir reads the contents of the directory associated with file and | ||
// returns a slice of FileInfo values in directory order. | ||
func readDir(fs http.FileSystem, name string) ([]os.FileInfo, error) { | ||
f, err := fs.Open(name) | ||
if err != nil { | ||
return nil, err | ||
} | ||
defer f.Close() | ||
return f.Readdir(0) | ||
} | ||
|
||
// stat returns the FileInfo structure describing file. | ||
func stat(fs http.FileSystem, name string) (os.FileInfo, error) { | ||
f, err := fs.Open(name) | ||
if err != nil { | ||
return nil, err | ||
} | ||
defer f.Close() | ||
return f.Stat() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package utils | ||
|
||
import ( | ||
"io/fs" | ||
"net/http" | ||
"os" | ||
"testing" | ||
) | ||
|
||
func Test_ReadFile(t *testing.T) { | ||
t.Parallel() | ||
|
||
testFS := http.FS(os.DirFS(".github/tests")) | ||
file, err := ReadFile("john.txt", testFS) | ||
|
||
AssertEqual(t, string(file), "doe\n") | ||
AssertEqual(t, err, nil) | ||
} | ||
|
||
func Test_Walk(t *testing.T) { | ||
t.Parallel() | ||
|
||
type file struct { | ||
path string | ||
name string | ||
isDir bool | ||
} | ||
var files []file | ||
|
||
neededResults := []file{ | ||
{ | ||
path: "example", | ||
name: "example", | ||
isDir: true, | ||
}, | ||
{ | ||
path: "example/example1.txt", | ||
name: "example1.txt", | ||
isDir: false, | ||
}, | ||
{ | ||
path: "john.txt", | ||
name: "john.txt", | ||
isDir: false, | ||
}, | ||
} | ||
|
||
testFS := http.FS(os.DirFS(".github/tests")) | ||
err := Walk(testFS, ".", func(path string, info fs.FileInfo, err error) error { | ||
if path != "." { | ||
files = append(files, file{ | ||
path: path, | ||
name: info.Name(), | ||
isDir: info.IsDir(), | ||
}) | ||
} | ||
|
||
return nil | ||
}) | ||
|
||
AssertEqual(t, err, nil) | ||
AssertEqual(t, files, neededResults) | ||
} |