Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed wrong root identification in module detection #179

15 changes: 14 additions & 1 deletion utils/techutils/techutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -496,13 +496,26 @@ func getExistingRootDir(path string, workingDirectoryToIndicators map[string][]s
for wd := range workingDirectoryToIndicators {
parentWd := filepath.Dir(wd)
parentRoot := filepath.Dir(root)
if parentRoot != parentWd && strings.HasPrefix(root, wd) {
if parentRoot != parentWd && hasCompletePathPrefix(root, wd) {
root = wd
}
}
return
}

// This functions checks if wd is a PATH prefix for root. Examples:
// root = dir1/dir2/dir3 | wd = dir1/dir --> false (wd is prefix to root, but is not actually a valid part of its path)
// root = dir1/dir2/dir3 | wd = dir1/dir2 --> true
func hasCompletePathPrefix(root, wd string) bool {
if !strings.HasPrefix(root, wd) {
return false
}
rootParts := strings.Split(root, string(filepath.Separator))
wdParts := strings.Split(wd, string(filepath.Separator))
idxToCheck := len(wdParts) - 1
return rootParts[idxToCheck] == wdParts[idxToCheck]
}

// DetectedTechnologiesToSlice returns a string slice that includes all the names of the detected technologies.
func DetectedTechnologiesToSlice(detected map[Technology]map[string][]string) []string {
keys := make([]string, 0, len(detected))
Expand Down
55 changes: 55 additions & 0 deletions utils/techutils/techutils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,17 @@ func TestGetExistingRootDir(t *testing.T) {
},
expected: "directory",
},
{
// This test case checks that we capture the correct root when sub is a prefix to root, but not an actual path prefix
// Example: root = "dir1/dir2", sub = "dir" -> root indeed starts with 'dir' but 'dir' is not a path prefix to the root
name: "match root when root's letters start with sub's letters",
path: filepath.Join("dir3", "dir"),
workingDirectoryToIndicators: map[string][]string{
filepath.Join("dir3", "dir"): {filepath.Join("dir3", "dir", "package.json")},
"dir": {filepath.Join("dir", "package.json")},
},
expected: filepath.Join("dir3", "dir"),
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
Expand All @@ -298,6 +309,39 @@ func TestGetExistingRootDir(t *testing.T) {
}
}

func TestHasCompletePathPrefix(t *testing.T) {
tests := []struct {
name string
root string
wd string
expected bool
}{
{
name: "no prefix",
root: filepath.Join("dir1", "dir2"),
wd: filepath.Join("some", "other", "project"),
expected: false,
},
{
name: "prefix but not a path prefix",
root: filepath.Join("dir1", "dir2"),
wd: "dir",
expected: false,
},
{
name: "path prefix",
root: filepath.Join("dir1", "dir2"),
wd: "dir1",
expected: true,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
assert.Equal(t, test.expected, hasCompletePathPrefix(test.root, test.wd))
})
}
}

func TestCleanSubDirectories(t *testing.T) {
tests := []struct {
name string
Expand Down Expand Up @@ -531,6 +575,17 @@ func TestGetTechInformationFromWorkingDir(t *testing.T) {
"dir4": {filepath.Join("dir4", "package.json")},
},
},
{
name: "pnpmTestWithProvidedTechFromUser",
tech: Pnpm,
requestedDescriptors: make(map[Technology][]string),
techProvidedByUser: true,
expected: map[string][]string{
filepath.Join("dir3", "dir"): {filepath.Join("dir3", "dir", "package.json")},
"dir": {filepath.Join("dir", "package.json")},
"dir4": {filepath.Join("dir4", "package.json")},
},
},
}

for _, test := range tests {
Expand Down
Loading