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 749b3ab7..0b73c394 100644 --- a/src/main/java/org/openrewrite/java/dependencies/search/ModuleHasDependency.java +++ b/src/main/java/org/openrewrite/java/dependencies/search/ModuleHasDependency.java @@ -21,8 +21,10 @@ import org.openrewrite.*; import org.openrewrite.gradle.marker.GradleDependencyConfiguration; import org.openrewrite.gradle.marker.GradleProject; +import org.openrewrite.internal.StringUtils; import org.openrewrite.java.marker.JavaProject; import org.openrewrite.marker.SearchResult; +import org.openrewrite.maven.tree.Dependency; import org.openrewrite.maven.tree.MavenResolutionResult; import org.openrewrite.maven.tree.ResolvedDependency; import org.openrewrite.maven.tree.Scope; @@ -115,6 +117,11 @@ private boolean hasDependency(Tree tree) { return true; } } + for (Dependency requested : mavenResult.getPom().getRequestedDependencies()) { + if (matchesRequested(requested, requestedScope, versionComparator)) { + return true; + } + } return false; } @@ -128,10 +135,46 @@ private boolean hasDependency(Tree tree) { } } } + for (GradleDependencyConfiguration c : gp.getConfigurations()) { + for (Dependency requested : c.getRequested()) { + if (matchesRequested(requested, null, versionComparator)) { + return true; + } + } + } } return false; } + private boolean matchesRequested(Dependency dep, @Nullable Scope requestedScope, @Nullable VersionComparator versionComparator) { + if (dep.getGroupId() == null || dep.getArtifactId() == null) { + return false; + } + if (!StringUtils.matchesGlob(dep.getGroupId(), groupIdPattern)) { + return false; + } + if (!StringUtils.matchesGlob(dep.getArtifactId(), artifactIdPattern)) { + return false; + } + if (requestedScope != null) { + Scope depScope = dep.getScope() == null ? Scope.Compile : Scope.fromName(dep.getScope()); + if (!depScope.isInClasspathOf(requestedScope)) { + return false; + } + } + return versionMatches(dep.getVersion(), versionComparator); + } + + private static boolean versionMatches(@Nullable String version, @Nullable VersionComparator cmp) { + if (cmp == null || version == null) { + return true; + } + if (version.startsWith("${")) { + return false; + } + return cmp.isValid(null, version); + } + @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 c3357780..b982d0e2 100644 --- a/src/main/java/org/openrewrite/java/dependencies/search/RepositoryHasDependency.java +++ b/src/main/java/org/openrewrite/java/dependencies/search/RepositoryHasDependency.java @@ -21,8 +21,10 @@ import org.openrewrite.*; import org.openrewrite.gradle.marker.GradleDependencyConfiguration; import org.openrewrite.gradle.marker.GradleProject; +import org.openrewrite.internal.StringUtils; import org.openrewrite.java.marker.JavaProject; import org.openrewrite.marker.SearchResult; +import org.openrewrite.maven.tree.Dependency; import org.openrewrite.maven.tree.MavenResolutionResult; import org.openrewrite.maven.tree.ResolvedDependency; import org.openrewrite.maven.tree.Scope; @@ -110,6 +112,11 @@ private boolean hasDependency(Tree tree) { return true; } } + for (Dependency requested : mavenResult.getPom().getRequestedDependencies()) { + if (matchesRequested(requested, requestedScope, versionComparator)) { + return true; + } + } return false; } @@ -123,10 +130,46 @@ private boolean hasDependency(Tree tree) { } } } + for (GradleDependencyConfiguration c : gp.getConfigurations()) { + for (Dependency requested : c.getRequested()) { + if (matchesRequested(requested, null, versionComparator)) { + return true; + } + } + } } return false; } + private boolean matchesRequested(Dependency dep, @Nullable Scope requestedScope, @Nullable VersionComparator versionComparator) { + if (dep.getGroupId() == null || dep.getArtifactId() == null) { + return false; + } + if (!StringUtils.matchesGlob(dep.getGroupId(), groupIdPattern)) { + return false; + } + if (!StringUtils.matchesGlob(dep.getArtifactId(), artifactIdPattern)) { + return false; + } + if (requestedScope != null) { + Scope depScope = dep.getScope() == null ? Scope.Compile : Scope.fromName(dep.getScope()); + if (!depScope.isInClasspathOf(requestedScope)) { + return false; + } + } + return versionMatches(dep.getVersion(), versionComparator); + } + + private static boolean versionMatches(@Nullable String version, @Nullable VersionComparator cmp) { + if (cmp == null || version == null) { + return true; + } + if (version.startsWith("${")) { + return false; + } + return cmp.isValid(null, version); + } + @Override public TreeVisitor getVisitor(AtomicBoolean acc) { if (acc.get()) { diff --git a/src/test/java/org/openrewrite/java/dependencies/search/ModuleHasDependencyTest.java b/src/test/java/org/openrewrite/java/dependencies/search/ModuleHasDependencyTest.java index 61cd0285..0efe3269 100644 --- a/src/test/java/org/openrewrite/java/dependencies/search/ModuleHasDependencyTest.java +++ b/src/test/java/org/openrewrite/java/dependencies/search/ModuleHasDependencyTest.java @@ -21,9 +21,16 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.NullSource; import org.junit.jupiter.params.provider.ValueSource; +import org.openrewrite.InMemoryExecutionContext; +import org.openrewrite.Parser; +import org.openrewrite.maven.MavenExecutionContextView; +import org.openrewrite.maven.MavenSettings; import org.openrewrite.test.RecipeSpec; import org.openrewrite.test.RewriteTest; +import java.io.ByteArrayInputStream; +import java.nio.file.Path; + import static org.assertj.core.api.Assertions.assertThat; import static org.openrewrite.gradle.Assertions.buildGradle; import static org.openrewrite.gradle.toolingapi.Assertions.withToolingApi; @@ -346,6 +353,109 @@ void whenModuleDoesNotHaveDependencyButInvertedMarkingMarks() { ); } + @Nested + class WhenDependencyIsRequestedButNotResolved { + + @Language("groovy") + private final static String GradleNoRepositories = """ + plugins { + id 'java-library' + } + dependencies { + implementation 'org.springframework:spring-beans:6.0.0' + } + """; + + @Language("xml") + private final static String MavenNoRepositories = """ + + com.example + foo + 1.0.0 + + + org.springframework + spring-beans + 6.0.0 + + + + """; + + @Test + void gradleMatchesOnRequested() { + rewriteRun( + spec -> spec.recipe(new ModuleHasDependency(GroupId, ArtifactId, null, null, null)), + mavenProject("project-gradle", + buildGradle( + GradleNoRepositories, + spec -> spec.after(actual -> + assertThat(actual) + .startsWith(GradleMarkerPositive) + .actual() + ) + ), + java( + GradleJava, + spec -> spec.after(actual -> + assertThat(actual) + .startsWith(JavaMarkerPositive) + .actual() + ) + ) + ) + ); + } + + @Test + void mavenMatchesOnRequested() { + rewriteRun( + spec -> { + MavenExecutionContextView ctx = MavenExecutionContextView.view(new InMemoryExecutionContext()); + MavenSettings emptySettings = MavenSettings.parse(new Parser.Input(Path.of("settings.xml"), () -> new ByteArrayInputStream( + //language=xml + """ + + """.getBytes())), ctx); + ctx.setMavenSettings(emptySettings); + spec.recipe(new ModuleHasDependency(GroupId, ArtifactId, null, null, null)) + .executionContext(ctx); + }, + mavenProject("project-maven", + pomXml( + MavenNoRepositories, + spec -> spec.after(actual -> + assertThat(actual) + .startsWith(MavenMarkerPositive) + .actual() + ) + ), + java( + MavenJava, + spec -> spec.after(actual -> + assertThat(actual) + .startsWith(JavaMarkerPositive) + .actual() + ) + ) + ) + ); + } + + @Test + void gradleVersionRangeOnRequestedDoesNotMatchWhenOutOfRange() { + rewriteRun( + spec -> spec.recipe(new ModuleHasDependency(GroupId, ArtifactId, null, "[7.0,)", null)), + mavenProject("project-gradle", + buildGradle(GradleNoRepositories), + java(GradleJava) + ) + ); + } + } + @Nested class WithVersionsPattern { @ParameterizedTest