Removed Chdir from util.FindFilterFiles
Signed-off-by: Jonathon Anderson <janderson@ciq.com>
This commit is contained in:
@@ -183,82 +183,100 @@ func FindFilterFiles(
|
||||
ignorePattern []string,
|
||||
ignore_xdev bool) (ofiles []string, err error) {
|
||||
wwlog.Debug("Finding files: %s include: %s ignore: %s", path, includePattern, ignorePattern)
|
||||
// preprocess patterns to remove leading (and trailing) /, as we are handling relative paths
|
||||
|
||||
// Preprocess patterns to remove leading (and trailing) /, as we are handling relative paths
|
||||
for i, pattern := range ignorePattern {
|
||||
ignorePattern[i] = strings.Trim(pattern, "/")
|
||||
}
|
||||
cwd, err := os.Getwd()
|
||||
|
||||
// Convert the base path to an absolute path
|
||||
absPath, err := filepath.Abs(path)
|
||||
if err != nil {
|
||||
return ofiles, err
|
||||
return ofiles, fmt.Errorf("failed to resolve absolute path: %s: %w", path, err)
|
||||
}
|
||||
defer func() {
|
||||
err = FirstError(err, os.Chdir(cwd))
|
||||
}()
|
||||
err = os.Chdir(path)
|
||||
if err != nil {
|
||||
return ofiles, fmt.Errorf("failed to change path: %s: %w", path, err)
|
||||
}
|
||||
// expand our include list as fspath.Match with /foo/* would catch /foo/baar but
|
||||
// not /foo/baar/sibling
|
||||
|
||||
// Expand the include list
|
||||
var globedInclude []string
|
||||
for _, include := range includePattern {
|
||||
globed, err := filepath.Glob(include)
|
||||
globed, err := filepath.Glob(filepath.Join(absPath, include))
|
||||
if err != nil {
|
||||
return ofiles, err
|
||||
return ofiles, fmt.Errorf("failed to glob pattern %s: %w", include, err)
|
||||
}
|
||||
globedInclude = append(globedInclude, globed...)
|
||||
}
|
||||
|
||||
var dev uint64
|
||||
if ignore_xdev {
|
||||
wwlog.Debug("Ignoring cross-device (xdev) files")
|
||||
pathStat, err := os.Stat(absPath)
|
||||
if err != nil {
|
||||
return ofiles, fmt.Errorf("failed to stat base path: %s: %w", absPath, err)
|
||||
}
|
||||
dev = pathStat.Sys().(*syscall.Stat_t).Dev
|
||||
}
|
||||
|
||||
path_stat, err := os.Stat(".")
|
||||
if err != nil {
|
||||
return ofiles, err
|
||||
}
|
||||
|
||||
dev := path_stat.Sys().(*syscall.Stat_t).Dev
|
||||
for _, inc := range globedInclude {
|
||||
wwlog.Debug("inc %s", inc)
|
||||
wwlog.Debug("Processing include pattern: %s", inc)
|
||||
stat, err := os.Lstat(inc)
|
||||
if err != nil {
|
||||
return ofiles, err
|
||||
return ofiles, fmt.Errorf("failed to stat include: %s: %w", inc, err)
|
||||
}
|
||||
|
||||
if stat.IsDir() {
|
||||
// get the rest of dir
|
||||
// Walk the directory
|
||||
err = filepath.WalkDir(inc, func(location string, info fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if location == "." {
|
||||
|
||||
relPath, relErr := filepath.Rel(absPath, location)
|
||||
if relErr != nil {
|
||||
wwlog.Warn("Error computing relative path for %s: %v", location, relErr)
|
||||
return relErr
|
||||
}
|
||||
|
||||
if relPath == "." {
|
||||
return nil
|
||||
}
|
||||
|
||||
fsInfo, err := info.Info()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ignore_xdev && fsInfo.Sys().(*syscall.Stat_t).Dev != dev {
|
||||
wwlog.Debug("Ignored (cross-device): %s", location)
|
||||
return nil
|
||||
}
|
||||
for _, ignored_pat := range ignorePattern {
|
||||
if ignored, _ := filepath.Match(ignored_pat, location); ignored {
|
||||
wwlog.Debug("Ignored %s due to pattern %s", location, ignored_pat)
|
||||
return filepath.SkipDir
|
||||
|
||||
for _, ignoredPattern := range ignorePattern {
|
||||
if ignored, _ := filepath.Match(ignoredPattern, relPath); ignored {
|
||||
wwlog.Debug("Ignored %s due to pattern %s", relPath, ignoredPattern)
|
||||
if info.IsDir() {
|
||||
return filepath.SkipDir
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
ofiles = append(ofiles, location)
|
||||
|
||||
ofiles = append(ofiles, relPath)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return ofiles, err
|
||||
return ofiles, fmt.Errorf("error walking directory %s: %w", inc, err)
|
||||
}
|
||||
} else {
|
||||
ofiles = append(ofiles, inc)
|
||||
// Add the file directly
|
||||
relPath, relErr := filepath.Rel(absPath, inc)
|
||||
if relErr != nil {
|
||||
wwlog.Warn("Error computing relative path for %s: %v", inc, relErr)
|
||||
return ofiles, relErr
|
||||
}
|
||||
ofiles = append(ofiles, relPath)
|
||||
}
|
||||
}
|
||||
|
||||
return ofiles, err
|
||||
return ofiles, nil
|
||||
}
|
||||
|
||||
// ******************************************************************************
|
||||
|
||||
@@ -1,25 +1,13 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/warewulf/warewulf/internal/pkg/testenv"
|
||||
"github.com/warewulf/warewulf/internal/pkg/wwlog"
|
||||
)
|
||||
|
||||
func TryCreatePath(t *testing.T, elem ...string) {
|
||||
err := os.MkdirAll(filepath.Join(elem...), os.ModePerm)
|
||||
if err != nil {
|
||||
t.Errorf("Failed creating dir: %v", err)
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
func Test_FindFiles(t *testing.T) {
|
||||
var tests = map[string]struct {
|
||||
createFiles []string
|
||||
@@ -55,34 +43,52 @@ func Test_FindFiles(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_FindFilterFiles(t *testing.T) {
|
||||
wwlog.SetLogLevel(wwlog.DEBUG)
|
||||
dir, err := os.MkdirTemp(os.TempDir(), "warewulf-test")
|
||||
if err != nil {
|
||||
t.Errorf("Failed creating tmpdir: %v", err)
|
||||
t.FailNow()
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
TryCreatePath(t, dir, "boot")
|
||||
TryCreatePath(t, dir, "usr", "local")
|
||||
TryCreatePath(t, dir, "usr", "bin")
|
||||
TryCreatePath(t, dir, "usr", "usr", "local")
|
||||
TryCreatePath(t, dir, "bin")
|
||||
TryCreatePath(t, dir, "lib")
|
||||
|
||||
assert.NoError(t, os.Symlink("/path/to/target", filepath.Join(dir, "symlink")))
|
||||
|
||||
files, err := FindFilterFiles(dir, []string{"boot", "usr", "bin", "symlink"}, []string{"/b*/", "/usr/local"}, true)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("FindFilerFiles failed: %v", err)
|
||||
t.FailNow()
|
||||
var tests = map[string]struct {
|
||||
createFiles []string
|
||||
include []string
|
||||
exclude []string
|
||||
findFiles []string
|
||||
}{
|
||||
"no files": {
|
||||
createFiles: []string{},
|
||||
include: []string{"*"},
|
||||
findFiles: nil,
|
||||
},
|
||||
"single file": {
|
||||
createFiles: []string{"testfile"},
|
||||
include: []string{"*"},
|
||||
findFiles: []string{"testfile"},
|
||||
},
|
||||
"nested file": {
|
||||
createFiles: []string{"testdir/testfile"},
|
||||
include: []string{"*"},
|
||||
findFiles: []string{"testdir", "testdir/testfile"},
|
||||
},
|
||||
"multiple files": {
|
||||
createFiles: []string{"test1/testfile", "test2/testfile"},
|
||||
include: []string{"*"},
|
||||
findFiles: []string{"test1", "test1/testfile", "test2", "test2/testfile"},
|
||||
},
|
||||
"excluded files": {
|
||||
createFiles: []string{"test1/test1", "test1/test2", "test2/test1", "test2/test2"},
|
||||
include: []string{"*"},
|
||||
exclude: []string{"test1/*2", "test2"},
|
||||
findFiles: []string{"test1", "test1/test1"},
|
||||
},
|
||||
}
|
||||
|
||||
expected := []string{"usr", "usr/bin", "usr/usr", "usr/usr/local", "symlink"}
|
||||
sort.Strings(expected)
|
||||
sort.Strings(files)
|
||||
if !reflect.DeepEqual(files, expected) {
|
||||
t.Errorf("expected %v, got %v", expected, files)
|
||||
t.FailNow()
|
||||
for name, tt := range tests {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
env := testenv.New(t)
|
||||
defer env.RemoveAll(t)
|
||||
env.MkdirAll(t, "/test")
|
||||
for _, file_ := range tt.createFiles {
|
||||
env.CreateFile(t, filepath.Join("/test", file_))
|
||||
}
|
||||
|
||||
files, err := FindFilterFiles(env.GetPath("/test"), tt.include, tt.exclude, true)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tt.findFiles, files)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user