From 1484fef945b543296a8333cc818542c252b1b5d8 Mon Sep 17 00:00:00 2001 From: Steve Elliott Date: Wed, 22 Apr 2026 14:56:08 -0400 Subject: [PATCH] Speed up ModuleHasDependency and RepositoryHasDependency by removing DependencyInsight Both recipes ran a fresh DependencyInsight visitor against every source file during scanning, which performs exhaustive Gradle + Maven dependency analysis just to answer a binary yes/no question about whether the module contains a given GAV. Replace the visitor with a direct check against MavenResolutionResult.findDependencies for Maven modules, and against GradleProject's configurations + ResolvedDependency.findDependency for Gradle modules. This mirrors the pattern Sam applied to the single-build-system versions of ModuleHasDependency in openrewrite/rewrite (commit 919c9f5 / PR #6664). These recipes are used as preconditions in many declarative migration recipes. Avoiding the DependencyInsight allocation + traversal per source file substantially reduces scanner time on repositories with many Java files. --- .../search/ModuleHasDependency.java | 43 +++++++++++++++-- .../search/RepositoryHasDependency.java | 48 +++++++++++++++---- 2 files changed, 78 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/openrewrite/java/dependencies/search/ModuleHasDependency.java b/src/main/java/org/openrewrite/java/dependencies/search/ModuleHasDependency.java index 842c0692..a2cd0c54 100644 --- a/src/main/java/org/openrewrite/java/dependencies/search/ModuleHasDependency.java +++ b/src/main/java/org/openrewrite/java/dependencies/search/ModuleHasDependency.java @@ -19,11 +19,18 @@ import lombok.Value; import org.jspecify.annotations.Nullable; import org.openrewrite.*; -import org.openrewrite.java.dependencies.DependencyInsight; +import org.openrewrite.gradle.marker.GradleDependencyConfiguration; +import org.openrewrite.gradle.marker.GradleProject; import org.openrewrite.java.marker.JavaProject; import org.openrewrite.marker.SearchResult; +import org.openrewrite.maven.tree.MavenResolutionResult; +import org.openrewrite.maven.tree.ResolvedDependency; +import org.openrewrite.maven.tree.Scope; +import org.openrewrite.semver.Semver; +import org.openrewrite.semver.VersionComparator; import java.util.HashSet; +import java.util.List; import java.util.Optional; import java.util.Set; @@ -87,10 +94,7 @@ public Tree visit(@Nullable Tree tree, ExecutionContext ctx) { tree.getMarkers() .findFirst(JavaProject.class) .ifPresent(jp -> { - Tree t = new DependencyInsight(groupIdPattern, artifactIdPattern, version, scope) - .getVisitor() - .visit(tree, ctx); - if (t != tree) { + if (hasDependency(tree)) { acc.add(jp); } }); @@ -99,6 +103,35 @@ public Tree visit(@Nullable Tree tree, ExecutionContext ctx) { }; } + private boolean hasDependency(Tree tree) { + VersionComparator versionComparator = version != null ? Semver.validate(version, null).getValue() : null; + + MavenResolutionResult mavenResult = tree.getMarkers().findFirst(MavenResolutionResult.class).orElse(null); + if (mavenResult != null) { + Scope requestedScope = scope == null ? null : Scope.fromName(scope); + List dependencies = mavenResult.findDependencies(groupIdPattern, artifactIdPattern, requestedScope); + for (ResolvedDependency dependency : dependencies) { + if (versionComparator == null || versionComparator.isValid(null, dependency.getVersion())) { + return true; + } + } + return false; + } + + GradleProject gp = tree.getMarkers().findFirst(GradleProject.class).orElse(null); + if (gp != null) { + for (GradleDependencyConfiguration c : gp.getConfigurations()) { + for (ResolvedDependency resolvedDependency : c.getDirectResolved()) { + ResolvedDependency found = resolvedDependency.findDependency(groupIdPattern, artifactIdPattern); + if (found != null && (versionComparator == null || versionComparator.isValid(null, found.getVersion()))) { + return true; + } + } + } + } + return false; + } + @Override public TreeVisitor getVisitor(Set acc) { return new TreeVisitor() { diff --git a/src/main/java/org/openrewrite/java/dependencies/search/RepositoryHasDependency.java b/src/main/java/org/openrewrite/java/dependencies/search/RepositoryHasDependency.java index 0b67f7a2..c3357780 100644 --- a/src/main/java/org/openrewrite/java/dependencies/search/RepositoryHasDependency.java +++ b/src/main/java/org/openrewrite/java/dependencies/search/RepositoryHasDependency.java @@ -19,10 +19,17 @@ import lombok.Value; import org.jspecify.annotations.Nullable; import org.openrewrite.*; -import org.openrewrite.java.dependencies.DependencyInsight; +import org.openrewrite.gradle.marker.GradleDependencyConfiguration; +import org.openrewrite.gradle.marker.GradleProject; import org.openrewrite.java.marker.JavaProject; import org.openrewrite.marker.SearchResult; +import org.openrewrite.maven.tree.MavenResolutionResult; +import org.openrewrite.maven.tree.ResolvedDependency; +import org.openrewrite.maven.tree.Scope; +import org.openrewrite.semver.Semver; +import org.openrewrite.semver.VersionComparator; +import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; @EqualsAndHashCode(callSuper = false) @@ -75,18 +82,14 @@ public TreeVisitor getScanner(AtomicBoolean acc) { return new TreeVisitor() { @Override public Tree visit(@Nullable Tree tree, ExecutionContext ctx) { - if(acc.get()) { - assert tree != null; + assert tree != null; + if (acc.get()) { return tree; } - assert tree != null; tree.getMarkers() .findFirst(JavaProject.class) .ifPresent(jp -> { - Tree t = new DependencyInsight(groupIdPattern, artifactIdPattern, scope, version) - .getVisitor() - .visit(tree, ctx); - if (t != tree) { + if (hasDependency(tree)) { acc.set(true); } }); @@ -95,6 +98,35 @@ public Tree visit(@Nullable Tree tree, ExecutionContext ctx) { }; } + private boolean hasDependency(Tree tree) { + VersionComparator versionComparator = version != null ? Semver.validate(version, null).getValue() : null; + + MavenResolutionResult mavenResult = tree.getMarkers().findFirst(MavenResolutionResult.class).orElse(null); + if (mavenResult != null) { + Scope requestedScope = scope == null ? null : Scope.fromName(scope); + List dependencies = mavenResult.findDependencies(groupIdPattern, artifactIdPattern, requestedScope); + for (ResolvedDependency dependency : dependencies) { + if (versionComparator == null || versionComparator.isValid(null, dependency.getVersion())) { + return true; + } + } + return false; + } + + GradleProject gp = tree.getMarkers().findFirst(GradleProject.class).orElse(null); + if (gp != null) { + for (GradleDependencyConfiguration c : gp.getConfigurations()) { + for (ResolvedDependency resolvedDependency : c.getDirectResolved()) { + ResolvedDependency found = resolvedDependency.findDependency(groupIdPattern, artifactIdPattern); + if (found != null && (versionComparator == null || versionComparator.isValid(null, found.getVersion()))) { + return true; + } + } + } + } + return false; + } + @Override public TreeVisitor getVisitor(AtomicBoolean acc) { if (acc.get()) {