Add integration test for kpm compiler plugin sensitive options

This commit is contained in:
Anton Lakotka
2021-05-05 10:41:38 +02:00
committed by Space
parent c01be75f47
commit 70a2678bbc
8 changed files with 201 additions and 3 deletions
@@ -15,6 +15,7 @@ val kotlinGradlePluginTest = project(":kotlin-gradle-plugin").sourceSets.named("
dependencies {
testImplementation(project(":kotlin-gradle-plugin"))
testImplementation(project(":kotlin-project-model"))
testImplementation(project(":kotlin-tooling-metadata"))
testImplementation(kotlinGradlePluginTest)
testImplementation(project(":kotlin-gradle-subplugin-example"))
@@ -780,6 +780,15 @@ Finished executing task ':$taskName'|
fun CompiledProject.javaClassesDir(subproject: String? = null, sourceSet: String = "main"): String =
project.classesDir(subproject, sourceSet, language = "java")
fun CompiledProject.compilerArgs(taskName: String): String {
val pattern = "$taskName Kotlin compiler args: "
return output
.lineSequence()
.firstOrNull { it.contains(pattern) }
?.substringAfter(pattern)
?: throw AssertionError("Cant find compiler args for task: $taskName")
}
private fun Project.createBuildCommand(wrapperDir: File, params: Array<out String>, options: BuildOptions): List<String> =
createGradleCommand(wrapperDir, createGradleTailParameters(options, params))
@@ -0,0 +1,65 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.gradle
import org.junit.Test
import kotlin.test.assertTrue
class KpmCompilerPluginIT : BaseGradleIT() {
@Test
fun testSensitivePluginOptions() {
val project = transformProjectWithPluginsDsl("kpmSensitivePluginOptions")
fun updatePluginOptions(sensitiveValue: String, insensitiveValue: String) {
project.gradleProperties().writeText(
"""
test-plugin.sensitive=$sensitiveValue
test-plugin.insensitive=$insensitiveValue
""".trimIndent()
)
}
updatePluginOptions("XXX", "YYY")
project.build("compileKotlin") {
assertSuccessful()
assertTasksExecuted(":compileKotlinJvm")
compilerArgs(":compileKotlinJvm").also { args ->
assertTrue(
args.contains("plugin:test-plugin:sensitive=XXX"),
"Expected sensitive plugin option in compilation args"
)
assertTrue(
args.contains("plugin:test-plugin:insensitive=YYY"),
"Expected insensitive plugin option in compilation args"
)
}
}
// When insensitive plugin option change
updatePluginOptions("XXX", "ZZZ")
project.build("compileKotlin") {
assertSuccessful()
assertTasksUpToDate(":compileKotlinJvm")
}
// When sensitive 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"
)
assertTrue(
args.contains("plugin:test-plugin:insensitive=ZZZ"),
"Expected insensitive plugin option in compilation args"
)
}
}
}
}
@@ -0,0 +1,55 @@
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.*
plugins {
kotlin("multiplatform.pm20")
}
repositories {
mavenCentral()
mavenLocal()
}
plugins.apply(GradleKpmPluginWithSensitivePluginOptions::class.java)
configure<KotlinPm20ProjectExtension> {
main {
jvm
}
}
class KpmPluginWithSensitivePluginOptions(
private val sensitiveOptionValue: String,
private val insensitiveOptionValue: 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)
)
)
override fun forMetadataCompilation(fragment: KotlinModuleFragment) = pluginData()
override fun forNativeMetadataCompilation(fragment: KotlinModuleFragment) = pluginData()
override fun forPlatformCompilation(variant: KotlinModuleVariant) = pluginData()
}
class GradleKpmPluginWithSensitivePluginOptions : GradleKpmCompilerPlugin {
private lateinit var project: Project
override fun apply(target: Project) {
project = target
}
override val kpmCompilerPlugin by lazy {
KpmPluginWithSensitivePluginOptions(
sensitiveOptionValue = project.property("test-plugin.sensitive") as String,
insensitiveOptionValue = project.property("test-plugin.insensitive") as String
)
}
}
@@ -0,0 +1,2 @@
test-plugin.sensitive=SENSITIVE_VALUE
test-plugin.insensitive=INSENSITIVE_VALUE
@@ -0,0 +1,12 @@
pluginManagement {
repositories {
mavenLocal()
mavenCentral()
}
plugins {
kotlin("multiplatform.pm20").version("1.5.255-SNAPSHOT")
}
}
rootProject.name = "kpmSensitivePluginOptions"
@@ -0,0 +1,4 @@
package testProject.kpmSensitivePluginOptions
class Foo {
}
@@ -3,6 +3,7 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@file:Suppress("invisible_reference", "invisible_member", "FunctionName")
package org.jetbrains.kotlin.gradle.mpp
import org.gradle.api.Project
@@ -14,8 +15,7 @@ import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinNativeCompile
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilerPluginData
import org.jetbrains.kotlin.project.model.*
import org.junit.Test
import kotlin.test.assertEquals
import kotlin.test.*
class KpmCompilerPluginTest {
@Test
@@ -83,11 +83,46 @@ class KpmCompilerPluginTest {
}
}
@Test
fun `compiler plugins should be applied lazily`() {
val project = buildProjectWithKPM {
plugins.apply(TestPluginWithListeners::class.java)
projectModel {
main {
jvm
}
}
}
with(TestPluginWithListeners.Companion) {
onGetKpmCompilerPlugin = { throw AssertionError("KPM Compiler Plugin should not be obtained on project evaluate") }
onPluginDataGet = { throw AssertionError("Plugin data should not be requested on project evaluate") }
}
project.evaluate()
// Getting task shouldn't trigger plugin initialization as well (lazy all the way)
val task = project.tasks.getByName("compileKotlinJvm") as AbstractKotlinCompile<*>
var pluginInitialized = false
var pluginDataObtainCount = 0
with(TestPluginWithListeners.Companion) {
onGetKpmCompilerPlugin = { pluginInitialized = true }
onPluginDataGet = { pluginDataObtainCount++ }
}
// Upon pluginData request plugins should be initialized and obtained only once
repeat(5) { task.kotlinPluginData!!.get() }
assertTrue(pluginInitialized)
assertEquals(1, pluginDataObtainCount)
}
private fun Project.pluginDataOfTask(taskName: String) = this
.tasks
.getByName(taskName)
.let {
when(it) {
when (it) {
is AbstractKotlinCompile<*> -> it.kotlinPluginData
is AbstractKotlinNativeCompile<*, *> -> it.kotlinPluginData
else -> error("Unknown task type: $it")
@@ -128,4 +163,19 @@ class KpmCompilerPluginTest {
override fun forPlatformCompilation(variant: KotlinModuleVariant) = platformArtifact?.let(::pluginData)
}
open class TestPluginWithListeners : KpmCompilerPlugin, GradleKpmCompilerPlugin {
override val kpmCompilerPlugin: KpmCompilerPlugin get() = this.also { onGetKpmCompilerPlugin() }
override fun apply(target: Project) = onApply()
override fun forMetadataCompilation(fragment: KotlinModuleFragment): PluginData? = null.also { onPluginDataGet() }
override fun forNativeMetadataCompilation(fragment: KotlinModuleFragment): PluginData? = null.also { onPluginDataGet() }
override fun forPlatformCompilation(variant: KotlinModuleVariant): PluginData? = null.also { onPluginDataGet() }
companion object {
var onApply: () -> Unit = {}
var onGetKpmCompilerPlugin: () -> Unit = {}
var onPluginDataGet: () -> Unit = {}
}
}
}