Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions utils/file_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
package utils

import (
"errors"
"fmt"
"io/fs"
"os"
"path/filepath"
Expand All @@ -30,14 +32,20 @@ func NewFileDirReader(fileDir string, recursive bool, maxDepth int) (*StringArra
var filePaths []string
rootDepth := pathDepth(fileDir)

var errs []error

// filePaths is safely appended within WalkDir because WalkDir executes the callback sequentially.
// No race conditions occur in this implementation, even with slice reallocation.
err := filepath.WalkDir(fileDir, func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
errs = append(errs, fmt.Errorf("%s: %w", path, err))
if d != nil && d.IsDir() {
return fs.SkipDir
}
return nil
}

if !d.IsDir() {
if d != nil && !d.IsDir() {
filePaths = append(filePaths, path)
return nil
}
Expand All @@ -54,9 +62,10 @@ func NewFileDirReader(fileDir string, recursive bool, maxDepth int) (*StringArra
})

if err != nil {
return nil, err
errs = append(errs, err)
}
return &StringArrayReader{strings: filePaths}, nil

return &StringArrayReader{strings: filePaths}, errors.Join(errs...)
}

// pathDepth returns the depth of a given path by counting its components.
Expand Down
39 changes: 35 additions & 4 deletions utils/file_utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,22 +169,53 @@ func Test_NewFileDirReader_Error(t *testing.T) {
t.Parallel()

rootDir := t.TempDir()
noPerm := os.FileMode(0000)
if err := os.WriteFile(filepath.Join(rootDir, "a.txt"), []byte("hello world!"), noPerm); err != nil {
rwxPerm := os.FileMode(0755)
if err := os.WriteFile(filepath.Join(rootDir, "a.txt"), []byte("hello world!"), rwxPerm); err != nil {
t.Fatalf("unexpected error while WriteFile %v", err)
}
if err := os.WriteFile(filepath.Join(rootDir, "z.txt"), []byte("hello world!"), rwxPerm); err != nil {
t.Fatalf("unexpected error while WriteFile %v", err)
}
path := filepath.Join(rootDir, "sub")
noPerm := os.FileMode(0000)
if err := os.Mkdir(path, noPerm); err != nil {
t.Fatalf("unexpected error while Mkdir %v", err)
}
_, err := NewFileDirReader(rootDir, false, 10)

path = filepath.Join(rootDir, "sub_2")
if err := os.Mkdir(path, rwxPerm); err != nil {
t.Fatalf("unexpected error while Mkdir %v", err)
}

if err := os.WriteFile(filepath.Join(path, "www.txt"), []byte("hello world!"), rwxPerm); err != nil {
t.Fatalf("unexpected error while WriteFile %v", err)
}

sr, err := NewFileDirReader(rootDir, false, 10)
if err != nil {
t.Errorf("unexpected error while NewFileDirReader err:%v", err)
}
_, err = NewFileDirReader(rootDir, true, 10)

sr, err = NewFileDirReader(rootDir, true, 10)
if !strings.Contains(err.Error(), "permission denied") {
t.Errorf("unexpected error permissions denied message got:%v", err.Error())
}

if diff := cmp.Diff(
&StringArrayReader{
strings: []string{
filepath.Join(rootDir, "a.txt"),
// note we are ignoring, and not getting back sub permission denied directory
filepath.Join(rootDir, "sub_2/www.txt"),
filepath.Join(rootDir, "z.txt"),
},
},
sr,
cmp.AllowUnexported(StringArrayReader{}),
); diff != "" {
t.Errorf("unexpected StringArrayReader mismatch (-want +got):\n%s", diff)
}

}

func Test_pathDepth(t *testing.T) {
Expand Down