Introduce single-project extensions with static types for Kotlin target

This commit is contained in:
Sergey Igushkin
2019-02-28 16:40:29 +03:00
parent b3eef05e6e
commit 4e711f9a0c
9 changed files with 164 additions and 14 deletions
@@ -891,4 +891,34 @@ class KotlinGradleIT : BaseGradleIT() {
assertNotContains(MULTIPLE_KOTLIN_PLUGINS_SPECIFIC_PROJECTS_WARNING) assertNotContains(MULTIPLE_KOTLIN_PLUGINS_SPECIFIC_PROJECTS_WARNING)
} }
} }
@Test
fun testNewModelInOldJvmPlugin() = with(Project("new-model-in-old-plugin", GradleVersionRequired.AtLeast("4.10.2"))) {
setupWorkingDir()
gradleBuildScript().modify(::transformBuildScriptWithPluginsDsl)
build("publish", "check", "runBenchmark") {
assertSuccessful()
assertTasksExecuted(":compileKotlin", ":compileTestKotlin", ":compileBenchmarkKotlin", ":test", ":runBenchmark")
// Find the benchmark output:
assertContains("f ran at the speed of light")
val moduleDir = "build/repo/com/example/new-model/1.0/"
val publishedJar = fileInWorkingDir(moduleDir + "new-model-1.0.jar")
ZipFile(publishedJar).use { zip ->
val entries = zip.entries().asSequence().map { it.name }
assertTrue { "com/example/A.class" in entries }
}
val publishedPom = fileInWorkingDir(moduleDir + "new-model-1.0.pom")
val kotlinVersion = defaultBuildOptions().kotlinVersion
val pomText = publishedPom.readText().replace(Regex("\\s+"), "")
assertTrue { "kotlin-gradle-plugin-api</artifactId><version>$kotlinVersion</version><scope>compile</scope>" in pomText }
assertTrue { "kotlin-stdlib-jdk8</artifactId><version>$kotlinVersion</version><scope>runtime</scope>" in pomText }
assertFileExists(moduleDir + "new-model-1.0-sources.jar")
}
}
} }
@@ -0,0 +1,60 @@
plugins {
kotlin("jvm").version("<pluginMarkerVersion>")
`maven-publish`
}
group = "com.example"
version = "1.0"
repositories {
mavenLocal()
jcenter()
}
kotlin.target.compilations {
all {
kotlinOptions {
allWarningsAsErrors = true
jvmTarget = "1.8"
}
}
val main by getting {
defaultSourceSet.dependencies {
api(kotlin("gradle-plugin-api"))
implementation(kotlin("stdlib-jdk8"))
}
}
val test by getting {
defaultSourceSet.dependencies {
implementation(kotlin("test-junit"))
}
}
val benchmark by creating {
defaultSourceSet.dependencies {
implementation(main.compileDependencyFiles + main.output.allOutputs)
runtimeOnly(main.runtimeDependencyFiles)
implementation(kotlin("reflect"))
}
}
}
val runBenchmark by tasks.registering(JavaExec::class) {
classpath = kotlin.target.compilations["benchmark"].run { runtimeDependencyFiles + output.allOutputs }
main = "com.example.ABenchmarkKt"
}
publishing {
publications {
create("default", MavenPublication::class) {
from(kotlin.target.components.single())
artifact(tasks.getByName("kotlinSourcesJar"))
}
}
repositories {
maven("${buildDir}/repo")
}
}
@@ -0,0 +1,8 @@
pluginManagement {
repositories {
mavenLocal()
gradlePluginPortal()
}
}
rootProject.name = "new-model"
@@ -0,0 +1,8 @@
package com.example
fun main() {
val a = A()
val f = a::f
f()
println("${a::f.name} ran at the speed of light")
}
@@ -0,0 +1,5 @@
package com.example
class A {
fun f(): String = "hello".also(::println)
}
@@ -0,0 +1,11 @@
package com.example
import kotlin.test.*
class ATest {
@Test
fun testF() {
val f = A().f()
assertEquals("hello", f)
}
}
@@ -20,6 +20,8 @@ import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.internal.plugins.DslObject import org.gradle.api.internal.plugins.DslObject
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaTarget import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaTarget
import kotlin.reflect.KClass import kotlin.reflect.KClass
@@ -52,12 +54,33 @@ open class KotlinProjectExtension {
} }
} }
open class KotlinSingleJavaTargetExtension : KotlinProjectExtension() { abstract class KotlinSingleTargetExtension : KotlinProjectExtension() {
// TODO define subtypes with proper type arguments for each of the option types once the new model is available in old projects abstract val target: KotlinTarget
internal lateinit var target: KotlinWithJavaTarget<*>
} }
open class KotlinJvmProjectExtension : KotlinSingleJavaTargetExtension() abstract class KotlinSingleJavaTargetExtension : KotlinSingleTargetExtension() {
override abstract val target: KotlinWithJavaTarget<*>
}
open class KotlinJvmProjectExtension : KotlinSingleJavaTargetExtension() {
override lateinit var target: KotlinWithJavaTarget<KotlinJvmOptions>
internal set
}
open class Kotlin2JsProjectExtension : KotlinSingleJavaTargetExtension() {
override lateinit var target: KotlinWithJavaTarget<KotlinJsOptions>
internal set
}
open class KotlinCommonProjectExtension : KotlinSingleJavaTargetExtension() {
override lateinit var target: KotlinWithJavaTarget<KotlinMultiplatformCommonOptions>
internal set
}
open class KotlinAndroidProjectExtension : KotlinSingleTargetExtension() {
override lateinit var target: KotlinAndroidTarget
internal set
}
open class ExperimentalExtension { open class ExperimentalExtension {
var coroutines: Coroutines? = null var coroutines: Coroutines? = null
@@ -562,10 +562,10 @@ internal open class KotlinPlugin(
Kotlin2JvmSourceSetProcessor(project, tasksProvider, compilation, kotlinPluginVersion) Kotlin2JvmSourceSetProcessor(project, tasksProvider, compilation, kotlinPluginVersion)
override fun apply(project: Project) { override fun apply(project: Project) {
val target = KotlinWithJavaTarget<KotlinCommonOptions>(project, KotlinPlatformType.jvm, targetName).apply { val target = KotlinWithJavaTarget<KotlinJvmOptions>(project, KotlinPlatformType.jvm, targetName).apply {
disambiguationClassifier = null // don't add anything to the task names disambiguationClassifier = null // don't add anything to the task names
} }
(project.kotlinExtension as KotlinSingleJavaTargetExtension).target = target (project.kotlinExtension as KotlinJvmProjectExtension).target = target
project.pluginManager.apply(ScriptingGradleSubplugin::class.java) project.pluginManager.apply(ScriptingGradleSubplugin::class.java)
@@ -590,8 +590,8 @@ internal open class KotlinCommonPlugin(
KotlinCommonSourceSetProcessor(project, compilation, tasksProvider, kotlinPluginVersion) KotlinCommonSourceSetProcessor(project, compilation, tasksProvider, kotlinPluginVersion)
override fun apply(project: Project) { override fun apply(project: Project) {
val target = KotlinWithJavaTarget<KotlinCommonOptions>(project, KotlinPlatformType.common, targetName) val target = KotlinWithJavaTarget<KotlinMultiplatformCommonOptions>(project, KotlinPlatformType.common, targetName)
(project.kotlinExtension as KotlinSingleJavaTargetExtension).target = target (project.kotlinExtension as KotlinCommonProjectExtension).target = target
super.apply(project) super.apply(project)
} }
@@ -616,9 +616,9 @@ internal open class Kotlin2JsPlugin(
) )
override fun apply(project: Project) { override fun apply(project: Project) {
val target = KotlinWithJavaTarget<KotlinCommonOptions>(project, KotlinPlatformType.js, targetName) val target = KotlinWithJavaTarget<KotlinJsOptions>(project, KotlinPlatformType.js, targetName)
(project.kotlinExtension as KotlinSingleJavaTargetExtension).target = target (project.kotlinExtension as Kotlin2JsProjectExtension).target = target
super.apply(project) super.apply(project)
} }
} }
@@ -632,6 +632,8 @@ internal open class KotlinAndroidPlugin(
checkGradleCompatibility() checkGradleCompatibility()
val androidTarget = KotlinAndroidTarget("", project) val androidTarget = KotlinAndroidTarget("", project)
(project.kotlinExtension as KotlinAndroidProjectExtension).target = androidTarget
applyToTarget(kotlinPluginVersion, androidTarget) applyToTarget(kotlinPluginVersion, androidTarget)
registry.register(KotlinModelBuilder(kotlinPluginVersion, androidTarget)) registry.register(KotlinModelBuilder(kotlinPluginVersion, androidTarget))
} }
@@ -113,8 +113,8 @@ open class KotlinCommonPluginWrapper @Inject constructor(
override fun getPlugin(project: Project, kotlinGradleBuildServices: KotlinGradleBuildServices): Plugin<Project> = override fun getPlugin(project: Project, kotlinGradleBuildServices: KotlinGradleBuildServices): Plugin<Project> =
KotlinCommonPlugin(kotlinPluginVersion, registry) KotlinCommonPlugin(kotlinPluginVersion, registry)
override val projectExtensionClass: KClass<out KotlinSingleJavaTargetExtension> override val projectExtensionClass: KClass<out KotlinCommonProjectExtension>
get() = KotlinSingleJavaTargetExtension::class get() = KotlinCommonProjectExtension::class
} }
open class KotlinAndroidPluginWrapper @Inject constructor( open class KotlinAndroidPluginWrapper @Inject constructor(
@@ -123,6 +123,9 @@ open class KotlinAndroidPluginWrapper @Inject constructor(
) : KotlinBasePluginWrapper(fileResolver) { ) : KotlinBasePluginWrapper(fileResolver) {
override fun getPlugin(project: Project, kotlinGradleBuildServices: KotlinGradleBuildServices): Plugin<Project> = override fun getPlugin(project: Project, kotlinGradleBuildServices: KotlinGradleBuildServices): Plugin<Project> =
KotlinAndroidPlugin(kotlinPluginVersion, registry) KotlinAndroidPlugin(kotlinPluginVersion, registry)
override val projectExtensionClass: KClass<out KotlinAndroidProjectExtension>
get() = KotlinAndroidProjectExtension::class
} }
open class Kotlin2JsPluginWrapper @Inject constructor( open class Kotlin2JsPluginWrapper @Inject constructor(
@@ -132,8 +135,8 @@ open class Kotlin2JsPluginWrapper @Inject constructor(
override fun getPlugin(project: Project, kotlinGradleBuildServices: KotlinGradleBuildServices): Plugin<Project> = override fun getPlugin(project: Project, kotlinGradleBuildServices: KotlinGradleBuildServices): Plugin<Project> =
Kotlin2JsPlugin(kotlinPluginVersion, registry) Kotlin2JsPlugin(kotlinPluginVersion, registry)
override val projectExtensionClass: KClass<out KotlinSingleJavaTargetExtension> override val projectExtensionClass: KClass<out Kotlin2JsProjectExtension>
get() = KotlinSingleJavaTargetExtension::class get() = Kotlin2JsProjectExtension::class
} }
open class KotlinMultiplatformPluginWrapper @Inject constructor( open class KotlinMultiplatformPluginWrapper @Inject constructor(