Skip to content

Commit 628a2bb

Browse files
MBoegerstimtebeek
authored andcommitted
Gradle DependencyInsights breaks on dependencies with constraints (openrewrite#5897)
* add reproducing tests * correct expectation and document that the DependencyInsight recipes match against resolved versions * Fix performance problem with RemoveUnusedProperties (openrewrite#5895) * Fix performance problem with RemoveUnusedProperties - openrewrite#5875 * Make the test values more descriptive * Stable label order for `PrintMavenAsDot` (openrewrite#5893) * Stable label order for `PrintMavenAsDot` * Restore junit-bom * Update PrintMavenAsDotTest.java * Minimize indentation * Use the same bounds for labels as for edges * Match dot output in CI (openrewrite#5898) * apply best practices --------- Co-authored-by: Tim te Beek <tim@moderne.io>
1 parent 6e05368 commit 628a2bb

3 files changed

Lines changed: 175 additions & 2 deletions

File tree

rewrite-gradle/src/main/java/org/openrewrite/gradle/search/DependencyInsight.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public class DependencyInsight extends Recipe {
6565
String artifactIdPattern;
6666

6767
@Option(displayName = "Version",
68-
description = "Match only dependencies with the specified version. " +
68+
description = "Match only dependencies with the specified resolved version. " +
6969
"Node-style [version selectors](https://docs.openrewrite.org/reference/dependency-version-selectors) may be used." +
7070
"All versions are searched by default.",
7171
example = "1.x",
@@ -87,7 +87,7 @@ public String getDisplayName() {
8787

8888
@Override
8989
public String getDescription() {
90-
return "Find direct and transitive dependencies matching a group, artifact, and optionally a configuration name. " +
90+
return "Find direct and transitive dependencies matching a group, artifact, resolved version, and optionally a configuration name. " +
9191
"Results include dependencies that either directly match or transitively include a matching dependency.";
9292
}
9393

rewrite-gradle/src/test/java/org/openrewrite/gradle/search/DependencyInsightTest.java

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.junit.jupiter.params.ParameterizedTest;
2222
import org.junit.jupiter.params.provider.Arguments;
2323
import org.junit.jupiter.params.provider.MethodSource;
24+
import org.junit.jupiter.params.provider.ValueSource;
2425
import org.openrewrite.DocumentExample;
2526
import org.openrewrite.maven.table.DependenciesInUse;
2627
import org.openrewrite.test.RecipeSpec;
@@ -323,6 +324,119 @@ void versionSearch() {
323324
);
324325
}
325326

327+
@Nested
328+
class VersionParameter {
329+
330+
@ParameterizedTest
331+
@ValueSource(strings = {
332+
"1.0.1", // exact
333+
"1.0.1-1.0.5", // hyphenated
334+
"[1.0.1,1.0.5)", "[1.0.1,1.0.5]", "[1.0.1,1.0.5]", "(1.0.0,1.0.5]", // full range
335+
"~1.0.1"// tilde range
336+
})
337+
void singleMatch(String versionPattern) {
338+
rewriteRun(
339+
recipeSpec -> recipeSpec.recipe(new DependencyInsight("jakarta.data", "*", versionPattern, null)),
340+
//language=groovy
341+
buildGradle(
342+
"""
343+
plugins {
344+
id 'java-library'
345+
}
346+
repositories {
347+
mavenCentral()
348+
}
349+
dependencies {
350+
implementation 'jakarta.data:jakarta.data-api:1.0.1'
351+
implementation 'jakarta.data:jakarta.data-spec:1.0.0'
352+
}
353+
""",
354+
"""
355+
plugins {
356+
id 'java-library'
357+
}
358+
repositories {
359+
mavenCentral()
360+
}
361+
dependencies {
362+
/*~~(jakarta.data:jakarta.data-api:1.0.1)~~>*/implementation 'jakarta.data:jakarta.data-api:1.0.1'
363+
implementation 'jakarta.data:jakarta.data-spec:1.0.0'
364+
}
365+
"""
366+
)
367+
);
368+
}
369+
370+
/**
371+
* `1.0.X` is expected to match both dependencies.
372+
*/
373+
@Test
374+
void multiMatch() {
375+
rewriteRun(
376+
recipeSpec -> recipeSpec.recipe(new DependencyInsight("jakarta.data", "*", "1.0.X", null)),
377+
//language=groovy
378+
buildGradle(
379+
"""
380+
plugins {
381+
id 'java-library'
382+
}
383+
repositories {
384+
mavenCentral()
385+
}
386+
dependencies {
387+
implementation 'jakarta.data:jakarta.data-api:1.0.1'
388+
implementation 'jakarta.data:jakarta.data-spec:1.0.0'
389+
}
390+
""",
391+
"""
392+
plugins {
393+
id 'java-library'
394+
}
395+
repositories {
396+
mavenCentral()
397+
}
398+
dependencies {
399+
/*~~(jakarta.data:jakarta.data-api:1.0.1)~~>*/implementation 'jakarta.data:jakarta.data-api:1.0.1'
400+
/*~~(jakarta.data:jakarta.data-spec:1.0.0)~~>*/implementation 'jakarta.data:jakarta.data-spec:1.0.0'
401+
}
402+
"""
403+
)
404+
);
405+
}
406+
407+
/**
408+
* Gradle supports defining constraints on the framework side.
409+
* f.i. `org.springframework:spring-aop:6.2.2` enforces version 6.2.2 on every other dependency causing `org.springframework:spring-core:6.1.5` to be `org.springframework:spring-core:6.2.2` in fact.
410+
*/
411+
@ParameterizedTest
412+
@ValueSource(strings = {
413+
"6.1.1-6.1.15", // hyphenated
414+
"[6.1.1,6.1.6)", "[6.1.1,6.1.5]", "[6.1.5,6.1.15]", "(6.1.4,6.1.15]", // full range
415+
"6.1.X", // X range
416+
"~6.1.0", "~6.1", // tilde range
417+
})
418+
void withConstraintsEnforced(String versionPattern) {
419+
rewriteRun(
420+
recipeSpec -> recipeSpec.recipe(new DependencyInsight("org.springframework", "*", versionPattern, null)),
421+
//language=groovy
422+
buildGradle(
423+
"""
424+
plugins {
425+
id 'java-library'
426+
}
427+
repositories {
428+
mavenCentral()
429+
}
430+
dependencies {
431+
implementation 'org.springframework:spring-core:6.1.5'
432+
implementation 'org.springframework:spring-aop:6.2.2'
433+
}
434+
"""
435+
)
436+
);
437+
}
438+
}
439+
326440
@Test
327441
void nestedDependenciesAreTransitivelySearchedForMatchingDependencies() {
328442
rewriteRun(

rewrite-maven/src/test/java/org/openrewrite/maven/search/DependencyInsightTest.java

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
package org.openrewrite.maven.search;
1717

1818
import org.junit.jupiter.api.Test;
19+
import org.junit.jupiter.params.ParameterizedTest;
20+
import org.junit.jupiter.params.provider.ValueSource;
1921
import org.openrewrite.DocumentExample;
2022
import org.openrewrite.Issue;
2123
import org.openrewrite.test.RewriteTest;
@@ -194,4 +196,61 @@ void versionSelector() {
194196
)
195197
);
196198
}
199+
200+
@ParameterizedTest
201+
@ValueSource(strings = {
202+
"6.1.5", // exact
203+
"6.1.1-6.1.15", // hyphenated
204+
"[6.1.1,6.1.6)", "[6.1.1,6.1.5]", "[6.1.5,6.1.15]", "(6.1.4,6.1.15]", // full range
205+
"6.1.X", // X range
206+
"~6.1.0", "~6.1", // tilde range
207+
})
208+
void versionPatterns(String versionPattern) {
209+
rewriteRun(
210+
recipeSpec -> recipeSpec.recipe(new DependencyInsight("org.springframework", "*", null, versionPattern, null)),
211+
//language=xml
212+
pomXml(
213+
"""
214+
<project>
215+
<groupId>com.example</groupId>
216+
<artifactId>foo</artifactId>
217+
<version>1.0.0</version>
218+
219+
<dependencies>
220+
<dependency>
221+
<groupId>org.springframework</groupId>
222+
<artifactId>spring-core</artifactId>
223+
<version>6.1.5</version>
224+
</dependency>
225+
<dependency>
226+
<groupId>org.springframework</groupId>
227+
<artifactId>spring-aop</artifactId>
228+
<version>6.2.2</version>
229+
</dependency>
230+
</dependencies>
231+
</project>
232+
""",
233+
"""
234+
<project>
235+
<groupId>com.example</groupId>
236+
<artifactId>foo</artifactId>
237+
<version>1.0.0</version>
238+
239+
<dependencies>
240+
<!--~~>--><dependency>
241+
<groupId>org.springframework</groupId>
242+
<artifactId>spring-core</artifactId>
243+
<version>6.1.5</version>
244+
</dependency>
245+
<dependency>
246+
<groupId>org.springframework</groupId>
247+
<artifactId>spring-aop</artifactId>
248+
<version>6.2.2</version>
249+
</dependency>
250+
</dependencies>
251+
</project>
252+
"""
253+
)
254+
);
255+
}
197256
}

0 commit comments

Comments
 (0)