Skip to content

Commit dc43914

Browse files
committed
Add more tests, implement remaining rules based on attribute matching
1 parent 7354ca8 commit dc43914

File tree

5 files changed

+198
-23
lines changed

5 files changed

+198
-23
lines changed

src/main/java/org/gradlex/jvm/dependency/conflict/resolution/rules/AddApiDependencyMetadataRule.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,17 @@
1919
import org.gradle.api.artifacts.CacheableRule;
2020
import org.gradle.api.artifacts.ComponentMetadataContext;
2121
import org.gradle.api.artifacts.ComponentMetadataRule;
22+
import org.gradle.api.attributes.Category;
23+
import org.gradle.api.attributes.Usage;
2224

2325
import javax.inject.Inject;
2426

27+
import static org.gradlex.jvm.dependency.conflict.resolution.rules.VariantSelection.allVariantsMatching;
28+
2529
/**
2630
* See:
2731
* <a href="https://docs.gradle.org/current/userguide/component_metadata_rules.html#fixing_wrong_dependency_details">
28-
* component_metadata_rules.html#fixing_wrong_dependency_details</a>
32+
* component_metadata_rules.html#fixing_wrong_dependency_details</a>
2933
*/
3034
@CacheableRule
3135
public abstract class AddApiDependencyMetadataRule implements ComponentMetadataRule {
@@ -39,6 +43,8 @@ public AddApiDependencyMetadataRule(String dependency) {
3943

4044
@Override
4145
public void execute(ComponentMetadataContext context) {
42-
context.getDetails().allVariants(v -> v.withDependencies(d -> d.add(dependency)));
46+
allVariantsMatching(context,
47+
id -> (id.matches(Usage.USAGE_ATTRIBUTE, Usage.JAVA_API) || id.matches(Usage.USAGE_ATTRIBUTE, Usage.JAVA_RUNTIME)) && id.matches(Category.CATEGORY_ATTRIBUTE, Category.LIBRARY),
48+
v -> v.withDependencies(d -> d.add(dependency)));
4349
}
4450
}

src/main/java/org/gradlex/jvm/dependency/conflict/resolution/rules/AddCompileOnlyApiDependencyMetadataRule.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,17 @@
1919
import org.gradle.api.artifacts.CacheableRule;
2020
import org.gradle.api.artifacts.ComponentMetadataContext;
2121
import org.gradle.api.artifacts.ComponentMetadataRule;
22+
import org.gradle.api.attributes.Category;
23+
import org.gradle.api.attributes.Usage;
2224

2325
import javax.inject.Inject;
2426

27+
import static org.gradlex.jvm.dependency.conflict.resolution.rules.VariantSelection.allVariantsMatching;
28+
2529
/**
2630
* See:
2731
* <a href="https://docs.gradle.org/current/userguide/component_metadata_rules.html#fixing_wrong_dependency_details">
28-
* component_metadata_rules.html#fixing_wrong_dependency_details</a>
32+
* component_metadata_rules.html#fixing_wrong_dependency_details</a>
2933
*/
3034
@CacheableRule
3135
public abstract class AddCompileOnlyApiDependencyMetadataRule implements ComponentMetadataRule {
@@ -39,7 +43,8 @@ public AddCompileOnlyApiDependencyMetadataRule(String dependency) {
3943

4044
@Override
4145
public void execute(ComponentMetadataContext context) {
42-
context.getDetails().withVariant("compile", v -> v.withDependencies(d -> d.add(dependency))); // .pom
43-
context.getDetails().withVariant("apiElements", v -> v.withDependencies(d -> d.add(dependency))); // .module
46+
allVariantsMatching(context,
47+
id -> (id.matches(Usage.USAGE_ATTRIBUTE, Usage.JAVA_API) && id.matches(Category.CATEGORY_ATTRIBUTE, Category.LIBRARY)),
48+
v -> v.withDependencies(d -> d.add(dependency)));
4449
}
4550
}

src/main/java/org/gradlex/jvm/dependency/conflict/resolution/rules/AddRuntimeOnlyDependencyMetadataRule.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,17 @@
1919
import org.gradle.api.artifacts.CacheableRule;
2020
import org.gradle.api.artifacts.ComponentMetadataContext;
2121
import org.gradle.api.artifacts.ComponentMetadataRule;
22+
import org.gradle.api.attributes.Category;
23+
import org.gradle.api.attributes.Usage;
2224

2325
import javax.inject.Inject;
2426

27+
import static org.gradlex.jvm.dependency.conflict.resolution.rules.VariantSelection.allVariantsMatching;
28+
2529
/**
2630
* See:
2731
* <a href="https://docs.gradle.org/current/userguide/component_metadata_rules.html#fixing_wrong_dependency_details">
28-
* component_metadata_rules.html#fixing_wrong_dependency_details</a>
32+
* component_metadata_rules.html#fixing_wrong_dependency_details</a>
2933
*/
3034
@CacheableRule
3135
public abstract class AddRuntimeOnlyDependencyMetadataRule implements ComponentMetadataRule {
@@ -39,7 +43,8 @@ public AddRuntimeOnlyDependencyMetadataRule(String dependency) {
3943

4044
@Override
4145
public void execute(ComponentMetadataContext context) {
42-
context.getDetails().withVariant("runtime", v -> v.withDependencies(d -> d.add(dependency))); // .pom
43-
context.getDetails().withVariant("runtimeElements", v -> v.withDependencies(d -> d.add(dependency))); // .module
46+
allVariantsMatching(context,
47+
id -> id.matches(Usage.USAGE_ATTRIBUTE, Usage.JAVA_RUNTIME) && id.matches(Category.CATEGORY_ATTRIBUTE, Category.LIBRARY),
48+
v -> v.withDependencies(d -> d.add(dependency)));
4449
}
4550
}

src/main/java/org/gradlex/jvm/dependency/conflict/resolution/rules/RemoveDependencyMetadataRule.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,18 @@
1919
import org.gradle.api.artifacts.CacheableRule;
2020
import org.gradle.api.artifacts.ComponentMetadataContext;
2121
import org.gradle.api.artifacts.ComponentMetadataRule;
22+
import org.gradle.api.attributes.Category;
23+
import org.gradle.api.attributes.Usage;
2224

2325
import javax.inject.Inject;
2426
import java.util.stream.Collectors;
2527

28+
import static org.gradlex.jvm.dependency.conflict.resolution.rules.VariantSelection.allVariantsMatching;
29+
2630
/**
2731
* See:
2832
* <a href="https://docs.gradle.org/current/userguide/component_metadata_rules.html#fixing_wrong_dependency_details">
29-
* component_metadata_rules.html#fixing_wrong_dependency_details</a>
33+
* component_metadata_rules.html#fixing_wrong_dependency_details</a>
3034
*/
3135
@CacheableRule
3236
public abstract class RemoveDependencyMetadataRule implements ComponentMetadataRule {
@@ -40,7 +44,8 @@ public RemoveDependencyMetadataRule(String dependency) {
4044

4145
@Override
4246
public void execute(ComponentMetadataContext context) {
43-
context.getDetails().allVariants(v -> v.withDependencies(d ->
44-
d.removeAll(d.stream().filter(it -> dependency.equals(it.getModule().toString())).collect(Collectors.toList()))));
47+
allVariantsMatching(context,
48+
id -> (id.matches(Usage.USAGE_ATTRIBUTE, Usage.JAVA_API) || id.matches(Usage.USAGE_ATTRIBUTE, Usage.JAVA_RUNTIME)) && id.matches(Category.CATEGORY_ATTRIBUTE, Category.LIBRARY),
49+
v -> v.withDependencies(d -> d.removeAll(d.stream().filter(it -> dependency.equals(it.getModule().toString())).collect(Collectors.toList()))));
4550
}
4651
}

src/test/groovy/org/gradlex/jvm/dependency/conflict/test/patch/ModifyDependenciesTest.groovy

Lines changed: 166 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@ package org.gradlex.jvm.dependency.conflict.test.patch
22

33
import org.gradlex.jvm.dependency.conflict.test.fixture.GradleBuild
44

5+
/**
6+
* All tests in this class come in two flavors:
7+
* - pom-only metadata variants: test against components that have been published with Maven, thus just having Maven pom
8+
* metadata attached.
9+
* - Gradle metadata variants: always test against guava, because it is published with custom, non-standard Gradle
10+
* metadata.
11+
*/
512
class ModifyDependenciesTest extends AbstractPatchTest {
613

714
def setup() {
@@ -14,34 +21,69 @@ class ModifyDependenciesTest extends AbstractPatchTest {
1421
}
1522
}
1623

17-
def "can remove dependencies"() {
24+
def "can remove dependencies from pom-only metadata variants"() {
25+
given:
26+
buildFile << """
27+
jvmDependencyConflicts {
28+
patch {
29+
module("org.apache.commons:commons-text") {
30+
removeDependency("org.apache.commons:commons-lang3")
31+
}
32+
}
33+
}
34+
dependencies {
35+
implementation("org.apache.commons:commons-text:1.13.1")
36+
}
37+
"""
38+
39+
expect:
40+
dependenciesCompile().output.contains '''
41+
compileClasspath - Compile classpath for source set 'main'.
42+
\\--- org.apache.commons:commons-text:1.13.1
43+
44+
'''
45+
46+
and:
47+
dependenciesRuntime().output.contains '''
48+
runtimeClasspath - Runtime classpath of source set 'main'.
49+
\\--- org.apache.commons:commons-text:1.13.1
50+
51+
'''
52+
}
53+
54+
def "can remove dependencies from Gradle metadata variants"() {
1855
given:
1956
buildFile << """
2057
jvmDependencyConflicts {
2158
patch {
2259
module("com.google.guava:guava") {
23-
removeDependency("com.google.guava:listenablefuture")
24-
removeDependency("com.google.code.findbugs:jsr305")
25-
removeDependency("org.checkerframework:checker-qual")
2660
removeDependency("com.google.errorprone:error_prone_annotations")
61+
removeDependency("org.jspecify:jspecify")
2762
removeDependency("com.google.j2objc:j2objc-annotations")
2863
}
2964
}
3065
}
3166
dependencies {
32-
implementation("com.google.guava:guava:33.0.0-jre")
67+
implementation("com.google.guava:guava:33.4.8-jre")
3368
}
3469
"""
3570

3671
expect:
3772
dependenciesCompile().output.contains '''
3873
compileClasspath - Compile classpath for source set 'main'.
39-
\\--- com.google.guava:guava:33.0.0-jre
40-
\\--- com.google.guava:failureaccess:1.0.2
74+
\\--- com.google.guava:guava:33.4.8-jre
75+
\\--- com.google.guava:failureaccess:1.0.3
76+
'''
77+
78+
and:
79+
dependenciesRuntime().output.contains '''
80+
runtimeClasspath - Runtime classpath of source set 'main'.
81+
\\--- com.google.guava:guava:33.4.8-jre
82+
\\--- com.google.guava:failureaccess:1.0.3
4183
'''
4284
}
4385

44-
def "can reduce dependency scope to runtime only for pom-only metadata attributes"() {
86+
def "can reduce dependency scope to runtime only for pom-only metadata variants"() {
4587
given:
4688
buildFile << """
4789
jvmDependencyConflicts {
@@ -70,7 +112,7 @@ runtimeClasspath - Runtime classpath of source set 'main'.
70112
'''
71113
}
72114

73-
def "can remove runtime only dependency for Gradle metadata attributes"() {
115+
def "can reduce dependency scope to runtime only for Gradle metadata variants"() {
74116
given:
75117
buildFile << """
76118
jvmDependencyConflicts {
@@ -169,7 +211,7 @@ runtimeClasspath - Runtime classpath of source set 'main'.
169211
'''
170212
}
171213

172-
def "can add api dependency"() {
214+
def "can add api dependency for pom-only metadata variants"() {
173215
given:
174216
buildFile << """
175217
jvmDependencyConflicts {
@@ -199,7 +241,45 @@ runtimeClasspath - Runtime classpath of source set 'main'.
199241
'''
200242
}
201243

202-
def "can add runtime only dependency"() {
244+
def "can add api dependency for Gradle metadata variants"() {
245+
given:
246+
buildFile << """
247+
jvmDependencyConflicts {
248+
patch {
249+
module("com.google.guava:guava") {
250+
addApiDependency("io.projectreactor.tools:blockhound:1.0.8.RELEASE")
251+
}
252+
}
253+
}
254+
dependencies {
255+
implementation("com.google.guava:guava:33.4.8-jre")
256+
}
257+
"""
258+
259+
expect:
260+
dependenciesCompile().output.contains '''
261+
compileClasspath - Compile classpath for source set 'main'.
262+
\\--- com.google.guava:guava:33.4.8-jre
263+
+--- com.google.guava:failureaccess:1.0.3
264+
+--- org.jspecify:jspecify:1.0.0
265+
+--- com.google.errorprone:error_prone_annotations:2.36.0
266+
+--- com.google.j2objc:j2objc-annotations:3.0.0
267+
\\--- io.projectreactor.tools:blockhound:1.0.8.RELEASE
268+
269+
'''
270+
dependenciesRuntime().output.contains '''
271+
runtimeClasspath - Runtime classpath of source set 'main'.
272+
\\--- com.google.guava:guava:33.4.8-jre
273+
+--- com.google.guava:failureaccess:1.0.3
274+
+--- org.jspecify:jspecify:1.0.0
275+
+--- com.google.errorprone:error_prone_annotations:2.36.0
276+
+--- com.google.j2objc:j2objc-annotations:3.0.0
277+
\\--- io.projectreactor.tools:blockhound:1.0.8.RELEASE
278+
279+
'''
280+
}
281+
282+
def "can add runtime only dependency for pom-only metadata variants"() {
203283
given:
204284
buildFile << """
205285
jvmDependencyConflicts {
@@ -228,7 +308,44 @@ runtimeClasspath - Runtime classpath of source set 'main'.
228308
'''
229309
}
230310

231-
def "can add compile only dependency"() {
311+
def "can add runtime only dependency for Gradle metadata variants"() {
312+
given:
313+
buildFile << """
314+
jvmDependencyConflicts {
315+
patch {
316+
module("com.google.guava:guava") {
317+
addRuntimeOnlyDependency("io.projectreactor.tools:blockhound:1.0.8.RELEASE")
318+
}
319+
}
320+
}
321+
dependencies {
322+
implementation("com.google.guava:guava:33.4.8-jre")
323+
}
324+
"""
325+
326+
expect:
327+
dependenciesCompile().output.contains '''
328+
compileClasspath - Compile classpath for source set 'main'.
329+
\\--- com.google.guava:guava:33.4.8-jre
330+
+--- com.google.guava:failureaccess:1.0.3
331+
+--- org.jspecify:jspecify:1.0.0
332+
+--- com.google.errorprone:error_prone_annotations:2.36.0
333+
\\--- com.google.j2objc:j2objc-annotations:3.0.0
334+
335+
'''
336+
dependenciesRuntime().output.contains '''
337+
runtimeClasspath - Runtime classpath of source set 'main'.
338+
\\--- com.google.guava:guava:33.4.8-jre
339+
+--- com.google.guava:failureaccess:1.0.3
340+
+--- org.jspecify:jspecify:1.0.0
341+
+--- com.google.errorprone:error_prone_annotations:2.36.0
342+
+--- com.google.j2objc:j2objc-annotations:3.0.0
343+
\\--- io.projectreactor.tools:blockhound:1.0.8.RELEASE
344+
345+
'''
346+
}
347+
348+
def "can add compile only dependency for pom-only metadata variants"() {
232349
given:
233350
buildFile << """
234351
jvmDependencyConflicts {
@@ -254,6 +371,43 @@ compileClasspath - Compile classpath for source set 'main'.
254371
runtimeClasspath - Runtime classpath of source set 'main'.
255372
\\--- io.netty:netty-common:4.1.106.Final
256373
374+
'''
375+
}
376+
377+
def "can add compile only dependency for Gradle metadata variants"() {
378+
given:
379+
buildFile << """
380+
jvmDependencyConflicts {
381+
patch {
382+
module("com.google.guava:guava") {
383+
addCompileOnlyApiDependency("io.projectreactor.tools:blockhound:1.0.8.RELEASE")
384+
}
385+
}
386+
}
387+
dependencies {
388+
implementation("com.google.guava:guava:33.4.8-jre")
389+
}
390+
"""
391+
392+
expect:
393+
dependenciesCompile().output.contains '''
394+
compileClasspath - Compile classpath for source set 'main'.
395+
\\--- com.google.guava:guava:33.4.8-jre
396+
+--- com.google.guava:failureaccess:1.0.3
397+
+--- org.jspecify:jspecify:1.0.0
398+
+--- com.google.errorprone:error_prone_annotations:2.36.0
399+
+--- com.google.j2objc:j2objc-annotations:3.0.0
400+
\\--- io.projectreactor.tools:blockhound:1.0.8.RELEASE
401+
402+
'''
403+
dependenciesRuntime().output.contains '''
404+
runtimeClasspath - Runtime classpath of source set 'main'.
405+
\\--- com.google.guava:guava:33.4.8-jre
406+
+--- com.google.guava:failureaccess:1.0.3
407+
+--- org.jspecify:jspecify:1.0.0
408+
+--- com.google.errorprone:error_prone_annotations:2.36.0
409+
\\--- com.google.j2objc:j2objc-annotations:3.0.0
410+
257411
'''
258412
}
259413
}

0 commit comments

Comments
 (0)