diff --git a/java/dagger/hilt/android/plugin/src/main/kotlin/dagger/hilt/android/plugin/AndroidEntryPointClassVisitor.kt b/java/dagger/hilt/android/plugin/src/main/kotlin/dagger/hilt/android/plugin/AndroidEntryPointClassVisitor.kt index 4134738fe17..4d3345819ba 100644 --- a/java/dagger/hilt/android/plugin/src/main/kotlin/dagger/hilt/android/plugin/AndroidEntryPointClassVisitor.kt +++ b/java/dagger/hilt/android/plugin/src/main/kotlin/dagger/hilt/android/plugin/AndroidEntryPointClassVisitor.kt @@ -6,7 +6,7 @@ import com.android.build.api.instrumentation.ClassData import com.android.build.api.instrumentation.InstrumentationParameters import java.io.File import org.gradle.api.provider.Property -import org.gradle.api.tasks.Input +import org.gradle.api.tasks.Internal import org.objectweb.asm.ClassReader import org.objectweb.asm.ClassVisitor import org.objectweb.asm.FieldVisitor @@ -25,7 +25,7 @@ class AndroidEntryPointClassVisitor( @Suppress("UnstableApiUsage") // ASM Pipeline APIs interface AndroidEntryPointParams : InstrumentationParameters { - @get:Input + @get:Internal val additionalClassesDir: Property } diff --git a/java/dagger/hilt/android/plugin/src/test/kotlin/BuildCacheTest.kt b/java/dagger/hilt/android/plugin/src/test/kotlin/BuildCacheTest.kt new file mode 100644 index 00000000000..44a95688d5c --- /dev/null +++ b/java/dagger/hilt/android/plugin/src/test/kotlin/BuildCacheTest.kt @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2020 The Dagger Authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.util.UUID +import org.gradle.testkit.runner.TaskOutcome.FROM_CACHE +import org.gradle.testkit.runner.TaskOutcome.SUCCESS +import org.junit.Assert.assertEquals +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.rules.TemporaryFolder + +// Test that verifies the hilt class transform does not break the Gradle's remote build cache. +class BuildCacheTest { + @get:Rule + val gradleHomeFolder = TemporaryFolder() + + @get:Rule + val firstProjectDir = TemporaryFolder() + + lateinit var firstGradleRunner: GradleTestRunner + + @get:Rule + val secondProjectDir = TemporaryFolder() + + lateinit var secondGradleRunner: GradleTestRunner + + private val testId = UUID.randomUUID().toString() + + @Before + fun setup() { + firstGradleRunner = createGradleRunner(firstProjectDir) + secondGradleRunner = createGradleRunner(secondProjectDir) + } + + private fun createGradleRunner(folder: TemporaryFolder): GradleTestRunner { + val gradleRunner = GradleTestRunner(folder) + 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'", + ) + gradleRunner.runAdditionalTasks("--build-cache") + gradleRunner.addSrc( + srcPath = "minimal/MyApp.java", + srcContent = + """ + package minimal; + + import android.app.Application; + + @dagger.hilt.android.HiltAndroidApp + public class MyApp extends Application { + // random id inserted into the code to ensure that the first is never a cache hit and the + // second run always is + public static String RANDOM_ID = "$testId"; + } + """.trimIndent() + ) + gradleRunner.setAppClassName(".MyApp") + return gradleRunner + } + + // Verifies that library B and library C injected classes are available in the root classpath. + @Test + fun test_buildCacheHitOnRelocatedProject() { + val firstResult = firstGradleRunner.build() + assertEquals(firstResult.getTask(":transformDebugClassesWithAsm").outcome, SUCCESS) + + val secondResult = secondGradleRunner.build() + val cacheableTasks = listOf( + ":checkDebugAarMetadata", + ":checkDebugDuplicateClasses", + ":compileDebugJavaWithJavac", + ":compressDebugAssets", + ":extractDeepLinksDebug", + ":generateDebugBuildConfig", + ":generateDebugResValues", + ":javaPreCompileDebug", + ":mergeDebugAssets", + ":mergeDebugJavaResource", + ":mergeDebugJniLibFolders", + ":mergeDebugNativeLibs", + ":mergeDebugShaders", + ":mergeExtDexDebug", + ":mergeLibDexDebug", + ":mergeProjectDexDebug", + ":processDebugManifestForPackage", + ":transformDebugClassesWithAsm", + ":validateSigningDebug", + ":writeDebugAppMetadata", + ":writeDebugSigningConfigVersions", + ) + + val tasksFromCache = + secondResult.tasks.filter { it.outcome == FROM_CACHE }.map { it.path }.sorted() + assertEquals(cacheableTasks, tasksFromCache) + } +} diff --git a/java/dagger/hilt/android/plugin/src/test/kotlin/GradleTestRunner.kt b/java/dagger/hilt/android/plugin/src/test/kotlin/GradleTestRunner.kt index 20a8e19ebc0..759bc49051b 100644 --- a/java/dagger/hilt/android/plugin/src/test/kotlin/GradleTestRunner.kt +++ b/java/dagger/hilt/android/plugin/src/test/kotlin/GradleTestRunner.kt @@ -16,6 +16,7 @@ import java.io.File import org.gradle.testkit.runner.BuildResult +import org.gradle.testkit.runner.BuildTask import org.gradle.testkit.runner.GradleRunner import org.junit.rules.TemporaryFolder @@ -206,6 +207,9 @@ class GradleTestRunner(val tempFolder: TemporaryFolder) { private val projectRoot: File, private val buildResult: BuildResult ) { + + val tasks: List get() = buildResult.tasks + // Finds a task by name. fun getTask(name: String) = buildResult.task(name) ?: error("Task '$name' not found.") diff --git a/java/dagger/hilt/android/plugin/src/test/kotlin/NoTransformTest.kt b/java/dagger/hilt/android/plugin/src/test/kotlin/NoTransformTest.kt new file mode 100644 index 00000000000..cb67c2c128c --- /dev/null +++ b/java/dagger/hilt/android/plugin/src/test/kotlin/NoTransformTest.kt @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2020 The Dagger Authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.gradle.testkit.runner.TaskOutcome +import org.junit.Assert +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.rules.TemporaryFolder + +class NoTransformTest { + + @get:Rule + val testProjectDir = TemporaryFolder() + + lateinit var gradleRunner: GradleTestRunner + + @Before + fun setup() { + gradleRunner = GradleTestRunner(testProjectDir) + } + + // Simple functional test to verify transformation. + @Test + fun testAssemble() { + 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'" + ) + gradleRunner.addAndroidOption( + "buildFeatures.buildConfig = false" + ) + + val result = gradleRunner.build() + val assembleTask = result.getTask(":assembleDebug") + Assert.assertEquals(TaskOutcome.SUCCESS, assembleTask.outcome) + } +}