Migration to new multiplatorm plugin (#947)
Migration to a new multiplatform plugin
* kotlinx-coroutines-core-[common|js|native] are merged into one core module with multiple source sets
* Folder structure and readme are restructured
* Publication process is patched to preserve backward compatibility with artifact names
diff --git a/build.gradle b/build.gradle
index a6e81b7..01b2ec1 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,6 +1,26 @@
/*
- * Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
+ * Copyright 2016-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/
+import org.jetbrains.kotlin.konan.target.HostManager
+
+apply from: rootProject.file("gradle/experimental.gradle")
+
+def rootModule = "kotlinx.coroutines"
+def coreModule = "kotlinx-coroutines-core"
+// Not applicable for Kotlin plugin
+def sourceless = ['kotlinx.coroutines', 'site']
+def internal = sourceless + ['benchmarks', 'knit', 'js-stub', 'stdlib-stubs', 'binary-compatibility-validator']
+// Not published
+def unpublished = internal + ['kotlinx-coroutines-rx-example', 'example-frontend-js', 'android-unit-tests']
+
+static def platformOf(project) {
+ def name = project.name
+ if (name.endsWith("-js")) return "js"
+ if (name.endsWith("-common") || name.endsWith("-native")) {
+ throw IllegalStateException("$name platform is not supported")
+ }
+ return "jvm"
+}
buildscript {
ext.useKotlinSnapshot = rootProject.properties['kotlinSnapshot'] != null
@@ -19,22 +39,10 @@
maven { url "https://jetbrains.bintray.com/kotlin-native-dependencies" }
maven { url "https://plugins.gradle.org/m2/" }
}
- configurations.classpath {
- resolutionStrategy {
- eachDependency { DependencyResolveDetails details ->
- if (details.requested.group == 'org.jetbrains.kotlin' && details.requested.name != 'kotlin-native-gradle-plugin') {
- // fix version of all dependencies from org.jetbrains.kotlin group
- // even when other dependencies require other versions indirectly,
- // except kotlin-native, which has its own pre-release versioning
- details.useVersion kotlin_version
- }
- }
- }
- }
+
dependencies {
classpath "org.jfrog.buildinfo:build-info-extractor-gradle:$artifactory_plugin_version"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
- classpath "org.jetbrains.kotlin:kotlin-native-gradle-plugin:$kotlin_native_version"
classpath "org.jetbrains.dokka:dokka-gradle-plugin:$dokka_version"
classpath "org.jetbrains.kotlinx:atomicfu-gradle-plugin:$atomicFU_version"
classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:$bintray_version"
@@ -48,19 +56,26 @@
}
allprojects {
+ // the only place where HostManager could be instantiated
+ project.ext.hostManager = new HostManager()
+}
+
+allprojects {
+ apply plugin: 'kotlinx-atomicfu'
+
def deployVersion = properties['DeployVersion']
if (deployVersion != null) version = deployVersion
if (useKotlinSnapshot) {
kotlin_version = '1.2-SNAPSHOT'
}
- def name = it.name
+ def projectName = it.name
repositories {
/*
* google should be first in the repository list because some of the play services
* transitive dependencies was removed from jcenter, thus breaking gradle dependency resolution
*/
- if (name == "kotlinx-coroutines-play-services") {
+ if (projectName == "kotlinx-coroutines-play-services") {
google()
}
jcenter()
@@ -69,98 +84,63 @@
maven { url "https://kotlin.bintray.com/kotlin-eap" }
maven { url "https://kotlin.bintray.com/kotlinx" }
}
-}
+ if (projectName == rootModule || projectName == coreModule) return
-// Report Kotlin compiler version when building project
-println("Using Kotlin compiler version: $org.jetbrains.kotlin.config.KotlinCompilerVersion.VERSION")
+ // Add dependency to core source sets. Core is configured in kx-core/build.gradle
+ evaluationDependsOn(":$coreModule")
+ if (sourceless.contains(projectName)) return
-// --------------- Configure sub-projects with Kotlin sources ---------------
-
-def sourceless = ['site']
-
-static def platformOf(project) {
- if (project.name.endsWith("-common")) return "common"
- if (project.name.endsWith("-js")) return "js"
- if (project.name.endsWith("-native")) return "native"
- return "jvm"
-}
-
-static def platformLib(base, platform) {
- if (platform == "jvm") return base
- return "$base-$platform"
-}
-
-subprojects {
- if (useKotlinSnapshot) {
- repositories {
- maven { url "https://oss.sonatype.org/content/repositories/snapshots" }
- }
- }
- configurations.all {
- resolutionStrategy {
- eachDependency { DependencyResolveDetails details ->
- if (details.requested.group == 'org.jetbrains.kotlin') {
- details.useVersion kotlin_version
- }
- }
- }
- }
-}
-
-configure(subprojects.findAll { !sourceless.contains(it.name) }) {
def platform = platformOf(it)
apply from: rootProject.file("gradle/compile-${platform}.gradle")
+
+
+ dependencies {
+ // See comment below for rationale, it will be replaced with "project" dependency
+ compile "org.jetbrains.kotlinx:kotlinx-coroutines-core:$version"
+ compileOnly "org.jetbrains.kotlinx:atomicfu:$atomicFU_version"
+
+ // the only way IDEA can resolve test classes
+ testCompile project(":$coreModule").kotlin.targets.jvm.compilations.test.output.allOutputs
+ }
+
+ tasks.withType(org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile).all {
+ kotlinOptions.freeCompilerArgs += experimentalAnnotations.collect { "-Xuse-experimental=" + it }
+ kotlinOptions.freeCompilerArgs += "-progressive"
+ // Binary compatibility support
+ kotlinOptions.freeCompilerArgs += ["-Xdump-declarations-to=${buildDir}/visibilities.json"]
+ }
}
-// --------------- Configure sub-projects that are part of the library ---------------
+/*
+ * Hack to trick nmpp plugin: we are renaming artifacts in order to provide backward compatibility for dependencies,
+ * but publishing plugin does not re-read artifact names for kotlin-jvm projects, so renaming is not applied in pom files
+ * for JVM-only projects.
+ *
+ * We artificially replace "project" dependency with "module" one to have proper names in pom files, but then substitute it
+ * to have out "project" dependency back.
+ */
+configure(subprojects.findAll { it.name != coreModule && it.name != rootModule }) {
+ configurations.all {
+ resolutionStrategy.dependencySubstitution {
+ substitute module("org.jetbrains.kotlinx:kotlinx-coroutines-core:$version") with project(':kotlinx-coroutines-core')
+ }
+ }
+}
-def internal = sourceless + ['benchmarks', 'knit', 'js-stub', 'stdlib-stubs', 'binary-compatibility-validator']
-
-// Reconfigure source sets to avoid long "src/main/kotlin/fqn"
-configure(subprojects.findAll { !it.name.contains(sourceless) && it.name != "benchmarks" }) {
- def projectName = it.name
+// Redefine source sets because we are not using 'kotlin/main/fqn' folder convention
+configure(subprojects.findAll { !sourceless.contains(it.name) && it.name != "benchmarks" && it.name != coreModule }) {
sourceSets {
main.kotlin.srcDirs = ['src']
test.kotlin.srcDirs = ['test']
- // todo: do we still need this workaround?
- if (!projectName.endsWith("-native")) {
- main.resources.srcDirs = ['resources']
- test.resources.srcDirs = ['test-resources']
- }
+ main.resources.srcDirs = ['resources']
+ test.resources.srcDirs = ['test-resources']
+
}
}
-// configure atomicfu
-configure(subprojects.findAll { !internal.contains(it.name) }) {
- def platform = platformOf(it)
- apply from: rootProject.file("gradle/atomicfu-${platform}.gradle")
-}
-
-// configure dependencies on core
-configure(subprojects.findAll { !internal.contains(it.name) && it.name != 'kotlinx-coroutines-core-common'}) {
- def platform = platformOf(it)
- def coroutines_core = platformLib("kotlinx-coroutines-core", platform)
-
- if (it.name == coroutines_core) {
- dependencies {
- expectedBy project(':kotlinx-coroutines-core-common')
- }
- } else {
- dependencies {
- compile project(":$coroutines_core")
- //the only way IDEA can resolve test classes
- testCompile project(":$coroutines_core").sourceSets.test.output
- }
- }
-}
-
-// --------------- Configure sub-projects that are published ---------------
-
-def unpublished = internal + ['kotlinx-coroutines-rx-example', 'example-frontend-js', 'android-unit-tests']
-
-def core_docs_url = "https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/"
-def core_docs_file = "$projectDir/core/kotlinx-coroutines-core/build/dokka/kotlinx-coroutines-core/package-list"
+def core_docs_url = "https://kotlin.github.io/kotlinx.coroutines/$coreModule/"
+def core_docs_file = "$projectDir/kotlinx-coroutines-core/build/dokka/kotlinx-coroutines-core/package-list"
configure(subprojects.findAll { !unpublished.contains(it.name) }) {
apply from: rootProject.file('gradle/dokka.gradle')
@@ -168,12 +148,8 @@
}
configure(subprojects.findAll { !unpublished.contains(it.name) }) {
- def platform = platformOf(it)
- def coroutines_core = platformLib("kotlinx-coroutines-core", platform)
-
- if (it.name != coroutines_core) {
- dokka.dependsOn project(":$coroutines_core").dokka
-
+ if (it.name != coreModule) {
+ dokka.dependsOn project(":$coreModule").dokka
tasks.withType(dokka.getClass()) {
externalDocumentationLink {
url = new URL(core_docs_url)
@@ -182,27 +158,16 @@
}
}
- if (platform == "jvm") {
- dokkaJavadoc.dependsOn project(":$coroutines_core").dokka
- // dump declarations from main JVM module for binary-compatibility-validator
- compileKotlin {
- kotlinOptions.freeCompilerArgs += ["-Xdump-declarations-to=${buildDir}/visibilities.json"]
- }
- }
-
-
- tasks.withType(org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile).all {
- kotlinOptions.freeCompilerArgs += ["-Xuse-experimental=kotlin.Experimental",
- "-Xuse-experimental=kotlin.experimental.ExperimentalTypeInference",
- "-Xuse-experimental=kotlin.ExperimentalMultiplatform",
- "-Xuse-experimental=kotlinx.coroutines.ExperimentalCoroutinesApi",
- "-Xuse-experimental=kotlinx.coroutines.ObsoleteCoroutinesApi",
- "-Xuse-experimental=kotlinx.coroutines.InternalCoroutinesApi",
- "-progressive"]
+ if (platformOf(it) == "jvm") {
+ dokkaJavadoc.dependsOn project(":$coreModule").dokka
}
}
-// main deployment task
+
+// Report Kotlin compiler version when building project
+println("Using Kotlin compiler version: $org.jetbrains.kotlin.config.KotlinCompilerVersion.VERSION")
+
+// --------------- Configure sub-projects that are published ---------------
task deploy(dependsOn: getTasksByName("bintrayUpload", true) + getTasksByName("publishNpm", true))
apply plugin: 'base'