Skip to content

Commit

Permalink
Fix configuration cache compatibility when kotlin plugin is applied
Browse files Browse the repository at this point in the history
  • Loading branch information
ghale committed Feb 18, 2021
1 parent 42ed0cb commit ed384a0
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ class RoomSchemaLocationWorkaround implements Workaround {
// Project extension to hold all of the Room configuration
def roomExtension = project.extensions.create("room", RoomExtension)

// Grab fileOperations so we can do copy/sync operations
def fileOperations = project.fileOperations

// Create a task that will be used to merge the task-specific schema locations to the directory (or directories)
// originally specified. This allows us to fan out the generated output and keep good cacheability for the
// compile/kapt tasks but still join everything later in the location the user expects.
Expand All @@ -93,8 +96,6 @@ class RoomSchemaLocationWorkaround implements Workaround {
def taskSpecificSchemaDir = project.objects.directoryProperty()
taskSpecificSchemaDir.set(getTaskSpecificSchemaDir(task))

def fileOperations = project.fileOperations

// Add a command line argument provider to the task-specific list of providers
task.options.compilerArgumentProviders.add(
new JavaCompilerRoomSchemaLocationArgumentProvider(roomExtension.schemaLocationDir, taskSpecificSchemaDir)
Expand Down Expand Up @@ -134,14 +135,16 @@ class RoomSchemaLocationWorkaround implements Workaround {
// pre-seeding the directory with existing schemas should be a capability of the room annotation processor
// somehow?
def configureKaptTask = { Task task ->
task.ext.annotationProcessorOptionProviders = getAccessibleField(task.class, "annotationProcessorOptionProviders").get(task)

task.doFirst onlyIfAnnotationProcessorConfiguredForKapt(task) { KaptRoomSchemaLocationArgumentProvider provider ->
// Populate the variant-specific schemas dir with the existing schemas
copyExistingSchemasToTaskSpecificTmpDirForKapt(project.fileOperations, roomExtension.schemaLocationDir, provider)
copyExistingSchemasToTaskSpecificTmpDirForKapt(fileOperations, roomExtension.schemaLocationDir, provider)
}

task.doLast onlyIfAnnotationProcessorConfiguredForKapt(task) { KaptRoomSchemaLocationArgumentProvider provider ->
// Copy the generated schemas into the registered output directory
copyGeneratedSchemasToOutputDirForKapt(task, provider)
copyGeneratedSchemasToOutputDirForKapt(fileOperations, provider)
}

task.finalizedBy onlyIfAnnotationProcessorConfiguredForKapt(task) { roomExtension.schemaLocationDir.isPresent() ? mergeTask : null }
Expand Down Expand Up @@ -170,8 +173,7 @@ class RoomSchemaLocationWorkaround implements Workaround {
}

private static KaptRoomSchemaLocationArgumentProvider getKaptRoomSchemaLocationArgumentProvider(Task task) {
def annotationProcessorOptionProviders = getAccessibleField(task.class, "annotationProcessorOptionProviders").get(task)
return annotationProcessorOptionProviders.flatten().find { it instanceof KaptRoomSchemaLocationArgumentProvider }
return task.extensions.ext.annotationProcessorOptionProviders.flatten().find { it instanceof KaptRoomSchemaLocationArgumentProvider }
}

private static Closure onlyIfAnnotationProcessorConfiguredForKapt(Task task, Closure<?> action) {
Expand Down Expand Up @@ -228,17 +230,17 @@ class RoomSchemaLocationWorkaround implements Workaround {
copyExistingSchemasToTaskSpecificTmpDir(fileOperations, existingSchemaDir, temporaryVariantSpecificSchemaDir)
}

private static void copyGeneratedSchemasToOutputDirForKapt(Task task, KaptRoomSchemaLocationArgumentProvider provider) {
private static void copyGeneratedSchemasToOutputDirForKapt(FileOperations fileOperations, KaptRoomSchemaLocationArgumentProvider provider) {
// Copy the generated generated schemas from the task-specific tmp dir to the
// task-specific output dir. This dance prevents the kapt task from clearing out
// the existing schemas before the annotation processors run
// Derive the variant directory from the command line provider it is configured with
def variantSpecificSchemaDir = provider.schemaLocationDir
def temporaryVariantSpecificSchemaDir = provider.temporarySchemaLocationDir

task.project.sync {
from temporaryVariantSpecificSchemaDir
into variantSpecificSchemaDir
fileOperations.sync {
it.from temporaryVariantSpecificSchemaDir
it.into variantSpecificSchemaDir
}
}

Expand Down
22 changes: 20 additions & 2 deletions src/test/groovy/org/gradle/android/ConfigurationCachingTest.groovy
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
package org.gradle.android

import org.gradle.testkit.runner.BuildResult
import org.gradle.util.VersionNumber

class ConfigurationCachingTest extends AbstractTest {
def "Can run with configuration cache"() {
private static final VersionNumber SUPPORTED_KOTLIN_VERSION = VersionNumber.parse("1.4.30")

def "plugin is compatible with configuration cache"() {
given:
SimpleAndroidApp.builder(temporaryFolder.root, cacheDir)
.withAndroidVersion(Versions.latestAndroidVersion())
.withKotlinDisabled()
.withKotlinVersion(SUPPORTED_KOTLIN_VERSION)
.build()
.writeProject()

Expand All @@ -17,5 +22,18 @@ class ConfigurationCachingTest extends AbstractTest {

then:
!result.output.contains("problems were found storing the configuration cache")

when:
result = withGradleVersion(Versions.latestGradleVersion().version)
.withProjectDir(temporaryFolder.root)
.withArguments('--configuration-cache', 'assembleDebug')
.build()

then:
assertConfigurationCacheIsReused(result)
}

void assertConfigurationCacheIsReused(BuildResult result) {
assert result.output.contains('Reusing configuration cache.')
}
}

0 comments on commit ed384a0

Please sign in to comment.