-
Notifications
You must be signed in to change notification settings - Fork 0
Fix dogfood detector edge cases #184
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,7 +4,10 @@ import ( | |
| "bytes" | ||
| "context" | ||
| "fmt" | ||
| "os" | ||
| "path/filepath" | ||
| "regexp" | ||
| "strconv" | ||
| "strings" | ||
| "time" | ||
|
|
||
|
|
@@ -37,7 +40,19 @@ func (d NativeDetector) Ready() bool { | |
|
|
||
| // Applicable reports whether sbt build files are present. | ||
| func (d NativeDetector) Applicable(ctx context.Context, req sdk.DetectionRequest) (bool, error) { | ||
| return (Detector{WorkingDir: d.workingDir(req.ProjectPath)}).Applicable(ctx, req) | ||
| workingDir := d.workingDir(req.ProjectPath) | ||
| applicable, err := (Detector{WorkingDir: workingDir}).Applicable(ctx, req) | ||
| if err != nil || !applicable { | ||
| return applicable, err | ||
| } | ||
| if requiresDependencyGraphPlugin(workingDir) && !hasDependencyGraphPlugin(workingDir) { | ||
| d.logger().Debug("sbt native detector skipped: dependencyTree task is unavailable for this sbt version", | ||
| zap.String("working_dir", workingDir), | ||
| zap.String("sbt_version", sbtVersion(workingDir)), | ||
| ) | ||
| return false, nil | ||
| } | ||
| return true, nil | ||
| } | ||
|
|
||
| // Descriptor describes the sbt native detector. | ||
|
|
@@ -99,6 +114,68 @@ func (d NativeDetector) logger() *zap.Logger { | |
| return zap.NewNop() | ||
| } | ||
|
|
||
| func requiresDependencyGraphPlugin(workingDir string) bool { | ||
| version := sbtVersion(workingDir) | ||
| if version == "" { | ||
| return false | ||
| } | ||
| major, minor, ok := parseSBTMajorMinor(version) | ||
| if !ok { | ||
| return false | ||
| } | ||
| return major == 0 || (major == 1 && minor < 4) | ||
| } | ||
|
|
||
| func sbtVersion(workingDir string) string { | ||
| raw, err := os.ReadFile(filepath.Join(workingDir, "project", "build.properties")) | ||
| if err != nil { | ||
| return "" | ||
| } | ||
| for _, line := range strings.Split(string(raw), "\n") { | ||
| key, value, ok := strings.Cut(line, "=") | ||
| if !ok { | ||
| continue | ||
| } | ||
| if strings.TrimSpace(key) == "sbt.version" { | ||
| return strings.TrimSpace(value) | ||
| } | ||
| } | ||
| return "" | ||
| } | ||
|
|
||
| func parseSBTMajorMinor(version string) (int, int, bool) { | ||
| parts := strings.Split(strings.TrimSpace(version), ".") | ||
| if len(parts) < 2 { | ||
| return 0, 0, false | ||
| } | ||
| major, err := strconv.Atoi(parts[0]) | ||
| if err != nil { | ||
| return 0, 0, false | ||
| } | ||
| minor, err := strconv.Atoi(parts[1]) | ||
| if err != nil { | ||
| return 0, 0, false | ||
| } | ||
| return major, minor, true | ||
| } | ||
|
|
||
| func hasDependencyGraphPlugin(workingDir string) bool { | ||
| for _, name := range []string{ | ||
| filepath.Join("project", "plugins.sbt"), | ||
| filepath.Join("project", "build.sbt"), | ||
| "build.sbt", | ||
| } { | ||
| raw, err := os.ReadFile(filepath.Join(workingDir, name)) | ||
| if err != nil { | ||
| continue | ||
| } | ||
| if strings.Contains(string(raw), "sbt-dependency-graph") { | ||
| return true | ||
|
Comment on lines
+162
to
+173
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Plugin detection is too broad and can false-positive on comments/text. At Line 172, Suggested change+var sbtDependencyGraphPluginDecl = regexp.MustCompile(`(?m)^\s*addSbtPlugin\([^)\n]*"sbt-dependency-graph"`)
+
func hasDependencyGraphPlugin(workingDir string) bool {
for _, name := range []string{
filepath.Join("project", "plugins.sbt"),
filepath.Join("project", "build.sbt"),
"build.sbt",
} {
raw, err := os.ReadFile(filepath.Join(workingDir, name))
if err != nil {
continue
}
- if strings.Contains(string(raw), "sbt-dependency-graph") {
+ if sbtDependencyGraphPluginDecl.Match(raw) {
return true
}
}
return false
}🤖 Prompt for AI Agents |
||
| } | ||
| } | ||
| return false | ||
| } | ||
|
|
||
| // sbtDepTreeLinePattern matches a dependency line from sbt dependencyTree. | ||
| // Examples: | ||
| // | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move fake Gradle binary setup into shared
TestMainfixtures.Line 233-Line 237 create a fake Gradle executable inline; this should be centralized in the shared
TestMainfake-binary setup to keep fixture behavior consistent across detector tests.As per coding guidelines, "Fake binaries (npm, go, Gradle, plugin) must be built in
TestMain— seeinternal/cli/root_test_main_test.go."🤖 Prompt for AI Agents
Source: Coding guidelines