Skip to content

Commit

Permalink
Fix KAPT config name finding to discover SPI Plugin for aggregating j…
Browse files Browse the repository at this point in the history
…avac compile task.

This change also moves the creation of the hiltAnnotationProcessor configuration earlier since creating it during task configuration is not required and can lead to some issues if the configuration contained is locked.

Updated the SPIPluginTest.kt to verify behaviour with KAPT.

Fixes #3464

RELNOTES=N/A
PiperOrigin-RevId: 511799130
  • Loading branch information
danysantiago authored and Dagger Team committed Feb 23, 2023
1 parent ba66b29 commit 68a637a
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 20 deletions.
1 change: 1 addition & 0 deletions java/dagger/hilt/android/plugin/main/build.gradle
Expand Up @@ -72,6 +72,7 @@ dependencies {
testImplementation 'junit:junit:4.12'
testImplementation 'com.google.truth:truth:1.0.1'
testPluginCompile 'com.android.tools.build:gradle:7.1.2'
testPluginCompile 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.0'
}

// Configure the generating task of plugin-under-test-metadata.properties to
Expand Down
Expand Up @@ -325,6 +325,22 @@ class HiltGradlePlugin @Inject constructor(
project.files(variant.javaCompileProvider.map {it.destinationDirectory.get() })
)

val hiltAnnotationProcessorConfiguration = project.configurations.create(
"hiltAnnotationProcessor${variant.name.capitalize()}"
).also { config ->
config.isCanBeConsumed = false
config.isCanBeResolved = true
// Add user annotation processor configuration, so that SPI plugins and other processors
// are discoverable.
val apConfigurations: List<Configuration> = mutableListOf<Configuration>().apply {
add(variant.annotationProcessorConfiguration)
project.configurations.findByName(getKaptConfigName(variant))?.let { add(it) }
}
config.extendsFrom(*apConfigurations.toTypedArray())
// Add hilt-compiler even though it might be in the AP configurations already.
project.dependencies.add(config.name, "com.google.dagger:hilt-compiler:$HILT_VERSION")
}

fun getInputClasspath(artifactAttributeValue: String) =
mutableListOf<Configuration>().apply {
@Suppress("DEPRECATION") // Older variant API is deprecated
Expand Down Expand Up @@ -399,21 +415,7 @@ class HiltGradlePlugin @Inject constructor(
}
compileTask.destinationDirectory.set(componentClasses.singleFile)
compileTask.options.apply {
annotationProcessorPath = project.configurations.create(
"hiltAnnotationProcessor${variant.name.capitalize()}"
).also { config ->
config.isCanBeConsumed = false
config.isCanBeResolved = true
// Add user annotation processor configuration, so that SPI plugins and other processors
// are discoverable.
val apConfigurations: List<Configuration> = mutableListOf<Configuration>().apply {
add(variant.annotationProcessorConfiguration)
project.configurations.findByName(getKaptConfigName(variant))?.let { add(it) }
}
config.extendsFrom(*apConfigurations.toTypedArray())
// Add hilt-compiler even though it might be in the AP configurations already.
project.dependencies.add(config.name, "com.google.dagger:hilt-compiler:$HILT_VERSION")
}
annotationProcessorPath = hiltAnnotationProcessorConfiguration
generatedSourceOutputDirectory.set(
project.file(
project.buildDir.resolve("generated/hilt/component_sources/${variant.name}/")
Expand Down
Expand Up @@ -31,6 +31,6 @@ internal fun getKaptConfigName(variant: com.android.build.gradle.api.BaseVariant
is com.android.build.gradle.api.UnitTestVariant ->
"kaptTest${variant.name.substringBeforeLast("UnitTest").capitalize()}"
else ->
"kapt${variant.name}"
"kapt${variant.name.capitalize()}"
}
}
Expand Up @@ -22,10 +22,13 @@ import org.junit.rules.TemporaryFolder

/** Testing utility class that sets up a simple Android project that applies the Hilt plugin. */
class GradleTestRunner(val tempFolder: TemporaryFolder) {
private val pluginClasspaths = mutableListOf<String>()
private val pluginIds = mutableListOf<String>()
private val dependencies = mutableListOf<String>()
private val activities = mutableListOf<String>()
private val additionalAndroidOptions = mutableListOf<String>()
private val hiltOptions = mutableListOf<String>()
private val additionalClosures = mutableListOf<String>()
private var appClassName: String? = null
private var buildFile: File? = null
private var gradlePropertiesFile: File? = null
Expand All @@ -39,6 +42,17 @@ class GradleTestRunner(val tempFolder: TemporaryFolder) {
tempFolder.newFolder("src", "main", "res")
}

// Adds a Gradle plugin classpath to the test project,
// e.g. "org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.0"
fun addPluginClasspath(pluginClasspath: String) {
pluginClasspaths.add(pluginClasspath)
}

// Adds a Gradle plugin id to the test project, e.g. "kotlin-android"
fun addPluginId(pluginId: String) {
pluginIds.add(pluginId)
}

// Adds project dependencies, e.g. "implementation <group>:<id>:<version>"
fun addDependencies(vararg deps: String) {
dependencies.addAll(deps)
Expand All @@ -61,6 +75,10 @@ class GradleTestRunner(val tempFolder: TemporaryFolder) {
hiltOptions.addAll(options)
}

fun addAdditionalClosure(closure: String) {
additionalClosures.add(closure)
}

// Adds a source package to the project. The package path is relative to 'src/main/java'.
fun addSrcPackage(packagePath: String) {
File(tempFolder.root, "src/main/java/$packagePath").mkdirs()
Expand Down Expand Up @@ -127,12 +145,14 @@ class GradleTestRunner(val tempFolder: TemporaryFolder) {
}
dependencies {
classpath 'com.android.tools.build:gradle:7.1.2'
${pluginClasspaths.joinToString(separator = "\n") { "classpath '$it'" }}
}
}
plugins {
id '${ if (isAppProject) "com.android.application" else "com.android.library" }'
id 'com.google.dagger.hilt.android'
${pluginIds.joinToString(separator = "\n") { "id '$it'" }}
}
android {
Expand Down Expand Up @@ -168,6 +188,7 @@ class GradleTestRunner(val tempFolder: TemporaryFolder) {
hilt {
${hiltOptions.joinToString(separator = "\n")}
}
${additionalClosures.joinToString(separator = "\n")}
""".trimIndent()
)
}
Expand Down Expand Up @@ -207,7 +228,7 @@ class GradleTestRunner(val tempFolder: TemporaryFolder) {
.withProjectDir(tempFolder.root)
.withArguments(listOf("--stacktrace", "assembleDebug") + additionalTasks)
.withPluginClasspath()
// .withDebug(true) // Add this line to enable attaching a debugger to the gradle test
.withDebug(true) // Add this line to enable attaching a debugger to the gradle test
// invocation
.forwardOutput()

Expand Down
Expand Up @@ -21,8 +21,11 @@ import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
import org.junit.runner.RunWith
import org.junit.runners.Parameterized

class SPIPluginTest {
@RunWith(Parameterized::class)
class SPIPluginTest(val withKapt: Boolean) {
@get:Rule
val testProjectDir = TemporaryFolder()

Expand All @@ -40,12 +43,23 @@ class SPIPluginTest {
""".trimIndent()
)
}
val processorConfig = if (withKapt) "kapt" else "annotationProcessor"
if (withKapt) {
gradleRunner.addPluginClasspath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.0")
gradleRunner.addPluginId("kotlin-android")
gradleRunner.addPluginId("kotlin-kapt")
gradleRunner.addAdditionalClosure("""
|kotlin {
| jvmToolchain(11)
|}
""".trimMargin())
}
gradleRunner.addHiltOption("enableAggregatingTask = true")
gradleRunner.addDependencies(
"implementation 'androidx.appcompat:appcompat:1.1.0'",
"implementation 'com.google.dagger:hilt-android:LOCAL-SNAPSHOT'",
"annotationProcessor 'com.google.dagger:hilt-compiler:LOCAL-SNAPSHOT'",
"annotationProcessor project(':spi-plugin')",
"$processorConfig 'com.google.dagger:hilt-compiler:LOCAL-SNAPSHOT'",
"$processorConfig project(':spi-plugin')",
)
gradleRunner.addSrc(
srcPath = "minimal/MyApp.java",
Expand Down Expand Up @@ -74,4 +88,10 @@ class SPIPluginTest {
"[spi.TestPlugin] Found component: minimal.MyApp_HiltComponents.SingletonC"
)
}

companion object {
@JvmStatic
@Parameterized.Parameters(name = "withKapt = {0}")
fun params() = listOf(false, true)
}
}

0 comments on commit 68a637a

Please sign in to comment.