Skip to content
Merged
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
15 changes: 13 additions & 2 deletions search/files.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func readFileLines(path string) ([]string, error) {
return lines, nil
}

func readFiles(ctx context.Context, files chan<- file, workspace string) error {
func readFiles(ctx context.Context, files chan<- file, workspace, subdirectory string) error {
defer close(files)
ignoreFiles := []string{".gitignore", ".ignore", ".ldignore"}
allIgnores := newIgnore(workspace, ignoreFiles)
Expand Down Expand Up @@ -108,9 +108,20 @@ func readFiles(ctx context.Context, files chan<- file, workspace string) error {
return nil
}

files <- file{path: strings.TrimPrefix(path, workspace+"/"), lines: lines}
resolvedPath := resolvePath(path, workspace, subdirectory)

files <- file{path: resolvedPath, lines: lines}
return nil
}

return filepath.Walk(workspace, readFile)
}

func resolvePath(path, workspace, subdirectory string) string {
dir := workspace
if subdirectory != "" {
dir = strings.TrimSuffix(workspace, "/"+subdirectory)
}

return strings.TrimPrefix(path, dir+"/")
}
87 changes: 67 additions & 20 deletions search/files_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
func Test_readFiles(t *testing.T) {
t.Run("don't ignore .github by default", func(t *testing.T) {
files := make(chan file, 8)
err := readFiles(context.Background(), files, "testdata/include-github-files")
err := readFiles(context.Background(), files, "testdata/include-github-files", "")
require.NoError(t, err)
got := []file{}
for file := range files {
Expand All @@ -33,25 +33,72 @@ func Test_readFiles(t *testing.T) {
})

t.Run("explicitly ignore .github files", func(t *testing.T) {
files := make(chan file, 8)
err := readFiles(context.Background(), files, "testdata/exclude-github-files")
require.NoError(t, err)
got := []file{}
for file := range files {
got = append(got, file)
switch file.path {
case "fileWithNoRefs":
assert.Equal(t, []string{"fileWithNoRefs"}, file.lines)
case "fileWithRefs":
assert.Equal(t, testFile.lines, file.lines)
case "ignoredFiles/included":
assert.Equal(t, []string{"IGNORED BUT INCLUDED"}, file.lines)
case "symlink":
assert.Fail(t, "Should not read symlink contents")
default:
assert.Fail(t, "Read unexpected file", file)
t.Run("without subdirectory option", func(t *testing.T) {
files := make(chan file, 8)
err := readFiles(context.Background(), files, "testdata/exclude-github-files", "")
require.NoError(t, err)
got := []file{}
for file := range files {
got = append(got, file)
switch file.path {
case "fileWithNoRefs":
assert.Equal(t, []string{"fileWithNoRefs"}, file.lines)
case "fileWithRefs":
assert.Equal(t, testFile.lines, file.lines)
case "subdir/fileWithNoRefs":
assert.Equal(t, []string{"nope"}, file.lines)
case "subdir/fileWithRefs":
assert.Equal(t, testFileWithSubdir.lines, file.lines)
case "ignoredFiles/included":
assert.Equal(t, []string{"IGNORED BUT INCLUDED"}, file.lines)
case "symlink":
assert.Fail(t, "Should not read symlink contents")
default:
assert.Fail(t, "Read unexpected file", file)
}
}
}
assert.Len(t, got, 3, "Expected 3 valid files to have been found")
assert.Len(t, got, 5, "Expected 5 valid files to have been found")
})

t.Run("with subdirectory option", func(t *testing.T) {
files := make(chan file, 8)
err := readFiles(context.Background(), files, "testdata/exclude-github-files/subdir", "subdir")
require.NoError(t, err)
got := []file{}
for file := range files {
got = append(got, file)
switch file.path {
case "subdir/fileWithNoRefs":
assert.Equal(t, []string{"nope"}, file.lines)
case "subdir/fileWithRefs":
assert.Equal(t, testFileWithSubdir.lines, file.lines)
default:
assert.Fail(t, "Read unexpected file", file)
}
}
assert.Len(t, got, 2, "Expected 2 valid files to have been found")
})
})
}

func Test_resolvePath(t *testing.T) {
testCases := []struct{ name, path, workspace, subdirectory, expectedPath string }{{
name: "with subdirectory",
path: "/path/to/workspace/subdirectory/internal/file.txt",
workspace: "/path/to/workspace",
subdirectory: "subdirectory",
expectedPath: "subdirectory/internal/file.txt",
}, {
name: "without subdirectory",
path: "/path/to/workspace/file.txt",
workspace: "/path/to/workspace",
subdirectory: "",
expectedPath: "file.txt",
}}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
require.Equal(t, tc.expectedPath, resolvePath(tc.path, tc.workspace, tc.subdirectory))
})
}
}
2 changes: 1 addition & 1 deletion search/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func Scan(opts options.Options, repoParams ld.RepoParams, dir string) (Matcher,
searchDir = filepath.Join(dir, opts.Subdirectory)
}

refs, err := SearchForRefs(searchDir, matcher)
refs, err := SearchForRefs(searchDir, opts.Subdirectory, matcher)
if err != nil {
log.Error.Fatalf("error searching for flag key references: %s", err)
}
Expand Down
5 changes: 3 additions & 2 deletions search/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ func (f file) aggregateHunksForFlag(projKey, flagKey string, matcher Matcher, li
func (f file) toHunks(matcher Matcher) *ld.ReferenceHunksRep {
hunks := make([]ld.HunkRep, 0)
filteredMatchers := make([]ElementMatcher, 0)

for _, elementSearch := range matcher.Elements {
if elementSearch.Dir != "" {
matchDir := strings.HasPrefix(f.path, elementSearch.Dir)
Expand Down Expand Up @@ -192,15 +193,15 @@ func processFiles(ctx context.Context, files <-chan file, references chan<- ld.R
w.Wait()
}

func SearchForRefs(directory string, matcher Matcher) ([]ld.ReferenceHunksRep, error) {
func SearchForRefs(directory, subdirectory string, matcher Matcher) ([]ld.ReferenceHunksRep, error) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
files := make(chan file)
references := make(chan ld.ReferenceHunksRep)
// Start workers to process files asynchronously as they are written to the files channel
go processFiles(ctx, files, references, matcher)

err := readFiles(ctx, files, directory)
err := readFiles(ctx, files, directory, subdirectory)
if err != nil {
return nil, err
}
Expand Down
43 changes: 35 additions & 8 deletions search/search_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ var (
*withFlagKey(withAliases(makeHunkPtr(5, testFlag2Alias), testFlag2Alias), testFlagKey2),
}

testFileWithSubdir = file{
path: "subdir/fileWithRefs",
lines: []string{testFlagKey, testFlagKey2},
}

delimitedTestFlagKey = delimit(testFlagKey, `"`)
)

Expand Down Expand Up @@ -386,18 +391,40 @@ func Test_processFiles(t *testing.T) {

func Test_SearchForRefs(t *testing.T) {
os.Symlink("testdata/exclude-github-files/fileWithRefs", "testdata/exclude-github-files/symlink")
want := []ld.ReferenceHunksRep{{Path: testFile.path}}
matcher := Matcher{
ctxLines: 0,
}

matcher := Matcher{ctxLines: 0}
matcher.Elements = append(matcher.Elements,
NewElementMatcher("default", "", "", []string{testFlagKey, testFlagKey2}, nil),
)

t.Run("without subdirectory option finds both files", func(t *testing.T) {
actual, err := SearchForRefs("testdata/exclude-github-files", "", matcher)
require.NoError(t, err)
require.Len(t, actual, 2)

var foundFirst, foundSecond bool
for _, r := range actual {
switch r.Path {
case testFile.path:
foundFirst = true
case testFileWithSubdir.path:
foundSecond = true
default:
t.Fatal("found unexpected file " + r.Path)
}
}
require.True(t, foundFirst)
require.True(t, foundSecond)
})

t.Run("with subdirectory option finds only the file in the subdirectory", func(t *testing.T) {
actual, err := SearchForRefs("testdata/exclude-github-files/subdir", "subdir", matcher)
require.NoError(t, err)
require.Len(t, actual, 1)
require.Equal(t, testFileWithSubdir.path, actual[0].Path)
})

t.Cleanup(func() { os.Remove("testdata/exclude-github-files/symlink") })
got, err := SearchForRefs("testdata/exclude-github-files", matcher)
require.NoError(t, err)
require.Len(t, got, 1)
require.Equal(t, want[0].Path, got[0].Path)
}

func Test_truncateLine(t *testing.T) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nope
2 changes: 2 additions & 0 deletions search/testdata/exclude-github-files/subdir/fileWithRefs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
someFlag
anotherFlag
Loading