Skip to content

Commit

Permalink
This was changed to mark it as @internal to make sure the field is ig…
Browse files Browse the repository at this point in the history
…nored in the cache-key calculation.

I added a unit test which, when run on the current master fails because the :transformDebugClassesWithAsm results in a cache miss. On this branch it does succeed.

Fixes #2763
Closes #2775

RELNOTES=Fix a remote cache miss due to @input parameter in ASM transform.
COPYBARA_INTEGRATE_REVIEW=#2775 from remcomokveld:rm/remote-build-cache-fix e093fe0
PiperOrigin-RevId: 387379476
  • Loading branch information
remcomokveld authored and Dagger Team committed Jul 28, 2021
1 parent ef7e7a1 commit 2f50035
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -25,7 +25,7 @@ class AndroidEntryPointClassVisitor(

@Suppress("UnstableApiUsage") // ASM Pipeline APIs
interface AndroidEntryPointParams : InstrumentationParameters {
@get:Input
@get:Internal
val additionalClassesDir: Property<File>
}

Expand Down
112 changes: 112 additions & 0 deletions java/dagger/hilt/android/plugin/src/test/kotlin/BuildCacheTest.kt
Original file line number Diff line number Diff line change
@@ -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)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -206,6 +207,9 @@ class GradleTestRunner(val tempFolder: TemporaryFolder) {
private val projectRoot: File,
private val buildResult: BuildResult
) {

val tasks: List<BuildTask> get() = buildResult.tasks

// Finds a task by name.
fun getTask(name: String) = buildResult.task(name) ?: error("Task '$name' not found.")

Expand Down
52 changes: 52 additions & 0 deletions java/dagger/hilt/android/plugin/src/test/kotlin/NoTransformTest.kt
Original file line number Diff line number Diff line change
@@ -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)
}
}

0 comments on commit 2f50035

Please sign in to comment.