aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/osutil
diff options
context:
space:
mode:
authorAleksandr Nogikh <nogikh@google.com>2025-07-31 14:37:16 +0200
committerAleksandr Nogikh <nogikh@google.com>2025-08-05 13:17:38 +0000
commit9e53e3a878f64a974f33589b6f3f1e84c38313c5 (patch)
treea50198bc6857bcfc44aaca9a09e820b69859806f /pkg/osutil
parent1458b364e100752374725b0cbf83b70a54b327d3 (diff)
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.
Diffstat (limited to 'pkg/osutil')
-rw-r--r--pkg/osutil/fileutil.go27
-rw-r--r--pkg/osutil/fileutil_test.go17
2 files changed, 44 insertions, 0 deletions
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)
+}