From 9e53e3a878f64a974f33589b6f3f1e84c38313c5 Mon Sep 17 00:00:00 2001 From: Aleksandr Nogikh Date: Thu, 31 Jul 2025 14:37:16 +0200 Subject: pkg/manager: remove a dependency on grep Instead of calling grep (the implementations of which may differ in different environments), traverse the directory and grep files with a special pkg/osutil helper functionality. --- pkg/osutil/fileutil.go | 27 +++++++++++++++++++++++++++ pkg/osutil/fileutil_test.go | 17 +++++++++++++++++ 2 files changed, 44 insertions(+) (limited to 'pkg/osutil') diff --git a/pkg/osutil/fileutil.go b/pkg/osutil/fileutil.go index cd5b602cf..01319bd5c 100644 --- a/pkg/osutil/fileutil.go +++ b/pkg/osutil/fileutil.go @@ -4,8 +4,10 @@ package osutil import ( + "bytes" "fmt" "io" + "io/fs" "os" "path/filepath" ) @@ -81,3 +83,28 @@ func WriteTempFile(data []byte) (string, error) { f.Close() return f.Name(), nil } + +// GrepFiles returns the list of files (relative to root) that include target. +// If ext is not empty, the files will be filtered by the extension. +// The function assumes that the files are not too big and may fit in memory. +func GrepFiles(root, ext string, target []byte) ([]string, error) { + var ret []string + err := filepath.WalkDir(root, func(path string, d fs.DirEntry, err error) error { + if err != nil { + return err + } + if d.IsDir() || filepath.Ext(path) != ext { + return nil + } + content, err := os.ReadFile(path) + if err != nil { + return fmt.Errorf("failed to open %s: %w", path, err) + } + if bytes.Contains(content, target) { + rel, _ := filepath.Rel(root, path) + ret = append(ret, rel) + } + return nil + }) + return ret, err +} diff --git a/pkg/osutil/fileutil_test.go b/pkg/osutil/fileutil_test.go index 33a450fda..7609ca83b 100644 --- a/pkg/osutil/fileutil_test.go +++ b/pkg/osutil/fileutil_test.go @@ -9,6 +9,9 @@ import ( "strconv" "sync" "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestProcessTempDir(t *testing.T) { @@ -60,3 +63,17 @@ func TestProcessTempDir(t *testing.T) { }() } } + +func TestGrepFiles(t *testing.T) { + dir := t.TempDir() + require.NoError(t, FillDirectory(dir, map[string]string{ + "a.c": `must be found`, + "a/b.c": `nested`, + "a/b/c.c": `even more nested, must be found`, + "a.txt": `must be found, but has a different extension`, + })) + + ret, err := GrepFiles(dir, ".c", []byte(`must be found`)) + require.NoError(t, err) + assert.ElementsMatch(t, []string{"a.c", "a/b/c.c"}, ret) +} -- cgit mrf-deployment