1
1
package org.gradle.android.workarounds
2
2
3
-
4
3
import org.gradle.android.AndroidIssue
5
4
import org.gradle.api.DefaultTask
6
5
import org.gradle.api.Project
7
6
import org.gradle.api.Task
7
+ import org.gradle.api.execution.TaskExecutionGraph
8
8
import org.gradle.api.file.ConfigurableFileCollection
9
9
import org.gradle.api.file.Directory
10
10
import org.gradle.api.file.DirectoryProperty
@@ -13,6 +13,7 @@ import org.gradle.api.internal.file.FileOperations
13
13
import org.gradle.api.model.ObjectFactory
14
14
import org.gradle.api.provider.Provider
15
15
import org.gradle.api.tasks.Internal
16
+ import org.gradle.api.tasks.Optional
16
17
import org.gradle.api.tasks.OutputDirectory
17
18
import org.gradle.api.tasks.TaskAction
18
19
import org.gradle.api.tasks.TaskProvider
@@ -22,6 +23,7 @@ import org.gradle.util.VersionNumber
22
23
23
24
import javax.inject.Inject
24
25
import java.lang.reflect.Field
26
+ import java.util.function.Supplier
25
27
26
28
/**
27
29
* Changes annotation processor arguments to set the room.schemaLocation via a CommandLineArgsProcessor
@@ -72,13 +74,18 @@ class RoomSchemaLocationWorkaround implements Workaround {
72
74
// Grab fileOperations so we can do copy/sync operations
73
75
def fileOperations = project. fileOperations
74
76
77
+ // An undefined directory property for use when providers are disabled
78
+ def nullDirectory = project. objects. directoryProperty()
79
+
75
80
// Create a task that will be used to merge the task-specific schema locations to the directory (or directories)
76
81
// originally specified. This allows us to fan out the generated output and keep good cacheability for the
77
82
// compile/kapt tasks but still join everything later in the location the user expects.
78
83
TaskProvider<RoomSchemaLocationMergeTask > mergeTask = project. tasks. register(" mergeRoomSchemaLocations" , RoomSchemaLocationMergeTask ) {
79
84
roomSchemaMergeLocations = roomExtension. roomSchemaMergeLocations
80
85
}
81
86
87
+ boolean javaCompileSchemaGenerationEnabled = true
88
+
82
89
def configureVariant = { variant ->
83
90
// Make sure that the annotation processor argument has not been explicitly configured in the Android
84
91
// configuration (i.e. we only want this configured through the room extension
@@ -98,15 +105,21 @@ class RoomSchemaLocationWorkaround implements Workaround {
98
105
99
106
// Add a command line argument provider to the task-specific list of providers
100
107
task. options. compilerArgumentProviders. add(
101
- new JavaCompilerRoomSchemaLocationArgumentProvider (roomExtension. schemaLocationDir, taskSpecificSchemaDir)
108
+ new JavaCompilerRoomSchemaLocationArgumentProvider (roomExtension. schemaLocationDir, taskSpecificSchemaDir, nullDirectory, { javaCompileSchemaGenerationEnabled } as Supplier )
102
109
)
103
110
104
111
// Register the generated schemas to be merged back to the original specified schema directory
105
- roomExtension. registerOutputDirectory(taskSpecificSchemaDir)
112
+ task. project. gradle. taskGraph. whenReady { TaskExecutionGraph graph ->
113
+ if (graph. hasTask(task)) {
114
+ roomExtension. registerOutputDirectory(taskSpecificSchemaDir)
115
+ }
116
+ }
106
117
107
118
// Seed the task-specific generated schema dir with the existing schemas
108
119
task. doFirst {
109
- copyExistingSchemasToTaskSpecificTmpDir(fileOperations, roomExtension. schemaLocationDir, taskSpecificSchemaDir)
120
+ if (javaCompileSchemaGenerationEnabled) {
121
+ copyExistingSchemasToTaskSpecificTmpDir(fileOperations, roomExtension. schemaLocationDir, taskSpecificSchemaDir)
122
+ }
110
123
}
111
124
112
125
task. finalizedBy { roomExtension. schemaLocationDir. isPresent() ? mergeTask : null }
@@ -122,10 +135,7 @@ class RoomSchemaLocationWorkaround implements Workaround {
122
135
applyToAllAndroidVariants(project) { variant ->
123
136
def variantSpecificSchemaDir = project. objects. directoryProperty()
124
137
variantSpecificSchemaDir. set(getVariantSpecificSchemaDir(project, " kapt${ variant.name.capitalize()} Kotlin" ))
125
- variant. javaCompileOptions. annotationProcessorOptions. compilerArgumentProviders. add(new KaptRoomSchemaLocationArgumentProvider (roomExtension. schemaLocationDir, variantSpecificSchemaDir))
126
-
127
- // Register the variant-specific directory with the merge task
128
- roomExtension. registerOutputDirectory(variantSpecificSchemaDir)
138
+ variant. javaCompileOptions. annotationProcessorOptions. compilerArgumentProviders. add(new KaptRoomSchemaLocationArgumentProvider (roomExtension. schemaLocationDir, variantSpecificSchemaDir, nullDirectory))
129
139
}
130
140
131
141
// Kapt tasks will remove the contents of any output directories, which will interfere with any additional
@@ -148,27 +158,24 @@ class RoomSchemaLocationWorkaround implements Workaround {
148
158
}
149
159
150
160
task. finalizedBy onlyIfAnnotationProcessorConfiguredForKapt(annotationProcessorOptionProviders) { roomExtension. schemaLocationDir. isPresent() ? mergeTask : null }
161
+
162
+ TaskExecutionGraph taskGraph = task. project. gradle. taskGraph
163
+ taskGraph. whenReady onlyIfAnnotationProcessorConfiguredForKapt(annotationProcessorOptionProviders) { KaptRoomSchemaLocationArgumentProvider provider ->
164
+ if (taskGraph. hasTask(task)) {
165
+ // Register the variant-specific directory with the merge task
166
+ roomExtension. registerOutputDirectory(provider. schemaLocationDir)
167
+ }
168
+ }
151
169
}
152
170
153
171
project. tasks. withType(kaptWithoutKotlincTaskClass). configureEach(configureKaptTask)
154
172
project. tasks. withType(kaptWithKotlincTaskClass). configureEach(configureKaptTask)
155
173
156
- // Since we've added a new kapt-specific provider to the variant, go through the
157
- // JavaCompile tasks and remove this provider from its task-specific list so that
158
- // it only has its JavaCompile-specific provider. This is not great, but there
174
+ // Since we've added a new kapt-specific provider to the variant, disable the provider
175
+ // used for the JavaCompile task. This is not great, but there
159
176
// does not seem to be a way around this with the way the kotlin android plugin
160
177
// maps annotation processor providers from the variant directly onto kapt tasks.
161
- project. afterEvaluate {
162
- project. tasks. withType(JavaCompile ). configureEach { JavaCompile task ->
163
- def itr = task. options. compilerArgumentProviders. iterator()
164
- while (itr. hasNext()) {
165
- def provider = itr. next()
166
- if (provider instanceof KaptRoomSchemaLocationArgumentProvider ) {
167
- itr. remove()
168
- }
169
- }
170
- }
171
- }
178
+ javaCompileSchemaGenerationEnabled = false
172
179
}
173
180
}
174
181
@@ -295,12 +302,20 @@ class RoomSchemaLocationWorkaround implements Workaround {
295
302
@Internal
296
303
final Provider<Directory > configuredSchemaLocationDir
297
304
298
- @OutputDirectory
305
+ @Internal
299
306
final Provider<Directory > schemaLocationDir
300
307
301
- RoomSchemaLocationArgumentProvider (Provider<Directory > configuredSchemaLocationDir , Provider<Directory > schemaLocationDir ) {
308
+ @Internal
309
+ final Supplier<Boolean > enabled
310
+
311
+ @Internal
312
+ final Provider<Directory > nullDirectory
313
+
314
+ RoomSchemaLocationArgumentProvider (Provider<Directory > configuredSchemaLocationDir , Provider<Directory > schemaLocationDir , Provider<Directory > nullDirectory , Supplier<Boolean > enabled ) {
302
315
this . configuredSchemaLocationDir = configuredSchemaLocationDir
316
+ this . enabled = enabled
303
317
this . schemaLocationDir = schemaLocationDir
318
+ this . nullDirectory = nullDirectory
304
319
}
305
320
306
321
@Internal
@@ -310,25 +325,31 @@ class RoomSchemaLocationWorkaround implements Workaround {
310
325
311
326
@Override
312
327
Iterable<String > asArguments () {
313
- if (configuredSchemaLocationDir. isPresent()) {
328
+ if (configuredSchemaLocationDir. isPresent() && enabled . get() ) {
314
329
return [" -A${ ROOM_SCHEMA_LOCATION} =${ schemaLocationPath} " as String ]
315
330
} else {
316
331
return []
317
332
}
318
333
}
334
+
335
+ @OutputDirectory
336
+ @Optional
337
+ Provider<Directory > getEffectiveSchemaLocationDir () {
338
+ return enabled. get() ? schemaLocationDir : nullDirectory
339
+ }
319
340
}
320
341
321
342
static class JavaCompilerRoomSchemaLocationArgumentProvider extends RoomSchemaLocationArgumentProvider {
322
- JavaCompilerRoomSchemaLocationArgumentProvider (Provider<Directory > configuredSchemaLocationDir , Provider<Directory > schemaLocationDir ) {
323
- super (configuredSchemaLocationDir, schemaLocationDir)
343
+ JavaCompilerRoomSchemaLocationArgumentProvider (Provider<Directory > configuredSchemaLocationDir , Provider<Directory > schemaLocationDir , Provider< Directory > nullDirectory , Supplier< Boolean > enabled ) {
344
+ super (configuredSchemaLocationDir, schemaLocationDir, nullDirectory, enabled )
324
345
}
325
346
}
326
347
327
348
static class KaptRoomSchemaLocationArgumentProvider extends RoomSchemaLocationArgumentProvider {
328
349
private Provider<Directory > temporarySchemaLocationDir
329
350
330
- KaptRoomSchemaLocationArgumentProvider (Provider<Directory > configuredSchemaLocationDir , Provider<Directory > schemaLocationDir ) {
331
- super (configuredSchemaLocationDir, schemaLocationDir)
351
+ KaptRoomSchemaLocationArgumentProvider (Provider<Directory > configuredSchemaLocationDir , Provider<Directory > schemaLocationDir , Provider< Directory > nullDirectory ) {
352
+ super (configuredSchemaLocationDir, schemaLocationDir, nullDirectory, { true } as Supplier< Boolean > )
332
353
this . temporarySchemaLocationDir = schemaLocationDir. map {it. dir(" ../${ it.asFile.name} Temp" ) }
333
354
}
334
355
0 commit comments