Add missing DSL features to the MPP dependencies DSL
* Add DSL for project(...) with path and configuration
* Add DSL for e.g. api(someDependency) { /* ... */ }
* Add DSL for e.g. api(kotlin("stdlib"))
Issue #KT-26663 Fixed
This commit is contained in:
+35
-4
@@ -6,12 +6,43 @@
|
|||||||
package org.jetbrains.kotlin.gradle.plugin
|
package org.jetbrains.kotlin.gradle.plugin
|
||||||
|
|
||||||
import groovy.lang.Closure
|
import groovy.lang.Closure
|
||||||
|
import org.gradle.api.artifacts.Dependency
|
||||||
|
import org.gradle.api.artifacts.ExternalModuleDependency
|
||||||
|
import org.gradle.api.artifacts.ProjectDependency
|
||||||
|
import org.gradle.util.ConfigureUtil
|
||||||
|
|
||||||
interface KotlinDependencyHandler {
|
interface KotlinDependencyHandler {
|
||||||
fun api(dependencyNotation: Any)
|
fun api(dependencyNotation: Any): Dependency?
|
||||||
fun implementation(dependencyNotation: Any)
|
fun api(dependencyNotation: String, configure: ExternalModuleDependency.() -> Unit): ExternalModuleDependency
|
||||||
fun compileOnly(dependencyNotation: Any)
|
fun <T : Dependency> api(dependency: T, configure: T.() -> Unit): T
|
||||||
fun runtimeOnly(dependencyNotation: Any)
|
fun api(dependencyNotation: String, configure: Closure<*>) = api(dependencyNotation) { ConfigureUtil.configure(configure, this) }
|
||||||
|
fun <T : Dependency> api(dependency: T, configure: Closure<*>) = api(dependency) { ConfigureUtil.configure(configure, this) }
|
||||||
|
|
||||||
|
fun implementation(dependencyNotation: Any): Dependency?
|
||||||
|
fun implementation(dependencyNotation: String, configure: ExternalModuleDependency.() -> Unit): ExternalModuleDependency
|
||||||
|
fun <T : Dependency> implementation(dependency: T, configure: T.() -> Unit): T
|
||||||
|
fun implementation(dependencyNotation: String, configure: Closure<*>) = implementation(dependencyNotation) { ConfigureUtil.configure(configure, this) }
|
||||||
|
fun <T : Dependency> implementation(dependency: T, configure: Closure<*>) = implementation(dependency) { ConfigureUtil.configure(configure, this) }
|
||||||
|
|
||||||
|
fun compileOnly(dependencyNotation: Any): Dependency?
|
||||||
|
fun compileOnly(dependencyNotation: String, configure: ExternalModuleDependency.() -> Unit): ExternalModuleDependency
|
||||||
|
fun <T : Dependency> compileOnly(dependency: T, configure: T.() -> Unit): T
|
||||||
|
fun compileOnly(dependencyNotation: String, configure: Closure<*>) = compileOnly(dependencyNotation) { ConfigureUtil.configure(configure, this) }
|
||||||
|
fun <T : Dependency> compileOnly(dependency: T, configure: Closure<*>) = compileOnly(dependency) { ConfigureUtil.configure(configure, this) }
|
||||||
|
|
||||||
|
fun runtimeOnly(dependencyNotation: Any): Dependency?
|
||||||
|
fun runtimeOnly(dependencyNotation: String, configure: ExternalModuleDependency.() -> Unit): ExternalModuleDependency
|
||||||
|
fun <T : Dependency> runtimeOnly(dependency: T, configure: T.() -> Unit): T
|
||||||
|
fun runtimeOnly(dependencyNotation: String, configure: Closure<*>) = runtimeOnly(dependencyNotation) { ConfigureUtil.configure(configure, this) }
|
||||||
|
fun <T : Dependency> runtimeOnly(dependency: T, configure: Closure<*>) = runtimeOnly(dependency) { ConfigureUtil.configure(configure, this) }
|
||||||
|
|
||||||
|
fun kotlin(simpleModuleName: String): ExternalModuleDependency = kotlin(simpleModuleName, null)
|
||||||
|
fun kotlin(simpleModuleName: String, version: String?): ExternalModuleDependency
|
||||||
|
|
||||||
|
fun project(path: String, configuration: String? = null): ProjectDependency =
|
||||||
|
project(listOf("path", "configuration").zip(listOfNotNull(path, configuration)).toMap())
|
||||||
|
|
||||||
|
fun project(notation: Map<String, Any?>): ProjectDependency
|
||||||
}
|
}
|
||||||
|
|
||||||
interface HasKotlinDependencies {
|
interface HasKotlinDependencies {
|
||||||
|
|||||||
+31
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.gradle.plugin.sources.SourceSetConsistencyChecks
|
|||||||
import org.jetbrains.kotlin.gradle.util.checkBytecodeContains
|
import org.jetbrains.kotlin.gradle.util.checkBytecodeContains
|
||||||
import org.jetbrains.kotlin.gradle.util.isWindows
|
import org.jetbrains.kotlin.gradle.util.isWindows
|
||||||
import org.jetbrains.kotlin.gradle.util.modify
|
import org.jetbrains.kotlin.gradle.util.modify
|
||||||
|
import org.jetbrains.kotlin.gradle.util.testResolveAllConfigurations
|
||||||
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
||||||
import org.jetbrains.kotlin.konan.target.HostManager
|
import org.jetbrains.kotlin.konan.target.HostManager
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
@@ -1171,6 +1172,36 @@ class NewMultiplatformIT : BaseGradleIT() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testDependenciesDsl() = with(transformProjectWithPluginsDsl("newMppDependenciesDsl", GradleVersionRequired.AtLeast("4.10"))) {
|
||||||
|
val originalBuildscriptContent = gradleBuildScript("app").readText()
|
||||||
|
|
||||||
|
fun testDependencies() = testResolveAllConfigurations("app") {
|
||||||
|
assertContains(">> :app:testNonTransitiveStringNotationApi --> junit-4.12.jar")
|
||||||
|
assertEquals(1, (Regex.escape(">> :app:testNonTransitiveStringNotationApi") + " .*").toRegex().findAll(output).count())
|
||||||
|
|
||||||
|
assertContains(">> :app:testNonTransitiveDependencyNotationApi --> kotlin-reflect-${defaultBuildOptions().kotlinVersion}.jar")
|
||||||
|
assertEquals(1, (Regex.escape(">> :app:testNonTransitiveStringNotationApi") + " .*").toRegex().findAll(output).count())
|
||||||
|
|
||||||
|
assertContains(">> :app:testExplicitKotlinVersionApi --> kotlin-reflect-1.3.0.jar")
|
||||||
|
assertContains(">> :app:testExplicitKotlinVersionImplementation --> kotlin-reflect-1.2.71.jar")
|
||||||
|
assertContains(">> :app:testExplicitKotlinVersionCompileOnly --> kotlin-reflect-1.2.70.jar")
|
||||||
|
assertContains(">> :app:testExplicitKotlinVersionRuntimeOnly --> kotlin-reflect-1.2.60.jar")
|
||||||
|
|
||||||
|
assertContains(">> :app:testProjectWithConfigurationApi --> output.txt")
|
||||||
|
}
|
||||||
|
|
||||||
|
testDependencies()
|
||||||
|
|
||||||
|
// Then run with Gradle Kotlin DSL; the build script needs only one correction to be a valid GK DSL script:
|
||||||
|
gradleBuildScript("app").run {
|
||||||
|
modify { originalBuildscriptContent.replace(": ", " = ") }
|
||||||
|
renameTo(projectDir.resolve("app/build.gradle.kts"))
|
||||||
|
}
|
||||||
|
|
||||||
|
testDependencies()
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testUnusedSourceSetsReport() = with(Project("sample-lib", gradleVersion, "new-mpp-lib-and-app")) {
|
fun testUnusedSourceSetsReport() = with(Project("sample-lib", gradleVersion, "new-mpp-lib-and-app")) {
|
||||||
setupWorkingDir()
|
setupWorkingDir()
|
||||||
|
|||||||
+34
-1
@@ -19,7 +19,14 @@ fun BaseGradleIT.Project.testResolveAllConfigurations(
|
|||||||
) = with(testCase) {
|
) = with(testCase) {
|
||||||
|
|
||||||
setupWorkingDir()
|
setupWorkingDir()
|
||||||
gradleBuildScript(subproject).appendText("\n" + generateResolveAllConfigurationsTask(excludePredicate))
|
gradleBuildScript(subproject).run {
|
||||||
|
val taskCode = when (extension) {
|
||||||
|
"gradle" -> generateResolveAllConfigurationsTask(excludePredicate)
|
||||||
|
"kts" -> generateResolveAllConfigurationsTaskKts(excludePredicate)
|
||||||
|
else -> error("Unexpected build script extension $extension")
|
||||||
|
}
|
||||||
|
appendText("\n" + taskCode)
|
||||||
|
}
|
||||||
|
|
||||||
build(RESOLVE_ALL_CONFIGURATIONS_TASK_NAME) {
|
build(RESOLVE_ALL_CONFIGURATIONS_TASK_NAME) {
|
||||||
assertSuccessful()
|
assertSuccessful()
|
||||||
@@ -53,3 +60,29 @@ private fun generateResolveAllConfigurationsTask(exclude: String) =
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
|
|
||||||
|
private fun generateResolveAllConfigurationsTaskKts(exclude: String) =
|
||||||
|
"""
|
||||||
|
tasks.create("$RESOLVE_ALL_CONFIGURATIONS_TASK_NAME") {
|
||||||
|
doFirst {
|
||||||
|
project.configurations
|
||||||
|
.filter { it.isCanBeResolved }
|
||||||
|
.filterNot { $exclude }
|
||||||
|
.forEach { configuration ->
|
||||||
|
val path = (configuration as org.gradle.api.internal.artifacts.configurations.ConfigurationInternal).path
|
||||||
|
try {
|
||||||
|
println("Resolving ${'$'}path")
|
||||||
|
configuration.files.forEach { println(">> ${'$'}path --> ${'$'}{it.name}") }
|
||||||
|
println("OK, resolved ${'$'}path\n")
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
var ex = e as Throwable?
|
||||||
|
while (ex != null) {
|
||||||
|
println(ex.message)
|
||||||
|
ex = ex.cause
|
||||||
|
}
|
||||||
|
println("$UNRESOLVED_MARKER ${'$'}{configuration.name}\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""".trimIndent()
|
||||||
+3
-3
@@ -31,18 +31,18 @@ kotlin {
|
|||||||
sourceSets {
|
sourceSets {
|
||||||
val commonMain by getting {
|
val commonMain by getting {
|
||||||
dependencies {
|
dependencies {
|
||||||
api("org.jetbrains.kotlin:kotlin-stdlib-common")
|
api(kotlin("stdlib-common"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
jvm.compilations["main"].defaultSourceSet {
|
jvm.compilations["main"].defaultSourceSet {
|
||||||
dependencies {
|
dependencies {
|
||||||
api("org.jetbrains.kotlin:kotlin-stdlib")
|
api(kotlin("stdlib"))
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:0.23.4")
|
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:0.23.4")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
js.compilations["main"].defaultSourceSet {
|
js.compilations["main"].defaultSourceSet {
|
||||||
dependencies {
|
dependencies {
|
||||||
api("org.jetbrains.kotlin:kotlin-stdlib-js")
|
api(kotlin("stdlib-js"))
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-html-js:0.6.11")
|
implementation("org.jetbrains.kotlinx:kotlinx-html-js:0.6.11")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
plugins {
|
||||||
|
id("org.jetbrains.kotlin.multiplatform").version("<pluginMarkerVersion>")
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenLocal()
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
jvm("jvm6")
|
||||||
|
js { }
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
create("testNonTransitiveStringNotation") {
|
||||||
|
dependencies {
|
||||||
|
api("junit:junit:4.12") { setTransitive(false) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
create("testNonTransitiveDependencyNotation") {
|
||||||
|
dependencies {
|
||||||
|
api(kotlin("reflect")) { setTransitive(false) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
create("testExplicitKotlinVersion") {
|
||||||
|
dependencies {
|
||||||
|
api(kotlin("reflect", "1.3.0"))
|
||||||
|
implementation(kotlin("reflect", "1.2.71"))
|
||||||
|
compileOnly(kotlin("reflect", "1.2.70"))
|
||||||
|
runtimeOnly(kotlin("reflect", "1.2.60"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
create("testProjectWithConfiguration") {
|
||||||
|
dependencies {
|
||||||
|
api(project(path: ":lib", configuration: "outputConfiguration"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
plugins {
|
||||||
|
id 'java'
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenLocal()
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
|
||||||
|
configurations {
|
||||||
|
outputConfiguration
|
||||||
|
}
|
||||||
|
|
||||||
|
artifacts {
|
||||||
|
outputConfiguration file('output.txt')
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
pluginManagement {
|
||||||
|
repositories {
|
||||||
|
mavenLocal()
|
||||||
|
gradlePluginPortal()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
include ':lib', ':app'
|
||||||
+80
@@ -0,0 +1,80 @@
|
|||||||
|
package org.jetbrains.kotlin.gradle.plugin.mpp
|
||||||
|
|
||||||
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.artifacts.Dependency
|
||||||
|
import org.gradle.api.artifacts.ExternalModuleDependency
|
||||||
|
import org.gradle.api.artifacts.ProjectDependency
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.HasKotlinDependencies
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler
|
||||||
|
|
||||||
|
class DefaultKotlinDependencyHandler(
|
||||||
|
val parent: HasKotlinDependencies,
|
||||||
|
val project: Project
|
||||||
|
) : KotlinDependencyHandler {
|
||||||
|
override fun api(dependencyNotation: Any): Dependency? =
|
||||||
|
addDependencyByAnyNotation(parent.apiConfigurationName, dependencyNotation)
|
||||||
|
|
||||||
|
override fun api(dependencyNotation: String, configure: ExternalModuleDependency.() -> Unit): ExternalModuleDependency =
|
||||||
|
addDependencyByStringNotation(parent.apiConfigurationName, dependencyNotation, configure)
|
||||||
|
|
||||||
|
override fun <T : Dependency> api(dependency: T, configure: T.() -> Unit): T =
|
||||||
|
addDependency(parent.apiConfigurationName, dependency, configure)
|
||||||
|
|
||||||
|
override fun implementation(dependencyNotation: Any): Dependency? =
|
||||||
|
addDependencyByAnyNotation(parent.implementationConfigurationName, dependencyNotation)
|
||||||
|
|
||||||
|
override fun implementation(dependencyNotation: String, configure: ExternalModuleDependency.() -> Unit): ExternalModuleDependency =
|
||||||
|
addDependencyByStringNotation(parent.implementationConfigurationName, dependencyNotation, configure)
|
||||||
|
|
||||||
|
override fun <T : Dependency> implementation(dependency: T, configure: T.() -> Unit): T =
|
||||||
|
addDependency(parent.implementationConfigurationName, dependency, configure)
|
||||||
|
|
||||||
|
override fun compileOnly(dependencyNotation: Any): Dependency? =
|
||||||
|
addDependencyByAnyNotation(parent.compileOnlyConfigurationName, dependencyNotation)
|
||||||
|
|
||||||
|
override fun compileOnly(dependencyNotation: String, configure: ExternalModuleDependency.() -> Unit): ExternalModuleDependency =
|
||||||
|
addDependencyByStringNotation(parent.compileOnlyConfigurationName, dependencyNotation, configure)
|
||||||
|
|
||||||
|
override fun <T : Dependency> compileOnly(dependency: T, configure: T.() -> Unit): T =
|
||||||
|
addDependency(parent.compileOnlyConfigurationName, dependency, configure)
|
||||||
|
|
||||||
|
override fun runtimeOnly(dependencyNotation: Any): Dependency? =
|
||||||
|
addDependencyByAnyNotation(parent.runtimeOnlyConfigurationName, dependencyNotation)
|
||||||
|
|
||||||
|
override fun runtimeOnly(dependencyNotation: String, configure: ExternalModuleDependency.() -> Unit): ExternalModuleDependency =
|
||||||
|
addDependencyByStringNotation(parent.runtimeOnlyConfigurationName, dependencyNotation, configure)
|
||||||
|
|
||||||
|
override fun <T : Dependency> runtimeOnly(dependency: T, configure: T.() -> Unit): T =
|
||||||
|
addDependency(parent.runtimeOnlyConfigurationName, dependency, configure)
|
||||||
|
|
||||||
|
override fun kotlin(simpleModuleName: String, version: String?): ExternalModuleDependency =
|
||||||
|
project.dependencies.create(
|
||||||
|
"org.jetbrains.kotlin:kotlin-$simpleModuleName" + version?.let { ":$it" }.orEmpty()
|
||||||
|
) as ExternalModuleDependency
|
||||||
|
|
||||||
|
override fun project(notation: Map<String, Any?>): ProjectDependency =
|
||||||
|
project.dependencies.project(notation) as ProjectDependency
|
||||||
|
|
||||||
|
private fun addDependencyByAnyNotation(
|
||||||
|
configurationName: String,
|
||||||
|
dependencyNotation: Any
|
||||||
|
): Dependency? =
|
||||||
|
project.dependencies.add(configurationName, dependencyNotation)
|
||||||
|
|
||||||
|
private fun addDependencyByStringNotation(
|
||||||
|
configurationName: String,
|
||||||
|
dependencyNotation: Any,
|
||||||
|
configure: ExternalModuleDependency.() -> Unit = { }
|
||||||
|
): ExternalModuleDependency =
|
||||||
|
addDependency(configurationName, project.dependencies.create(dependencyNotation) as ExternalModuleDependency, configure)
|
||||||
|
|
||||||
|
private fun <T : Dependency> addDependency(
|
||||||
|
configurationName: String,
|
||||||
|
dependency: T,
|
||||||
|
configure: T.() -> Unit
|
||||||
|
): T =
|
||||||
|
dependency.also {
|
||||||
|
configure(it)
|
||||||
|
project.dependencies.add(configurationName, it)
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-18
@@ -1,4 +1,4 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
* that can be found in the license/LICENSE.txt file.
|
* that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
@@ -38,23 +38,6 @@ internal fun KotlinCompilation<*>.composeName(prefix: String? = null, suffix: St
|
|||||||
internal val KotlinCompilation<*>.defaultSourceSetName: String
|
internal val KotlinCompilation<*>.defaultSourceSetName: String
|
||||||
get() = lowerCamelCaseName(target.disambiguationClassifier, compilationName)
|
get() = lowerCamelCaseName(target.disambiguationClassifier, compilationName)
|
||||||
|
|
||||||
internal class DefaultKotlinDependencyHandler(
|
|
||||||
val parent: HasKotlinDependencies,
|
|
||||||
val project: Project
|
|
||||||
) : KotlinDependencyHandler {
|
|
||||||
override fun api(dependencyNotation: Any) = addDependency(parent.apiConfigurationName, dependencyNotation)
|
|
||||||
|
|
||||||
override fun implementation(dependencyNotation: Any) = addDependency(parent.implementationConfigurationName, dependencyNotation)
|
|
||||||
|
|
||||||
override fun compileOnly(dependencyNotation: Any) = addDependency(parent.compileOnlyConfigurationName, dependencyNotation)
|
|
||||||
|
|
||||||
override fun runtimeOnly(dependencyNotation: Any) = addDependency(parent.runtimeOnlyConfigurationName, dependencyNotation)
|
|
||||||
|
|
||||||
private fun addDependency(configurationName: String, dependencyNotation: Any) {
|
|
||||||
project.dependencies.add(configurationName, dependencyNotation)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class AbstractKotlinCompilation<T : KotlinCommonOptions>(
|
abstract class AbstractKotlinCompilation<T : KotlinCommonOptions>(
|
||||||
target: KotlinTarget,
|
target: KotlinTarget,
|
||||||
override val compilationName: String
|
override val compilationName: String
|
||||||
|
|||||||
Reference in New Issue
Block a user