Skip to content

Commit 11e0453

Browse files
committed
Implement ReduceToCompileOnlyApi based on Attribute, not variant names
1 parent be4f1f0 commit 11e0453

File tree

2 files changed

+63
-7
lines changed

2 files changed

+63
-7
lines changed

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

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,24 @@
1616

1717
package org.gradlex.jvm.dependency.conflict.resolution.rules;
1818

19+
import org.gradle.api.Action;
1920
import org.gradle.api.artifacts.CacheableRule;
2021
import org.gradle.api.artifacts.ComponentMetadataContext;
22+
import org.gradle.api.artifacts.ComponentMetadataDetails;
2123
import org.gradle.api.artifacts.ComponentMetadataRule;
24+
import org.gradle.api.artifacts.VariantMetadata;
25+
import org.gradle.api.attributes.Attribute;
26+
import org.gradle.api.attributes.Category;
27+
import org.gradle.api.attributes.Usage;
2228

2329
import javax.inject.Inject;
30+
import java.util.Objects;
2431
import java.util.stream.Collectors;
2532

2633
/**
2734
* See:
2835
* <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>
36+
* component_metadata_rules.html#fixing_wrong_dependency_details</a>
3037
*/
3138
@CacheableRule
3239
public abstract class ReduceToCompileOnlyApiDependencyMetadataRule implements ComponentMetadataRule {
@@ -40,7 +47,18 @@ public ReduceToCompileOnlyApiDependencyMetadataRule(String dependency) {
4047

4148
@Override
4249
public void execute(ComponentMetadataContext context) {
43-
context.getDetails().withVariant("runtime", v -> v.withDependencies(d -> d.removeAll(d.stream().filter(it -> dependency.equals(it.getModule().toString())).collect(Collectors.toList())))); // .pom
44-
context.getDetails().withVariant("runtimeElements", v -> v.withDependencies(d -> d.removeAll(d.stream().filter(it -> dependency.equals(it.getModule().toString())).collect(Collectors.toList())))); // .module
50+
withVariants(context.getDetails(), Usage.JAVA_RUNTIME, v -> v.withDependencies(d -> d.removeAll(d.stream().filter(it -> dependency.equals(it.getModule().toString())).collect(Collectors.toList()))));
51+
}
52+
53+
private void withVariants(ComponentMetadataDetails details, String expectedUsage, Action<VariantMetadata> action) {
54+
details.allVariants(v -> {
55+
v.attributes(attributeContainer -> {
56+
String usage = attributeContainer.getAttributes().getAttribute(Attribute.of(Usage.USAGE_ATTRIBUTE.getName(), String.class));
57+
String category = attributeContainer.getAttributes().getAttribute(Attribute.of(Category.CATEGORY_ATTRIBUTE.getName(), String.class));
58+
if (Objects.equals(usage, expectedUsage) && Objects.equals(category, Category.LIBRARY)) {
59+
action.execute(v);
60+
}
61+
});
62+
});
4563
}
4664
}

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

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,18 @@ import org.gradlex.jvm.dependency.conflict.test.fixture.GradleBuild
44

55
class ModifyDependenciesTest extends AbstractPatchTest {
66

7-
def "can remove dependencies"() {
8-
given:
7+
def setup() {
98
if (GradleBuild.GRADLE6_TEST) {
109
buildFile << """
11-
configurations.compileClasspath {
10+
configurations.configureEach {
1211
attributes.attribute(Attribute.of("org.gradle.jvm.environment", String::class.java), "standard-jvm")
1312
}
1413
"""
1514
}
15+
}
16+
17+
def "can remove dependencies"() {
18+
given:
1619
buildFile << """
1720
jvmDependencyConflicts {
1821
patch {
@@ -67,7 +70,7 @@ runtimeClasspath - Runtime classpath of source set 'main'.
6770
'''
6871
}
6972

70-
def "can reduce dependency scope to compile only"() {
73+
def "can reduce dependency scope to compile only for standard variants"() {
7174
given:
7275
buildFile << """
7376
jvmDependencyConflicts {
@@ -93,6 +96,41 @@ compileClasspath - Compile classpath for source set 'main'.
9396
runtimeClasspath - Runtime classpath of source set 'main'.
9497
\\--- org.apache.commons:commons-text:1.11.0
9598
99+
'''
100+
}
101+
102+
def "can reduce dependency scope to compile only for non-standard variants"() {
103+
given:
104+
buildFile << """
105+
jvmDependencyConflicts {
106+
patch {
107+
module("com.google.guava:guava") {
108+
reduceToCompileOnlyApiDependency("com.google.errorprone:error_prone_annotations")
109+
reduceToCompileOnlyApiDependency("org.jspecify:jspecify")
110+
reduceToCompileOnlyApiDependency("com.google.j2objc:j2objc-annotations")
111+
}
112+
}
113+
}
114+
dependencies {
115+
implementation("com.google.guava:guava:33.4.8-jre")
116+
}
117+
"""
118+
119+
expect: 'All dependencies are present on the compile classpath'
120+
dependenciesCompile().output.contains '''
121+
compileClasspath - Compile classpath for source set 'main'.
122+
\\--- com.google.guava:guava:33.4.8-jre
123+
+--- com.google.guava:failureaccess:1.0.3
124+
+--- org.jspecify:jspecify:1.0.0
125+
+--- com.google.errorprone:error_prone_annotations:2.36.0
126+
\\--- com.google.j2objc:j2objc-annotations:3.0.0
127+
'''
128+
129+
and: 'Annotation libraries are not present on the runtime classpath'
130+
dependenciesRuntime().output.contains '''
131+
runtimeClasspath - Runtime classpath of source set 'main'.
132+
\\--- com.google.guava:guava:33.4.8-jre
133+
\\--- com.google.guava:failureaccess:1.0.3
96134
'''
97135
}
98136

0 commit comments

Comments
 (0)