Skip to content

Commit 2da8f31

Browse files
committed
Use correct artifactIds in GMM, too
1 parent e4dcfc9 commit 2da8f31

File tree

2 files changed

+92
-8
lines changed

2 files changed

+92
-8
lines changed

build-logic/src/main/kotlin/Deployment.kt

Lines changed: 87 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,21 @@
22

33
import groovy.lang.Closure
44
import groovy.util.Node
5-
import org.gradle.api.NamedDomainObjectCollection
65
import org.gradle.api.Project
76
import org.gradle.api.artifacts.Dependency
87
import org.gradle.api.artifacts.ProjectDependency
98
import org.gradle.api.plugins.ExtensionAware
109
import org.gradle.api.plugins.ExtraPropertiesExtension
1110
import org.gradle.api.publish.PublishingExtension
1211
import org.gradle.api.publish.internal.PublicationInternal
12+
import org.gradle.api.publish.internal.metadata.ModuleMetadataSpec
1313
import org.gradle.api.publish.maven.MavenArtifact
1414
import org.gradle.api.publish.maven.MavenPublication
15-
import org.gradle.api.publish.maven.internal.publication.DefaultMavenPublication
1615
import org.gradle.api.publish.maven.tasks.AbstractPublishToMaven
16+
import org.gradle.api.publish.tasks.GenerateModuleMetadata
1717
import org.gradle.api.tasks.SourceSet
1818
import org.gradle.api.tasks.SourceSetContainer
19+
import org.gradle.internal.Try
1920
import org.gradle.jvm.tasks.Jar
2021
import org.gradle.kotlin.dsl.closureOf
2122
import org.gradle.kotlin.dsl.maybeCreate
@@ -25,7 +26,8 @@ import org.gradle.kotlin.dsl.withGroovyBuilder
2526
import org.gradle.kotlin.dsl.withType
2627
import org.gradle.plugins.signing.Sign
2728
import org.gradle.plugins.signing.SigningExtension
28-
import java.io.File
29+
import java.lang.reflect.Field
30+
import java.lang.reflect.Method
2931

3032
/**
3133
* Configure deployment tasks and properties for a project using the provided [deployConfig].
@@ -146,9 +148,25 @@ private fun Project.configureAndroidDeployment(
146148
}
147149

148150
// Disable main publication
149-
tasks.withType<AbstractPublishToMaven>().configureEach {
151+
tasks.withType<AbstractPublishToMaven> {
150152
isEnabled = "Main" !in name
151153
}
154+
155+
// Hook into Gradle module metadata generation
156+
// and replace project references (e.g. "core") with the correct
157+
// Maven dependency coordinates ("android-test-core")
158+
tasks.withType<GenerateModuleMetadata> {
159+
val junit = SupportedJUnit.values()
160+
.firstOrNull { name.contains(it.variant, ignoreCase = true) }
161+
162+
if (junit != null) {
163+
val modifier = ReflectiveModuleMetadataModifier(this, junit)
164+
165+
doFirst {
166+
modifier.run()
167+
}
168+
}
169+
}
152170
}
153171

154172
private fun Project.configurePluginDeployment(
@@ -465,3 +483,68 @@ private fun Project.centralPublishing(
465483
}
466484
}
467485
}
486+
487+
/**
488+
* Gradle module metadata modifier, replacing references to instrumentation libraries
489+
* with the correct artifact ID in each module's JSON file (build/publications/.../module.json).
490+
*/
491+
private class ReflectiveModuleMetadataModifier(
492+
private val task: GenerateModuleMetadata,
493+
private val junit: SupportedJUnit
494+
) {
495+
@Suppress("UNCHECKED_CAST")
496+
private companion object {
497+
private val reflectiveMethodCache = mutableMapOf<Class<*>, MutableMap<String, Method>>()
498+
private val reflectiveFieldCache = mutableMapOf<Class<*>, MutableMap<String, Field>>()
499+
500+
fun <R : Any> method(cls: Class<*>, named: String, receiver: Any, vararg args: Any): R {
501+
val methods = reflectiveMethodCache.getOrPut(cls, ::mutableMapOf)
502+
val method = methods.getOrPut(named) {
503+
cls.getDeclaredMethod(named).also { it.isAccessible = true }
504+
}
505+
return method.invoke(receiver, *args) as R
506+
}
507+
508+
fun field(cls: Class<*>, named: String): Field {
509+
val fields = reflectiveFieldCache.getOrPut(cls, ::mutableMapOf)
510+
val field = fields.getOrPut(named) {
511+
cls.getDeclaredField(named).also { it.isAccessible = true }
512+
}
513+
return field
514+
}
515+
516+
fun <R : Any> Any.field(named: String): R = field(this.javaClass, named).get(this) as R
517+
}
518+
519+
fun run() {
520+
// Access the inputs of the task, then crawl through to the dependencies
521+
// of each variant inside its module metadata. Rewrite the coordinates of each
522+
// instrumentation lib found inside there.
523+
val inputState = method<Any>(GenerateModuleMetadata::class.java, "inputState", task)
524+
val metadataSpecTry = inputState.field<Try<ModuleMetadataSpec>>("moduleMetadataSpec")
525+
val metadataSpec = metadataSpecTry.get()
526+
val variants = metadataSpec.field<List<Any>>("variants")
527+
528+
for (variant in variants) {
529+
val variantDependencies =
530+
runCatching { variant.field<List<Any>>("dependencies") }
531+
.getOrNull()
532+
?: continue
533+
534+
for (variantDependency in variantDependencies) {
535+
val depCoordinates = variantDependency.field<Any>("coordinates")
536+
val depGroup = depCoordinates.field<String>("group")
537+
val depName = depCoordinates.field<String>("name")
538+
539+
if (depGroup == Artifacts.Instrumentation.groupId) {
540+
Artifacts.from(depName)?.let { replacement ->
541+
field(depCoordinates.javaClass, "name").set(
542+
depCoordinates,
543+
suffixedArtifactId(replacement.artifactId, junit)
544+
)
545+
}
546+
}
547+
}
548+
}
549+
}
550+
}

build-logic/src/main/kotlin/Environment.kt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,14 @@ object Artifacts {
8888
const val LICENSE = "Apache-2.0"
8989

9090
/**
91-
* Retrieve the artifact configuration based on a Gradle project reference.
92-
* Return null if none can be found
91+
* Retrieve the artifact configuration based on a string name, or null if none can be found
9392
*/
94-
fun from(project: Project) =
95-
when (project.name) {
93+
fun from(name: String): Deployed? =
94+
when (name) {
9695
"core" -> Instrumentation.Core
96+
"extensions" -> Instrumentation.Extensions
9797
"runner" -> Instrumentation.Runner
98+
"compose" -> Instrumentation.Compose
9899
"android-junit5" -> Plugin
99100
else -> null
100101
}

0 commit comments

Comments
 (0)