Improve disambiguation of subplugin option inputs

The original approach required evaluating the existing input properties
of the task. This led to evaluation of the property values, and could
execute incorrectly if the task was not properly initialized at that
moment.
The new approach fixes that by first grouping options from each
subplugin by key and then adding disambiguating index suffixes.
This commit is contained in:
Sergey Igushkin
2017-12-31 02:23:41 +03:00
parent 1be9e04797
commit d881efdeb1
2 changed files with 32 additions and 21 deletions
@@ -246,17 +246,17 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
private fun Kapt3SubpluginContext.buildAndAddOptionsTo(task: Task, container: CompilerPluginOptions, aptMode: String) { private fun Kapt3SubpluginContext.buildAndAddOptionsTo(task: Task, container: CompilerPluginOptions, aptMode: String) {
val compilerPluginId = getCompilerPluginId() val compilerPluginId = getCompilerPluginId()
for (option in wrapPluginOptions(buildOptions(aptMode), "configuration")) { val kaptSubpluginOptions = wrapPluginOptions(buildOptions(aptMode), "configuration")
task.registerSubpluginOptionsAsInputs(compilerPluginId, kaptSubpluginOptions)
for (option in kaptSubpluginOptions) {
container.addPluginArgument(compilerPluginId, option) container.addPluginArgument(compilerPluginId, option)
task.registerSubpluginOptionAsInput(compilerPluginId, option)
} }
// Also register all the subplugin options from the Kotlin task: // Also register all the subplugin options from the Kotlin task:
project.afterEvaluate { project.afterEvaluate {
kotlinCompile.pluginOptions.subpluginOptionsByPluginId.forEach { (pluginId, options) -> kotlinCompile.pluginOptions.subpluginOptionsByPluginId.forEach { (pluginId, options) ->
options.forEach { option -> task.registerSubpluginOptionsAsInputs("kotlinCompile.$pluginId", options)
task.registerSubpluginOptionAsInput("kotlinCompile.$pluginId", option)
}
} }
} }
} }
@@ -826,10 +826,12 @@ internal class SubpluginEnvironment(
val subpluginClasspath = subpluginClasspaths[subplugin] ?: continue val subpluginClasspath = subpluginClasspaths[subplugin] ?: continue
subpluginClasspath.forEach { pluginOptions.addClasspathEntry(it) } subpluginClasspath.forEach { pluginOptions.addClasspathEntry(it) }
for (option in subplugin.apply(project, kotlinTask, javaTask, variantData, androidProjectHandler, javaSourceSet)) { val subpluginOptions = subplugin.apply(project, kotlinTask, javaTask, variantData, androidProjectHandler, javaSourceSet)
val pluginId = subplugin.getCompilerPluginId() val subpluginId = subplugin.getCompilerPluginId()
pluginOptions.addPluginArgument(pluginId, option) kotlinTask.registerSubpluginOptionsAsInputs(subpluginId, subpluginOptions)
kotlinTask.registerSubpluginOptionAsInput(pluginId, option)
for (option in subpluginOptions) {
pluginOptions.addPluginArgument(subpluginId, option)
} }
} }
@@ -837,18 +839,27 @@ internal class SubpluginEnvironment(
} }
} }
internal fun Task.registerSubpluginOptionAsInput(subpluginId: String, option: SubpluginOption) { internal fun Task.registerSubpluginOptionsAsInputs(subpluginId: String, subpluginOptions: List<SubpluginOption>) {
when (option) { // There might be several options with the same key. We group them together
is CompositeSubpluginOption -> { // and add an index to the Gradle input property name to resolve possible duplication:
val subpluginIdWithWrapperKey = "$subpluginId.${option.key}" val pluginOptionsGrouped = subpluginOptions.groupBy { it.key }
option.originalOptions.forEach { registerSubpluginOptionAsInput(subpluginIdWithWrapperKey, it) } for ((optionKey, optionsGroup) in pluginOptionsGrouped) {
} optionsGroup.forEachIndexed { index, option ->
is FilesSubpluginOption -> Unit val indexSuffix = if (optionsGroup.size > 1) ".$index" else ""
else -> { when (option) {
// Since there might be multiple subplugin options with the same key, is CompositeSubpluginOption -> {
// use the properties count to resolve duplication: val subpluginIdWithWrapperKey = "$subpluginId.${optionKey}$indexSuffix"
val propertyInputsCount = inputsCompatible.properties.size registerSubpluginOptionsAsInputs(subpluginIdWithWrapperKey, option.originalOptions)
inputsCompatible.propertyCompatible("$subpluginId." + option.key + ".$propertyInputsCount", option.value) }
is FilesSubpluginOption -> when (option.kind) {
FilesOptionKind.INTERNAL -> Unit
}.run { /* exhaustive when */ }
else -> {
inputsCompatible.propertyCompatible("$subpluginId." + option.key + indexSuffix, option.value)
}
}
} }
} }
} }