From cee52c095f1353c702fdae43e841b7df468322f3 Mon Sep 17 00:00:00 2001 From: Sergey Igushkin Date: Wed, 21 Nov 2018 16:37:20 +0300 Subject: [PATCH] Add and generate Groovy-friendly DSL members As Gradle Groovy DSL does out-of-the box not allow working with SAM-receiving functions in the same way as those accepting a Closure, and, moreover, does not work with Kotlin default parameters, we need to provide Groovy-friendly DSL functions along with Kotlin DSL functions This commit adds those additional members for all of the newly introduced MPP DSL members. --- .../kotlin/gradle/plugin/KotlinCompilation.kt | 3 + .../gradle/dsl/mppPresetFunctionsCodegen.kt | 24 +++-- .../sample-lib/build.gradle | 23 ++++- .../dsl/KotlinMultiplatformExtension.kt | 11 +++ ...otlinTargetContainerWithPresetFunctions.kt | 87 ++++++++++++++++++- 5 files changed, 138 insertions(+), 10 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinCompilation.kt b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinCompilation.kt index 96358d7dc7f..1d77add617c 100644 --- a/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinCompilation.kt +++ b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinCompilation.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.gradle.plugin +import groovy.lang.Closure import org.gradle.api.Named import org.gradle.api.attributes.HasAttributes import org.gradle.api.file.ConfigurableFileCollection @@ -32,6 +33,7 @@ interface KotlinCompilation : Named, HasAttributes, val defaultSourceSet: KotlinSourceSet fun defaultSourceSet(configure: KotlinSourceSet.() -> Unit) + fun defaultSourceSet(configure: Closure<*>) = defaultSourceSet { ConfigureUtil.configure(configure, this) } val compileDependencyConfigurationName: String @@ -48,6 +50,7 @@ interface KotlinCompilation : Named, HasAttributes, val kotlinOptions: T fun kotlinOptions(configure: T.() -> Unit) + fun kotlinOptions(configure: Closure<*>) = kotlinOptions { ConfigureUtil.configure(configure, this) } val compileAllTaskName: String diff --git a/libraries/tools/kotlin-gradle-plugin-dsl-codegen/src/main/kotlin/org/jetbrains/kotlin/generators/gradle/dsl/mppPresetFunctionsCodegen.kt b/libraries/tools/kotlin-gradle-plugin-dsl-codegen/src/main/kotlin/org/jetbrains/kotlin/generators/gradle/dsl/mppPresetFunctionsCodegen.kt index ba594acab52..d7e0f46c754 100644 --- a/libraries/tools/kotlin-gradle-plugin-dsl-codegen/src/main/kotlin/org/jetbrains/kotlin/generators/gradle/dsl/mppPresetFunctionsCodegen.kt +++ b/libraries/tools/kotlin-gradle-plugin-dsl-codegen/src/main/kotlin/org/jetbrains/kotlin/generators/gradle/dsl/mppPresetFunctionsCodegen.kt @@ -5,6 +5,8 @@ package org.jetbrains.kotlin.generators.gradle.dsl +import groovy.lang.Closure +import org.gradle.util.ConfigureUtil import org.jetbrains.kotlin.gradle.plugin.KotlinTargetsContainerWithPresets import java.io.File @@ -19,7 +21,7 @@ private val presetsProperty = KotlinTargetsContainerWithPresets::presets.name private fun generateKotlinTargetContainerWithPresetFunctionsInterface() { // Generate KotlinMutliplatformExtension subclass with member functions for the presets: val functions = allPresetEntries.map { - generatePresetFunction(it, presetsProperty, "configureOrCreate") + generatePresetFunctions(it, presetsProperty, "configureOrCreate") } val parentInterfaceName = @@ -31,6 +33,8 @@ private fun generateKotlinTargetContainerWithPresetFunctionsInterface() { val imports = allPresetEntries .flatMap { it.typeNames() } .plus(parentInterfaceName) + .plus(typeName(ConfigureUtil::class.java.canonicalName)) + .plus(typeName(Closure::class.java.canonicalName)) .filter { it.packageName() != className.packageName() } .flatMap { it.collectFqNames() } .toSortedSet() @@ -52,21 +56,29 @@ private fun generateKotlinTargetContainerWithPresetFunctionsInterface() { targetFile.writeText(code) } -private fun generatePresetFunction( +private fun generatePresetFunctions( presetEntry: KotlinPresetEntry, getPresetsExpression: String, configureOrCreateFunctionName: String -): String = """ - fun ${presetEntry.presetName}( - name: String = "${presetEntry.presetName}", +): String { + val presetName = presetEntry.presetName + return """ + fun $presetName( + name: String = "$presetName", configure: ${presetEntry.targetType.renderShort()}.() -> Unit = { } ): ${presetEntry.targetType.renderShort()} = $configureOrCreateFunctionName( name, - $getPresetsExpression.getByName("${presetEntry.presetName}") as ${presetEntry.presetType.renderErased()}, + $getPresetsExpression.getByName("$presetName") as ${presetEntry.presetType.renderErased()}, configure ) + + fun $presetName() = $presetName("$presetName") { } + fun $presetName(name: String) = $presetName(name) { } + fun $presetName(name: String, configure: Closure<*>) = $presetName(name) { ConfigureUtil.configure(configure, this) } + fun $presetName(configure: Closure<*>) = $presetName { ConfigureUtil.configure(configure, this) } """.trimIndent() +} private fun String.indented(nSpaces: Int = 4): String { val spaces = String(CharArray(nSpaces) { ' ' }) diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-lib-and-app/sample-lib/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-lib-and-app/sample-lib/build.gradle index d8923e3c33d..456372d83a4 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-lib-and-app/sample-lib/build.gradle +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-lib-and-app/sample-lib/build.gradle @@ -20,14 +20,31 @@ repositories { } kotlin { + // Check the new preset functions: + jvm('jvm6') { } + js('nodeJs') + targetFromPreset(presets.wasm32) { println targetName } + targetFromPreset(presets.jvm, 'jvm6') { println targetName } // access existing target + targets { - fromPreset(presets.jvm, 'jvm6') - fromPreset(presets.js, 'nodeJs') - fromPreset(presets.wasm32, 'wasm32') + // Also check that the old DSL (fromPreset) works: fromPreset(presets.linuxX64, 'linux64') fromPreset(presets.mingwX64, 'mingw64') fromPreset(presets.macosX64, 'macos64') + // Check the DSL constructs in the Groovy DSL: + fromPreset(presets.jvm, 'jvm6') { + println "Configuring $targetName" + compilations.main { + kotlinOptions { + println "jvmTarget = " + jvmTarget + } + defaultSourceSet { + println "Kotlin srcDirs: " + kotlin.srcDirs + } + } + } + all { mavenPublication { pom.withXml { diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinMultiplatformExtension.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinMultiplatformExtension.kt index caf8113ff3e..fcebc819482 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinMultiplatformExtension.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinMultiplatformExtension.kt @@ -5,8 +5,10 @@ package org.jetbrains.kotlin.gradle.dsl +import groovy.lang.Closure import org.gradle.api.InvalidUserCodeException import org.gradle.api.NamedDomainObjectCollection +import org.gradle.util.ConfigureUtil import org.jetbrains.kotlin.gradle.plugin.KotlinTarget import org.jetbrains.kotlin.gradle.plugin.KotlinTargetPreset import org.jetbrains.kotlin.gradle.plugin.KotlinTargetsContainerWithPresets @@ -28,11 +30,20 @@ open class KotlinMultiplatformExtension : KotlinProjectExtension(), KotlinTarget @Suppress("UNCHECKED_CAST") (targets.getByName(KotlinMultiplatformPlugin.METADATA_TARGET_NAME) as KotlinOnlyTarget).also(configure) + fun metadata(configure: Closure<*>) = metadata { ConfigureUtil.configure(configure, this) } + fun targetFromPreset( preset: KotlinTargetPreset, name: String = preset.name, configure: T.() -> Unit = { } ): T = configureOrCreate(name, preset, configure) + + fun targetFromPreset(preset: KotlinTargetPreset<*>, name: String, configure: Closure<*>) = + targetFromPreset(preset, name) { ConfigureUtil.configure(configure, this) } + + fun targetFromPreset(preset: KotlinTargetPreset<*>) = targetFromPreset(preset, preset.name) { } + fun targetFromPreset(preset: KotlinTargetPreset<*>, name: String) = targetFromPreset(preset, name) { } + fun targetFromPreset(preset: KotlinTargetPreset<*>, configure: Closure<*>) = targetFromPreset(preset, preset.name, configure) } internal fun KotlinTarget.isProducedFromPreset(kotlinTargetPreset: KotlinTargetPreset<*>): Boolean = diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinTargetContainerWithPresetFunctions.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinTargetContainerWithPresetFunctions.kt index 18122f738a2..6c909fd6e6f 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinTargetContainerWithPresetFunctions.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinTargetContainerWithPresetFunctions.kt @@ -1,7 +1,17 @@ package org.jetbrains.kotlin.gradle.dsl +import groovy.lang.Closure +import org.gradle.util.ConfigureUtil import org.jetbrains.kotlin.gradle.plugin.KotlinTargetsContainerWithPresets -import org.jetbrains.kotlin.gradle.plugin.mpp.* +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTargetPreset +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsTargetPreset +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmCompilation +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmTargetPreset +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTargetPreset +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinOnlyTarget // DO NOT EDIT MANUALLY! Generated by org.jetbrains.kotlin.generators.gradle.dsl.MppPresetFunctionsCodegenKt @@ -16,6 +26,11 @@ interface KotlinTargetContainerWithPresetFunctions : KotlinTargetsContainerWithP presets.getByName("jvm") as KotlinJvmTargetPreset, configure ) + + fun jvm() = jvm("jvm") { } + fun jvm(name: String) = jvm(name) { } + fun jvm(name: String, configure: Closure<*>) = jvm(name) { ConfigureUtil.configure(configure, this) } + fun jvm(configure: Closure<*>) = jvm { ConfigureUtil.configure(configure, this) } fun js( name: String = "js", @@ -26,6 +41,11 @@ interface KotlinTargetContainerWithPresetFunctions : KotlinTargetsContainerWithP presets.getByName("js") as KotlinJsTargetPreset, configure ) + + fun js() = js("js") { } + fun js(name: String) = js(name) { } + fun js(name: String, configure: Closure<*>) = js(name) { ConfigureUtil.configure(configure, this) } + fun js(configure: Closure<*>) = js { ConfigureUtil.configure(configure, this) } fun android( name: String = "android", @@ -36,6 +56,11 @@ interface KotlinTargetContainerWithPresetFunctions : KotlinTargetsContainerWithP presets.getByName("android") as KotlinAndroidTargetPreset, configure ) + + fun android() = android("android") { } + fun android(name: String) = android(name) { } + fun android(name: String, configure: Closure<*>) = android(name) { ConfigureUtil.configure(configure, this) } + fun android(configure: Closure<*>) = android { ConfigureUtil.configure(configure, this) } fun androidNativeArm32( name: String = "androidNativeArm32", @@ -46,6 +71,11 @@ interface KotlinTargetContainerWithPresetFunctions : KotlinTargetsContainerWithP presets.getByName("androidNativeArm32") as KotlinNativeTargetPreset, configure ) + + fun androidNativeArm32() = androidNativeArm32("androidNativeArm32") { } + fun androidNativeArm32(name: String) = androidNativeArm32(name) { } + fun androidNativeArm32(name: String, configure: Closure<*>) = androidNativeArm32(name) { ConfigureUtil.configure(configure, this) } + fun androidNativeArm32(configure: Closure<*>) = androidNativeArm32 { ConfigureUtil.configure(configure, this) } fun androidNativeArm64( name: String = "androidNativeArm64", @@ -56,6 +86,11 @@ interface KotlinTargetContainerWithPresetFunctions : KotlinTargetsContainerWithP presets.getByName("androidNativeArm64") as KotlinNativeTargetPreset, configure ) + + fun androidNativeArm64() = androidNativeArm64("androidNativeArm64") { } + fun androidNativeArm64(name: String) = androidNativeArm64(name) { } + fun androidNativeArm64(name: String, configure: Closure<*>) = androidNativeArm64(name) { ConfigureUtil.configure(configure, this) } + fun androidNativeArm64(configure: Closure<*>) = androidNativeArm64 { ConfigureUtil.configure(configure, this) } fun iosArm32( name: String = "iosArm32", @@ -66,6 +101,11 @@ interface KotlinTargetContainerWithPresetFunctions : KotlinTargetsContainerWithP presets.getByName("iosArm32") as KotlinNativeTargetPreset, configure ) + + fun iosArm32() = iosArm32("iosArm32") { } + fun iosArm32(name: String) = iosArm32(name) { } + fun iosArm32(name: String, configure: Closure<*>) = iosArm32(name) { ConfigureUtil.configure(configure, this) } + fun iosArm32(configure: Closure<*>) = iosArm32 { ConfigureUtil.configure(configure, this) } fun iosArm64( name: String = "iosArm64", @@ -76,6 +116,11 @@ interface KotlinTargetContainerWithPresetFunctions : KotlinTargetsContainerWithP presets.getByName("iosArm64") as KotlinNativeTargetPreset, configure ) + + fun iosArm64() = iosArm64("iosArm64") { } + fun iosArm64(name: String) = iosArm64(name) { } + fun iosArm64(name: String, configure: Closure<*>) = iosArm64(name) { ConfigureUtil.configure(configure, this) } + fun iosArm64(configure: Closure<*>) = iosArm64 { ConfigureUtil.configure(configure, this) } fun iosX64( name: String = "iosX64", @@ -86,6 +131,11 @@ interface KotlinTargetContainerWithPresetFunctions : KotlinTargetsContainerWithP presets.getByName("iosX64") as KotlinNativeTargetPreset, configure ) + + fun iosX64() = iosX64("iosX64") { } + fun iosX64(name: String) = iosX64(name) { } + fun iosX64(name: String, configure: Closure<*>) = iosX64(name) { ConfigureUtil.configure(configure, this) } + fun iosX64(configure: Closure<*>) = iosX64 { ConfigureUtil.configure(configure, this) } fun linuxX64( name: String = "linuxX64", @@ -96,6 +146,11 @@ interface KotlinTargetContainerWithPresetFunctions : KotlinTargetsContainerWithP presets.getByName("linuxX64") as KotlinNativeTargetPreset, configure ) + + fun linuxX64() = linuxX64("linuxX64") { } + fun linuxX64(name: String) = linuxX64(name) { } + fun linuxX64(name: String, configure: Closure<*>) = linuxX64(name) { ConfigureUtil.configure(configure, this) } + fun linuxX64(configure: Closure<*>) = linuxX64 { ConfigureUtil.configure(configure, this) } fun linuxArm32Hfp( name: String = "linuxArm32Hfp", @@ -106,6 +161,11 @@ interface KotlinTargetContainerWithPresetFunctions : KotlinTargetsContainerWithP presets.getByName("linuxArm32Hfp") as KotlinNativeTargetPreset, configure ) + + fun linuxArm32Hfp() = linuxArm32Hfp("linuxArm32Hfp") { } + fun linuxArm32Hfp(name: String) = linuxArm32Hfp(name) { } + fun linuxArm32Hfp(name: String, configure: Closure<*>) = linuxArm32Hfp(name) { ConfigureUtil.configure(configure, this) } + fun linuxArm32Hfp(configure: Closure<*>) = linuxArm32Hfp { ConfigureUtil.configure(configure, this) } fun linuxMips32( name: String = "linuxMips32", @@ -116,6 +176,11 @@ interface KotlinTargetContainerWithPresetFunctions : KotlinTargetsContainerWithP presets.getByName("linuxMips32") as KotlinNativeTargetPreset, configure ) + + fun linuxMips32() = linuxMips32("linuxMips32") { } + fun linuxMips32(name: String) = linuxMips32(name) { } + fun linuxMips32(name: String, configure: Closure<*>) = linuxMips32(name) { ConfigureUtil.configure(configure, this) } + fun linuxMips32(configure: Closure<*>) = linuxMips32 { ConfigureUtil.configure(configure, this) } fun linuxMipsel32( name: String = "linuxMipsel32", @@ -126,6 +191,11 @@ interface KotlinTargetContainerWithPresetFunctions : KotlinTargetsContainerWithP presets.getByName("linuxMipsel32") as KotlinNativeTargetPreset, configure ) + + fun linuxMipsel32() = linuxMipsel32("linuxMipsel32") { } + fun linuxMipsel32(name: String) = linuxMipsel32(name) { } + fun linuxMipsel32(name: String, configure: Closure<*>) = linuxMipsel32(name) { ConfigureUtil.configure(configure, this) } + fun linuxMipsel32(configure: Closure<*>) = linuxMipsel32 { ConfigureUtil.configure(configure, this) } fun mingwX64( name: String = "mingwX64", @@ -136,6 +206,11 @@ interface KotlinTargetContainerWithPresetFunctions : KotlinTargetsContainerWithP presets.getByName("mingwX64") as KotlinNativeTargetPreset, configure ) + + fun mingwX64() = mingwX64("mingwX64") { } + fun mingwX64(name: String) = mingwX64(name) { } + fun mingwX64(name: String, configure: Closure<*>) = mingwX64(name) { ConfigureUtil.configure(configure, this) } + fun mingwX64(configure: Closure<*>) = mingwX64 { ConfigureUtil.configure(configure, this) } fun macosX64( name: String = "macosX64", @@ -146,6 +221,11 @@ interface KotlinTargetContainerWithPresetFunctions : KotlinTargetsContainerWithP presets.getByName("macosX64") as KotlinNativeTargetPreset, configure ) + + fun macosX64() = macosX64("macosX64") { } + fun macosX64(name: String) = macosX64(name) { } + fun macosX64(name: String, configure: Closure<*>) = macosX64(name) { ConfigureUtil.configure(configure, this) } + fun macosX64(configure: Closure<*>) = macosX64 { ConfigureUtil.configure(configure, this) } fun wasm32( name: String = "wasm32", @@ -156,5 +236,10 @@ interface KotlinTargetContainerWithPresetFunctions : KotlinTargetsContainerWithP presets.getByName("wasm32") as KotlinNativeTargetPreset, configure ) + + fun wasm32() = wasm32("wasm32") { } + fun wasm32(name: String) = wasm32(name) { } + fun wasm32(name: String, configure: Closure<*>) = wasm32(name) { ConfigureUtil.configure(configure, this) } + fun wasm32(configure: Closure<*>) = wasm32 { ConfigureUtil.configure(configure, this) } } \ No newline at end of file