Rename sensitive flag to isTransient and inverse logic, add file outputs

isTransient with default value as false makes it a bit more readable
Some Compiler Plugins can use file outputs properties to dump some data
there and gradle can support incremental build
with file outputs.
This commit is contained in:
Anton Lakotka
2021-06-05 12:30:55 +02:00
committed by Space
parent 70a2678bbc
commit 52abecab43
11 changed files with 87 additions and 67 deletions
@@ -11,13 +11,13 @@ import kotlin.test.assertTrue
class KpmCompilerPluginIT : BaseGradleIT() {
@Test
fun testSensitivePluginOptions() {
val project = transformProjectWithPluginsDsl("kpmSensitivePluginOptions")
fun updatePluginOptions(sensitiveValue: String, insensitiveValue: String) {
fun testTransientPluginOptions() {
val project = transformProjectWithPluginsDsl("kpmTransientPluginOptions")
fun updatePluginOptions(regularOptionValue: String, transientOptionValue: String) {
project.gradleProperties().writeText(
"""
test-plugin.sensitive=$sensitiveValue
test-plugin.insensitive=$insensitiveValue
test-plugin.regular=$regularOptionValue
test-plugin.transient=$transientOptionValue
""".trimIndent()
)
}
@@ -28,36 +28,36 @@ class KpmCompilerPluginIT : BaseGradleIT() {
assertTasksExecuted(":compileKotlinJvm")
compilerArgs(":compileKotlinJvm").also { args ->
assertTrue(
args.contains("plugin:test-plugin:sensitive=XXX"),
"Expected sensitive plugin option in compilation args"
args.contains("plugin:test-plugin:regular=XXX"),
"Expected regular plugin option in compilation args"
)
assertTrue(
args.contains("plugin:test-plugin:insensitive=YYY"),
"Expected insensitive plugin option in compilation args"
args.contains("plugin:test-plugin:transient=YYY"),
"Expected transient plugin option in compilation args"
)
}
}
// When insensitive plugin option change
// When transient plugin option change
updatePluginOptions("XXX", "ZZZ")
project.build("compileKotlin") {
assertSuccessful()
assertTasksUpToDate(":compileKotlinJvm")
}
// When sensitive plugin option change
// When regular plugin option change
updatePluginOptions("ZZZ", "ZZZ")
project.build("compileKotlin") {
assertSuccessful()
assertTasksExecuted(":compileKotlinJvm")
compilerArgs(":compileKotlinJvm").also { args ->
assertTrue(
args.contains("plugin:test-plugin:sensitive=ZZZ"),
"Expected sensitive plugin option in compilation args"
args.contains("plugin:test-plugin:regular=ZZZ"),
"Expected regular plugin option in compilation args"
)
assertTrue(
args.contains("plugin:test-plugin:insensitive=ZZZ"),
"Expected insensitive plugin option in compilation args"
args.contains("plugin:test-plugin:transient=ZZZ"),
"Expected transient plugin option in compilation args"
)
}
}
@@ -1,2 +0,0 @@
test-plugin.sensitive=SENSITIVE_VALUE
test-plugin.insensitive=INSENSITIVE_VALUE
@@ -1,12 +0,0 @@
pluginManagement {
repositories {
mavenLocal()
mavenCentral()
}
plugins {
kotlin("multiplatform.pm20").version("1.5.255-SNAPSHOT")
}
}
rootProject.name = "kpmSensitivePluginOptions"
@@ -1,4 +0,0 @@
package testProject.kpmSensitivePluginOptions
class Foo {
}
@@ -1,5 +1,4 @@
import org.gradle.api.Project
import org.gradle.api.plugins.ExtraPropertiesExtension
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.*
import org.jetbrains.kotlin.project.model.*
@@ -12,7 +11,7 @@ repositories {
mavenLocal()
}
plugins.apply(GradleKpmPluginWithSensitivePluginOptions::class.java)
plugins.apply(GradleKpmPluginWithTransientPluginOptions::class.java)
configure<KotlinPm20ProjectExtension> {
main {
@@ -20,17 +19,17 @@ configure<KotlinPm20ProjectExtension> {
}
}
class KpmPluginWithSensitivePluginOptions(
private val sensitiveOptionValue: String,
private val insensitiveOptionValue: String
class KpmPluginWithTransientPluginOptions(
private val regularOptionValue: String,
private val transientOptionValue: String
) : KpmCompilerPlugin {
private fun pluginData() = PluginData(
pluginId = "test-plugin",
// allopen artifact is used to avoid boilerplate with cooking custom compiler plugin
artifact = PluginData.ArtifactCoordinates("org.jetbrains.kotlin", "kotlin-allopen"),
options = listOf(
StringOption("sensitive", sensitiveOptionValue, true),
StringOption("insensitive", insensitiveOptionValue, false)
StringOption("regular", regularOptionValue, isTransient = false),
StringOption("transient", transientOptionValue, isTransient = true)
)
)
@@ -39,7 +38,7 @@ class KpmPluginWithSensitivePluginOptions(
override fun forPlatformCompilation(variant: KotlinModuleVariant) = pluginData()
}
class GradleKpmPluginWithSensitivePluginOptions : GradleKpmCompilerPlugin {
class GradleKpmPluginWithTransientPluginOptions : GradleKpmCompilerPlugin {
private lateinit var project: Project
override fun apply(target: Project) {
@@ -47,9 +46,9 @@ class GradleKpmPluginWithSensitivePluginOptions : GradleKpmCompilerPlugin {
}
override val kpmCompilerPlugin by lazy {
KpmPluginWithSensitivePluginOptions(
sensitiveOptionValue = project.property("test-plugin.sensitive") as String,
insensitiveOptionValue = project.property("test-plugin.insensitive") as String
KpmPluginWithTransientPluginOptions(
regularOptionValue = project.property("test-plugin.regular") as String,
transientOptionValue = project.property("test-plugin.transient") as String
)
}
}
@@ -0,0 +1,2 @@
test-plugin.regular=REGULAR_VALUE
test-plugin.transient=TRANSIENT_VALUE
@@ -0,0 +1,13 @@
pluginManagement {
repositories {
mavenLocal()
mavenCentral()
}
plugins {
val kotlin_version: String by settings
kotlin("multiplatform.pm20").version(kotlin_version)
}
}
rootProject.name = "kpmTransientPluginOptions"
@@ -0,0 +1,4 @@
package testProject.kpmTransientPluginOptions
class Foo {
}
@@ -53,6 +53,7 @@ internal class CompilerPluginOptionsBuilder(
private val artifacts = mutableListOf<String>()
private val gradleInputs = mutableMapOf<String, MutableList<String>>()
private val gradleInputFiles = mutableSetOf<File>()
private val gradleOutputFiles = mutableSetOf<File>()
operator fun plusAssign(pluginData: PluginData) {
artifacts += pluginData.artifact.toGradleCoordinates()
@@ -60,8 +61,8 @@ internal class CompilerPluginOptionsBuilder(
for (option in pluginData.options) {
pluginOptions.addPluginArgument(pluginData.pluginId, option.toSubpluginOption())
if (option.sensitive) {
addToInputs(pluginData.pluginId, option)
if (!option.isTransient) {
addToInputsOutputs(pluginData.pluginId, option)
}
}
}
@@ -72,9 +73,14 @@ internal class CompilerPluginOptionsBuilder(
}
}
private fun addToInputs(pluginId: String, option: PluginOption) {
when(option) {
is FilesOption -> gradleInputFiles += option.files
private fun addToInputsOutputs(pluginId: String, option: PluginOption) {
when (option) {
is FilesOption ->
if (option.isOutput) {
gradleOutputFiles += option.files
} else {
gradleInputFiles += option.files
}
is StringOption -> gradleInputs
.getOrPut("${pluginId}.${option.key}") { mutableListOf() }
.add(option.value)
@@ -93,12 +99,15 @@ internal class CompilerPluginOptionsBuilder(
return KotlinCompilerPluginData(
classpath = pluginClasspathConfiguration,
options = pluginOptions,
inputs = gradleInputs.flattenWithIndex(),
inputFiles = gradleInputFiles
inputsOutputsState = KotlinCompilerPluginData.InputsOutputsState(
inputs = gradleInputs.flattenWithIndex(),
inputFiles = gradleInputFiles,
outputFiles = gradleOutputFiles
)
)
}
private fun Map<String,List<String>>.flattenWithIndex(): Map<String, String> {
private fun Map<String, List<String>>.flattenWithIndex(): Map<String, String> {
val result = mutableMapOf<String, String>()
for ((key, values) in this) {
@@ -116,5 +125,5 @@ internal class CompilerPluginOptionsBuilder(
}
private fun PluginData.ArtifactCoordinates.toGradleCoordinates(): String =
"$group:$artifact:${version ?: project.getKotlinPluginVersion()}"
listOfNotNull(group, artifact, version).joinToString(":")
}
@@ -788,14 +788,19 @@ data class KotlinCompilerPluginData(
/**
* Used only for Up-to-date checks
*/
@get:Input
val inputs: Map<String, String>,
@get:Nested
val inputsOutputsState: InputsOutputsState
) {
data class InputsOutputsState(
@get:Input
val inputs: Map<String, String>,
/**
* Used only for Up-to-date checks
*/
@get:InputFiles
@get:PathSensitive(PathSensitivity.RELATIVE)
val inputFiles: Set<File>
)
@get:InputFiles
@get:PathSensitive(PathSensitivity.RELATIVE)
val inputFiles: Set<File>,
@get:OutputFiles
val outputFiles: Set<File>
)
}
@@ -53,22 +53,28 @@ sealed class PluginOption {
abstract val key: String
/**
* when true a value of given plugin option is sensitive for incremental compilation
* when false compilation task can be skipped even if value differs from previous one
* Indicates whether value of [PluginOption] should be stored for incremental build checks.
* Value changes of non-transient [PluginOption] will invalidate incremental caches.
*/
abstract val sensitive: Boolean
abstract val isTransient: Boolean
}
data class StringOption(
override val key: String,
val value: String,
override val sensitive: Boolean = true
override val isTransient: Boolean = false
) : PluginOption()
data class FilesOption(
override val key: String,
val files: List<File>,
override val sensitive: Boolean = true
/**
* Indicates whether FilesOption is used as input or output during compilation
* false means input
* true means output
*/
val isOutput: Boolean = false,
override val isTransient: Boolean = false
) : PluginOption()
// TODO: It should be part of "Compilation Process": KotlinModule.compilationRequestFor(METADATA | PLATFORM) -> CompilationRequest