Skip to content

Commit 1033bad

Browse files
test: add failing test for distributionManagement.relocation.
1 parent daaddac commit 1033bad

File tree

4 files changed

+101
-0
lines changed

4 files changed

+101
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.autonomousapps.jvm
2+
3+
import com.autonomousapps.jvm.projects.PomRelocationProject
4+
import spock.lang.PendingFeature
5+
6+
import static com.autonomousapps.utils.Runner.build
7+
import static com.google.common.truth.Truth.assertThat
8+
9+
/**
10+
* See also discussion in {@link com.autonomousapps.transform.StandardTransform#computeAdvice} function. There we
11+
* deliberately strip possible advice to declare {@code runtimeOnly} dependencies that are in the transitive graph.
12+
* Doing that would likely be disruptive, so a more targeted approach is to try to find some direct way of supporting
13+
* {@code relocation}s in a .pom file.
14+
*/
15+
final class PomRelocationSpec extends AbstractJvmSpec {
16+
17+
@PendingFeature(reason = "Gradle transparently processes the relocation, offering no way for end users to know that it's happened")
18+
def "handles POM distributionManagement.relocation (#gradleVersion)"() {
19+
given:
20+
def project = new PomRelocationProject()
21+
gradleProject = project.gradleProject
22+
23+
when:
24+
build(gradleVersion, gradleProject.rootDir, 'buildHealth', ':proj:reason', '--id', 'com.mysql:mysql-connector-j')
25+
26+
then:
27+
assertThat(project.actualProjectAdvice()).containsExactlyElementsIn(project.expectedProjectAdvice)
28+
29+
where:
30+
gradleVersion << gradleVersions()
31+
}
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package com.autonomousapps.jvm.projects
2+
3+
import com.autonomousapps.AbstractProject
4+
import com.autonomousapps.kit.GradleProject
5+
import com.autonomousapps.model.Advice
6+
import com.autonomousapps.model.ProjectAdvice
7+
8+
import static com.autonomousapps.AdviceHelper.*
9+
import static com.autonomousapps.kit.gradle.Dependency.implementation
10+
import static com.autonomousapps.kit.gradle.Dependency.runtimeOnly
11+
12+
final class PomRelocationProject extends AbstractProject {
13+
14+
/*
15+
* `mysql:mysql-connector-java` pom file:
16+
*
17+
* <groupId>mysql</groupId>
18+
* <artifactId>mysql-connector-java</artifactId>
19+
* <version>8.0.33</version>
20+
* <distributionManagement>
21+
* <relocation>
22+
* <groupId>com.mysql</groupId>
23+
* <artifactId>mysql-connector-j</artifactId>
24+
* <message>MySQL Connector/J artifacts moved to reverse-DNS compliant Maven 2+ coordinates.</message>
25+
* </relocation>
26+
* </distributionManagement>
27+
*/
28+
29+
// This is a shim that redirects to `com.mysql:mysql-connector-j:8.0.33` via `distributionManagement.relocation`.
30+
// Also, this should be runtimeOnly since it's not used at compile- time.
31+
private final mySqlShim = implementation('mysql:mysql-connector-java:8.0.33')
32+
private final mySql = runtimeOnly('com.mysql:mysql-connector-j:8.0.33')
33+
34+
final GradleProject gradleProject
35+
36+
PomRelocationProject() {
37+
this.gradleProject = build()
38+
}
39+
40+
private GradleProject build() {
41+
return newGradleProjectBuilder()
42+
.withSubproject('proj') { c ->
43+
c.withBuildScript { bs ->
44+
bs.plugins = javaLibrary
45+
bs.dependencies(mySqlShim)
46+
}
47+
}
48+
.write()
49+
}
50+
51+
private final Set<Advice> projAdvice = [
52+
Advice.ofRemove(moduleCoordinates(mySqlShim), 'implementation'),
53+
Advice.ofAdd(moduleCoordinates(mySql), 'runtimeOnly'),
54+
]
55+
56+
Set<ProjectAdvice> actualProjectAdvice() {
57+
return actualProjectAdvice(gradleProject)
58+
}
59+
60+
final Set<ProjectAdvice> expectedProjectAdvice = [
61+
projectAdviceForDependencies(':proj', projAdvice),
62+
]
63+
}

src/main/kotlin/com/autonomousapps/tasks/ComputeUsagesTask.kt

+2
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,8 @@ private class GraphVisitor(
316316
private fun noRealCapabilities(dependency: Dependency): Boolean {
317317
if (dependency.capabilities.isEmpty()) return true
318318

319+
// TODO(tsr): this doesn't match the kdoc. Is this wrong or is the kdoc wrong? I think this is wrong, but no tests
320+
// are failing...
319321
val single = dependency.capabilities.values.singleOrNull { it is InferredCapability || it is NativeLibCapability }
320322

321323
return (single as? InferredCapability)?.isCompileOnlyAnnotations == false

src/main/kotlin/com/autonomousapps/transform/StandardTransform.kt

+4
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,10 @@ internal class StandardTransform(
243243
// Don't add unused usages!
244244
.filterUsed()
245245
// Don't add runtimeOnly or compileOnly (compileOnly, compileOnlyApi, providedCompile) declarations
246+
// nb: this probably remains the correct choice, but it can lead to issues when we remove an "unused" dependency
247+
// and fail to add a required runtimeOnly dependency that was part of the unused dep's transitive graph. Removing
248+
// this line would lead to "super strict" declarations that are, perhaps, more bazel-like (every classpath
249+
// consists only of positively-declared dependencies).
246250
.filterNot { it.bucket == Bucket.RUNTIME_ONLY || it.bucket == Bucket.COMPILE_ONLY }
247251
.mapTo(advice) { usage ->
248252
val preferredCoordinatesNotation =

0 commit comments

Comments
 (0)