Przeglądaj źródła

Improve buildscript, fix publication

Him188 4 lat temu
rodzic
commit
988794343b

+ 2 - 2
build.gradle.kts

@@ -7,7 +7,7 @@
  *  https://github.com/mamoe/mirai/blob/master/LICENSE
  */
 
-@file:Suppress("UnstableApiUsage", "UNUSED_VARIABLE")
+@file:Suppress("UnstableApiUsage", "UNUSED_VARIABLE", "NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")
 
 import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
 import net.mamoe.kjbb.compiler.UnitCoercion.COMPATIBILITY
@@ -41,7 +41,7 @@ plugins {
     kotlin("plugin.serialization") version Versions.kotlinCompiler
     id("org.jetbrains.dokka") version Versions.dokka
     id("net.mamoe.kotlin-jvm-blocking-bridge") version Versions.blockingBridge
-    id("com.jfrog.bintray") version Versions.bintray
+    id("com.jfrog.bintray") // version Versions.bintray
 }
 
 // https://github.com/kotlin/binary-compatibility-validator

+ 21 - 9
buildSrc/build.gradle.kts

@@ -1,5 +1,5 @@
 /*
- * Copyright 2019-2020 Mamoe Technologies and contributors.
+ * Copyright 2019-2021 Mamoe Technologies and contributors.
  *
  *  此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
  *  Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@@ -23,17 +23,29 @@ kotlin {
     }
 }
 
+
+fun version(name: String): String {
+    val versions = project.projectDir.resolve("src/main/kotlin/Versions.kt").readText()
+
+    return versions.lineSequence()
+        .map { it.trim() }
+        .single { it.startsWith("const val $name") }
+        .substringAfter('"', "")
+        .substringBefore('"', "")
+        .also {
+            check(it.isNotBlank())
+            logger.debug("$name=$it")
+        }
+}
+
 dependencies {
     fun kotlinx(id: String, version: String) = "org.jetbrains.kotlinx:kotlinx-$id:$version"
     fun ktor(id: String, version: String) = "io.ktor:ktor-$id:$version"
 
-    api("org.jsoup:jsoup:1.12.1")
+    // compileOnly(kotlin("gradle-plugin-api", "1.3.72")) // Gradle's Kotlin is 1.3.72
+
+    api("com.jfrog.bintray.gradle", "gradle-bintray-plugin", version("bintray"))
+    api("com.github.jengelman.gradle.plugins", "shadow", version("shadow"))
 
-    api("com.google.code.gson:gson:2.8.6")
-    api(kotlinx("coroutines-core", "1.3.3"))
-    api(ktor("client-core", "1.3.2"))
-    api(ktor("client-cio", "1.3.2"))
-    api(ktor("client-json", "1.3.2"))
-    compileOnly("com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.5")
-    api("com.github.jengelman.gradle.plugins:shadow:6.0.0")
+    api(gradleApi())
 }

+ 119 - 0
buildSrc/src/main/kotlin/JvmPublishing.kt

@@ -0,0 +1,119 @@
+/*
+ * Copyright 2019-2021 Mamoe Technologies and contributors.
+ *
+ *  此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
+ *  Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
+ *
+ *  https://github.com/mamoe/mirai/blob/master/LICENSE
+ */
+
+@file:Suppress(
+    "NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS",
+    "RECEIVER_NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS"
+)
+
+import com.github.jengelman.gradle.plugins.shadow.ShadowPlugin
+import org.gradle.api.Project
+import org.gradle.api.publish.maven.MavenPublication
+import org.gradle.api.tasks.bundling.Jar
+import org.gradle.kotlin.dsl.apply
+import org.gradle.kotlin.dsl.get
+import org.gradle.kotlin.dsl.register
+import org.gradle.kotlin.dsl.registering
+
+/*
+ * Copyright 2020 Mamoe Technologies and contributors.
+ *
+ * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
+ * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
+ *
+ * https://github.com/mamoe/mirai/blob/master/LICENSE
+ */
+
+
+fun Project.configureBintray() {
+    tasks.register("ensureBintrayAvailable") {
+        doLast {
+            if (!project.isBintrayAvailable()) {
+                error("bintray isn't available. ")
+            }
+        }
+    }
+
+    if (isBintrayAvailable()) {
+        publishing {
+            repositories {
+                maven {
+                    setUrl("https://api.bintray.com/maven/him188moe/mirai/mirai-core/;publish=1;override=1")
+
+                    credentials {
+                        username = Bintray.getUser(project)
+                        password = Bintray.getKey(project)
+                    }
+                }
+            }
+        }
+    }
+}
+
+@Suppress("NOTHING_TO_INLINE")
+inline fun Project.configurePublishing(
+    artifactId: String,
+    bintrayRepo: String = "mirai",
+    bintrayPkgName: String = artifactId,
+    vcs: String = "https://github.com/mamoe/mirai"
+) {
+    configureBintray()
+    apply<ShadowPlugin>()
+
+    if (!project.isBintrayAvailable()) {
+        println("bintray isn't available. NO PUBLICATIONS WILL BE SET")
+        return
+    }
+
+    bintray {
+        user = Bintray.getUser(project)
+        key = Bintray.getKey(project)
+
+        setPublications("mavenJava")
+        setConfigurations("archives")
+
+        publish = true
+        override = true
+
+        pkg.apply {
+            repo = bintrayRepo
+            name = bintrayPkgName
+            setLicenses("AGPLv3")
+            publicDownloadNumbers = true
+            vcsUrl = vcs
+        }
+    }
+
+    val sourcesJar by tasks.registering(Jar::class) {
+        archiveClassifier.set("sources")
+        from(sourceSets["main"].allSource)
+    }
+
+    publishing {
+        publications {
+            register("mavenJava", MavenPublication::class) {
+                from(components["java"])
+
+                groupId = rootProject.group.toString()
+                setArtifactId(artifactId)
+                version = project.version.toString()
+
+                pom.withXml {
+                    val root = asNode()
+                    root.appendNode("description", description)
+                    root.appendNode("name", project.name)
+                    root.appendNode("url", vcs)
+                    root.children().last()
+                }
+
+                artifact(sourcesJar.get())
+            }
+        }
+    }
+}

+ 58 - 0
buildSrc/src/main/kotlin/Mpp.kt

@@ -0,0 +1,58 @@
+/*
+ * Copyright 2019-2021 Mamoe Technologies and contributors.
+ *
+ *  此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
+ *  Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
+ *
+ *  https://github.com/mamoe/mirai/blob/master/LICENSE
+ */
+
+import org.gradle.api.NamedDomainObjectCollection
+import org.gradle.api.NamedDomainObjectProvider
+import org.gradle.api.Project
+import org.gradle.kotlin.dsl.provideDelegate
+
+/*
+ * Copyright 2020 Mamoe Technologies and contributors.
+ *
+ * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
+ * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
+ *
+ * https://github.com/mamoe/mirai/blob/master/LICENSE
+ */
+
+val Project.isAndroidSDKAvailable: Boolean
+    get() {
+        val isAndroidSDKAvailable: Boolean by this
+        return isAndroidSDKAvailable
+    }
+
+val <T> NamedDomainObjectCollection<T>.androidMain: NamedDomainObjectProvider<T>
+    get() = named("androidMain")
+
+val <T> NamedDomainObjectCollection<T>.jvmMain: NamedDomainObjectProvider<T>
+    get() = named("jvmMain")
+
+val <T> NamedDomainObjectCollection<T>.androidTest: NamedDomainObjectProvider<T>
+    get() = named("androidTest")
+
+val <T> NamedDomainObjectCollection<T>.jvmTest: NamedDomainObjectProvider<T>
+    get() = named("jvmTest")
+
+val <T> NamedDomainObjectCollection<T>.commonMain: NamedDomainObjectProvider<T>
+    get() = named("commonMain")
+
+fun Project.printAndroidNotInstalled() {
+//    println(
+//        """Android SDK 可能未安装.
+//                $name 的 Android 目标编译将不会进行.
+//                这不会影响 Android 以外的平台的编译.
+//            """.trimIndent()
+//    )
+//    println(
+//        """Android SDK might not be installed.
+//                Android target of $name will not be compiled.
+//                It does no influence on the compilation of other platforms.
+//            """.trimIndent()
+//    )
+}

+ 128 - 0
buildSrc/src/main/kotlin/MppPublishing.kt

@@ -0,0 +1,128 @@
+/*
+ * Copyright 2020 Mamoe Technologies and contributors.
+ *
+ * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
+ * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
+ *
+ * https://github.com/mamoe/mirai/blob/master/LICENSE
+ */
+
+import org.gradle.api.Project
+import org.gradle.api.XmlProvider
+import org.gradle.api.publish.maven.MavenArtifact
+import org.gradle.api.publish.maven.MavenPublication
+import org.gradle.jvm.tasks.Jar
+import org.gradle.kotlin.dsl.get
+import org.gradle.kotlin.dsl.register
+import org.gradle.kotlin.dsl.withType
+
+fun logPublishing(message: String) {
+    println("[Publishing] Configuring $message")
+}
+
+fun Project.configureMppPublishing() {
+    configureBintray()
+
+    // mirai does some magic on MPP targets
+    afterEvaluate {
+        tasks.findByName("compileKotlinCommon")?.enabled = false
+        tasks.findByName("compileTestKotlinCommon")?.enabled = false
+
+        tasks.findByName("compileCommonMainKotlinMetadata")?.enabled = false
+        tasks.findByName("compileKotlinMetadata")?.enabled = false
+
+        tasks.findByName("generateMetadataFileForKotlinMultiplatformPublication")?.enabled = false // FIXME: 2021/1/21 
+    }
+
+    tasks.withType<com.jfrog.bintray.gradle.tasks.BintrayUploadTask> {
+        doFirst {
+            publications
+                .filterIsInstance<MavenPublication>()
+                .forEach { publication ->
+                    val moduleFile = buildDir.resolve("publications/${publication.name}/module.json")
+                    if (moduleFile.exists()) {
+                        publication.artifact(object :
+                            org.gradle.api.publish.maven.internal.artifact.FileBasedMavenArtifact(moduleFile) {
+                            override fun getDefaultExtension() = "module"
+                        })
+                    }
+                }
+        }
+    }
+
+    val stubJavadoc = tasks.register("javadocJar", Jar::class) {
+        @Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")
+        archiveClassifier.set("javadoc")
+    }
+
+    afterEvaluate {
+        publishing {
+            logPublishing("Publications: ${publications.joinToString { it.name }}")
+
+            publications.filterIsInstance<MavenPublication>().forEach { publication ->
+                if (publication.name != "kotlinMultiplatform") {
+                    publication.artifact(stubJavadoc)
+                }
+
+                logPublishing(publication.name)
+                when (val type = publication.name) {
+                    "kotlinMultiplatform" -> {
+                        publication.artifactId = project.name
+                        publishPlatformArtifactsInRootModule(publications.getByName("jvm") as MavenPublication)
+                    }
+                    "metadata" -> { // TODO: 2021/1/21 seems no use. none `type` is "metadata"
+                        publication.artifactId = "${project.name}-metadata"
+                    }
+                    "common" -> {
+                    }
+                    else -> {
+                        // "jvm", "native", "js"
+                        publication.artifactId = "${project.name}-$type"
+                    }
+                }
+            }
+        }
+    }
+}
+
+val publishPlatformArtifactsInRootModule: Project.(MavenPublication) -> Unit = { platformPublication ->
+    lateinit var platformPomBuilder: XmlProvider
+    platformPublication.pom.withXml { platformPomBuilder = this }
+
+    publications.getByName("kotlinMultiplatform").let { it as MavenPublication }.run {
+        this.artifacts.removeIf {
+            it.classifier == null && it.extension == "jar"
+            // mirai-core\build\libs\mirai-core-2.0.0.jar, classifier=null, ext=jar
+        }
+
+        logPublishing("Existing artifacts in kotlinMultiplatform: " +
+                this.artifacts.joinToString("\n", prefix = "\n") { it.smartToString() }
+        )
+
+        platformPublication.artifacts.forEach {
+            logPublishing("Adding artifact to kotlinMultiplatform: ${it.smartToString()}")
+            artifact(it)
+        }
+
+
+        // replace pom
+        pom.withXml {
+            val pomStringBuilder = asString()
+            pomStringBuilder.setLength(0)
+            platformPomBuilder.toString().lines().forEach { line ->
+                if (!line.contains("<!--")) { // Remove the Gradle module metadata marker as it will be added anew
+                    pomStringBuilder.append(line.replace(platformPublication.artifactId, artifactId))
+                    pomStringBuilder.append("\n")
+                }
+            }
+        }
+    }
+
+    tasks.matching { it.name == "generatePomFileForKotlinMultiplatformPublication" }.configureEach {
+        dependsOn(tasks["generatePomFileFor${platformPublication.name.capitalize()}Publication"])
+    }
+}
+
+private fun MavenArtifact.smartToString(): String {
+    return "${file.path}, classifier=${classifier}, ext=${extension}"
+}

+ 25 - 124
buildSrc/src/main/kotlin/PublishingHelpers.kt

@@ -1,5 +1,5 @@
 /*
- * Copyright 2019-2020 Mamoe Technologies and contributors.
+ * Copyright 2019-2021 Mamoe Technologies and contributors.
  *
  *  此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
  *  Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@@ -7,17 +7,20 @@
  *  https://github.com/mamoe/mirai/blob/master/LICENSE
  */
 
-@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "NOTHING_TO_INLINE", "RemoveRedundantBackticks")
+@file:Suppress(
+    "INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "NOTHING_TO_INLINE", "RemoveRedundantBackticks",
+    "NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS"
+)
 
-import com.github.jengelman.gradle.plugins.shadow.ShadowPlugin
 import org.gradle.api.Project
 import org.gradle.api.Task
-import org.gradle.api.publish.maven.MavenPublication
+import org.gradle.api.publish.PublicationContainer
 import org.gradle.api.tasks.TaskContainer
-import org.gradle.api.tasks.bundling.Jar
-import org.gradle.kotlin.dsl.*
-import upload.Bintray
-import java.util.*
+import org.gradle.kotlin.dsl.ExistingDomainObjectDelegate
+import org.gradle.kotlin.dsl.RegisteringDomainObjectDelegateProviderWithTypeAndAction
+import kotlin.contracts.ExperimentalContracts
+import kotlin.contracts.InvocationKind
+import kotlin.contracts.contract
 import kotlin.reflect.KProperty
 
 /*
@@ -33,7 +36,7 @@ import kotlin.reflect.KProperty
  * Configures the [bintray][com.jfrog.bintray.gradle.BintrayExtension] extension.
  */
 @PublishedApi
-internal fun org.gradle.api.Project.`bintray`(configure: com.jfrog.bintray.gradle.BintrayExtension.() -> Unit): Unit =
+internal fun Project.`bintray`(configure: com.jfrog.bintray.gradle.BintrayExtension.() -> Unit): Unit =
     (this as org.gradle.api.plugins.ExtensionAware).extensions.configure("bintray", configure)
 
 @PublishedApi
@@ -45,7 +48,7 @@ internal operator fun <U : Task> RegisteringDomainObjectDelegateProviderWithType
 )
 
 @PublishedApi
-internal val org.gradle.api.Project.`sourceSets`: org.gradle.api.tasks.SourceSetContainer
+internal val Project.`sourceSets`: org.gradle.api.tasks.SourceSetContainer
     get() =
         (this as org.gradle.api.plugins.ExtensionAware).extensions.getByName("sourceSets") as org.gradle.api.tasks.SourceSetContainer
 
@@ -56,123 +59,21 @@ internal operator fun <T> ExistingDomainObjectDelegate<out T>.getValue(receiver:
 /**
  * Configures the [publishing][org.gradle.api.publish.PublishingExtension] extension.
  */
+@OptIn(ExperimentalContracts::class)
 @PublishedApi
-internal fun org.gradle.api.Project.`publishing`(configure: org.gradle.api.publish.PublishingExtension.() -> Unit): Unit =
-    (this as org.gradle.api.plugins.ExtensionAware).extensions.configure("publishing", configure)
-
-
-inline fun Project.configurePublishing(
-    artifactId: String,
-    bintrayRepo: String = "mirai",
-    bintrayPkgName: String = artifactId,
-    addPrefixAll: Boolean = true,
-    vcs: String = "https://github.com/mamoe/mirai"
-) {
-
-    tasks.register("ensureBintrayAvailable") {
-        doLast {
-            if (!Bintray.isBintrayAvailable(project)) {
-                error("bintray isn't available. ")
-            }
-        }
-    }
-    apply<ShadowPlugin>()
-
-    // afterEvaluate {
-
-    /*
-    val shadowJar = tasks.filterIsInstance<ShadowJar>().firstOrNull() ?: return//@afterEvaluate
-
-    tasks.register("shadowJarMd5") {
-        dependsOn(shadowJar)
-
-        val outFiles = shadowJar.outputs.files.associateWith { file ->
-            File(file.parentFile, file.name.removeSuffix(".jar").removeSuffix("-all") + "-all.jar.md5")
-        }
-
-        outFiles.forEach { (_, output) ->
-            output.createNewFile()
-            outputs.files(output)
-        }
-
-        doLast {
-            for ((origin, output) in outFiles) {
-                output
-                    .writeText(origin.inputStream().md5().toUHexString().trim(Char::isWhitespace))
-            }
-        }
-
-        tasks.getByName("publish").dependsOn(this)
-        tasks.getByName("bintrayUpload").dependsOn(this)
+internal fun Project.`publishing`(configure: org.gradle.api.publish.PublishingExtension.() -> Unit): Unit {
+    contract {
+        callsInPlace(configure, InvocationKind.EXACTLY_ONCE)
     }
-    */
-
-    if (Bintray.isBintrayAvailable(project)) {
-        bintray {
-            val keyProps = Properties()
-            val keyFile = file("../keys.properties")
-            if (keyFile.exists()) keyFile.inputStream().use { keyProps.load(it) }
-            if (keyFile.exists()) keyFile.inputStream().use { keyProps.load(it) }
-
-            user = Bintray.getUser(project)
-            key = Bintray.getKey(project)
-            setPublications("mavenJava")
-            setConfigurations("archives")
-
-            publish = true
-            override = true
-
-            pkg.apply {
-                repo = bintrayRepo
-                name = bintrayPkgName
-                setLicenses("AGPLv3")
-                publicDownloadNumbers = true
-                vcsUrl = vcs
-            }
-        }
+    (this as org.gradle.api.plugins.ExtensionAware).extensions.configure("publishing", configure)
+}
 
-        @Suppress("DEPRECATION")
-        val sourcesJar by tasks.registering(Jar::class) {
-            classifier = "sources"
-            from(sourceSets["main"].allSource)
-        }
 
+val Project.publications: PublicationContainer
+    get() {
+        val ret: PublicationContainer
         publishing {
-            /*
-            repositories {
-                maven {
-                    // change to point to your repo, e.g. http://my.org/repo
-                    url = uri("$buildDir/repo")
-                }
-            }*/
-            publications {
-                register("mavenJava", MavenPublication::class) {
-                    from(components["java"])
-                    /*
-                    afterEvaluate {
-                        for (file in tasks.getByName("shadowJarMd5").outputs.files) {
-                            artifact(provider { file })
-                        }
-                    }
-                    */
-
-                    groupId = rootProject.group.toString()
-                    this.artifactId = artifactId
-                    version = version
-
-                    pom.withXml {
-                        val root = asNode()
-                        root.appendNode("description", description)
-                        root.appendNode("name", project.name)
-                        root.appendNode("url", vcs)
-                        root.children().last()
-                    }
-
-                    artifact(sourcesJar.get())
-                }
-            }
+            ret = publications
         }
-    } else println("bintray isn't available. NO PUBLICATIONS WILL BE SET")
-    //}
-
-}
+        return ret
+    }

+ 1 - 0
buildSrc/src/main/kotlin/Versions.kt

@@ -33,6 +33,7 @@ object Versions {
     const val androidGradlePlugin = "3.5.3"
 
     const val bintray = "1.8.5"
+    const val shadow = "6.1.0"
 
     const val slf4j = "1.7.30"
     const val log4j = "2.13.3"

+ 4 - 3
buildSrc/src/main/kotlin/upload/Bintray.kt

@@ -1,5 +1,5 @@
 /*
- * Copyright 2019-2020 Mamoe Technologies and contributors.
+ * Copyright 2019-2021 Mamoe Technologies and contributors.
  *
  *  此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
  *  Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@@ -7,8 +7,6 @@
  *  https://github.com/mamoe/mirai/blob/master/LICENSE
  */
 
-package upload
-
 import org.gradle.api.Project
 import org.gradle.kotlin.dsl.provideDelegate
 import java.io.File
@@ -21,6 +19,9 @@ import java.io.File
  *
  * https://github.com/mamoe/mirai/blob/master/LICENSE
  */
+fun Project.isBintrayAvailable() = Bintray.isBintrayAvailable(project)
+
+@Suppress("DuplicatedCode")
 object Bintray {
 
     @JvmStatic

+ 0 - 21
gradle/bintray.gradle

@@ -1,21 +0,0 @@
-/*
- * Copyright 2019-2020 Mamoe Technologies and contributors.
- *
- *  此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- *  Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- *  https://github.com/mamoe/mirai/blob/master/LICENSE
- */
-
-publishing {
-    repositories {
-        maven {
-            url = "https://api.bintray.com/maven/him188moe/mirai/mirai-core/;publish=1;override=1"
-
-            credentials {
-                username = upload.Bintray.getUser(project)
-                password = upload.Bintray.getKey(project)
-            }
-        }
-    }
-}

+ 8 - 0
gradle/mpp.gradle.kts

@@ -0,0 +1,8 @@
+/*
+ * Copyright 2019-2021 Mamoe Technologies and contributors.
+ *
+ *  此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
+ *  Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
+ *
+ *  https://github.com/mamoe/mirai/blob/master/LICENSE
+ */

+ 51 - 82
gradle/publish.gradle

@@ -1,5 +1,5 @@
 /*
- * Copyright 2019-2020 Mamoe Technologies and contributors.
+ * Copyright 2019-2021 Mamoe Technologies and contributors.
  *
  *  此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
  *  Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@@ -12,42 +12,12 @@
 
 tasks.register("ensureBintrayAvailable") {
     doLast {
-        if (!upload.Bintray.isBintrayAvailable(project)) {
+        if (!Bintray.isBintrayAvailable(project)) {
             throw new IllegalStateException("bintray isn't available. ")
         }
     }
 }
 
-def vcs = "https://github.com/mamoe/mirai"
-
-def pomConfig = {
-    licenses {
-        license {
-            name "AGPLv3 with Mamoe Exceptions"
-            url "https://github.com/mamoe/mirai/blob/master/LICENSE"
-            distribution "repo"
-        }
-    }
-    developers {
-        developer {
-            id "mamoe"
-            name "Mamoe Technologies"
-            email "support@mamoe.net"
-        }
-    }
-    scm {
-        url vcs
-    }
-}
-
-project.ext.configureMavenCentralMetadata = { pom ->
-    def root = asNode()
-    root.appendNode('name', project.name)
-    root.appendNode('description', project.description)
-    root.appendNode('url', vcs)
-    root.children().last() + pomConfig
-}
-
 try {
 
 // empty xxx-javadoc.jar
@@ -72,33 +42,32 @@ try {
  * (see details in https://youtrack.jetbrains.com/issue/KT-39184#focus=streamItem-27-4115233.0-0)
  */
 project.ext.publishPlatformArtifactsInRootModule = { platformPublication ->
-    afterEvaluate {
-        def platformPomBuilder = null
+    def platformPomBuilder = null
 
-        platformPublication.pom.withXml { platformPomBuilder = asString() }
+    platformPublication.pom.withXml { platformPomBuilder = asString() }
 
-        publishing.publications.kotlinMultiplatform {
-            platformPublication.artifacts.forEach {
-                artifact(it)
-            }
+    publishing.publications.kotlinMultiplatform {
+        platformPublication.artifacts.forEach {
+            println("Adding artiface to root: $it")
+            artifact(it)
+        }
 
-            pom.withXml {
-                def pomStringBuilder = asString()
-                pomStringBuilder.setLength(0)
-                // The platform POM needs its artifact ID replaced with the artifact ID of the root module:
-                def platformPomString = platformPomBuilder.toString()
-                platformPomString.eachLine { line ->
-                    if (!line.contains("<!--")) { // Remove the Gradle module metadata marker as it will be added anew
-                        pomStringBuilder.append(line.replace(platformPublication.artifactId, artifactId))
-                        pomStringBuilder.append("\n")
-                    }
+        pom.withXml {
+            def pomStringBuilder = asString()
+            pomStringBuilder.setLength(0)
+            // The platform POM needs its artifact ID replaced with the artifact ID of the root module:
+            def platformPomString = platformPomBuilder.toString()
+            platformPomString.eachLine { line ->
+                if (!line.contains("<!--")) { // Remove the Gradle module metadata marker as it will be added anew
+                    pomStringBuilder.append(line.replace(platformPublication.artifactId, artifactId))
+                    pomStringBuilder.append("\n")
                 }
             }
         }
+    }
 
-        tasks.matching { it.name == "generatePomFileForKotlinMultiplatformPublication" }.configureEach {
-            dependsOn(tasks["generatePomFileFor${platformPublication.name.capitalize()}Publication"])
-        }
+    tasks.matching { it.name == "generatePomFileForKotlinMultiplatformPublication" }.configureEach {
+        dependsOn(tasks["generatePomFileFor${platformPublication.name.capitalize()}Publication"])
     }
 }
 
@@ -111,47 +80,43 @@ afterEvaluate {
 
         // Rename artifacts for backward compatibility
         publications.all {
+            // add empty javadocs
+            if (it.name != "kotlinMultiplatform") {
+                it.artifact(javadocJar)
+            }
+
+            // Rename MPP artifacts for backward compatibility
             def type = it.name
-            logger.info("Configuring $type")
             switch (type) {
                 case 'kotlinMultiplatform':
-                    if (isKotlin137x) {
-                        it.artifactId = "$variantName-native"
-                        it.artifact sourcesJar
-                    } else {
-                        // With Kotlin 1.4.0, the root module ID has no suffix, but for compatibility with
-                        // the consumers who can't read Gradle module metadata, we publish the JVM artifacts in it
-                        it.artifactId = variantName
-                        // publishPlatformArtifactsInRootModule(publications["jvm"])
+                    // With Kotlin 1.4 & HMPP, the root module should have no suffix in the ID, but for compatibility with
+                    // the consumers who can't read Gradle module metadata, we publish the JVM artifacts in it, too
+                    it.artifactId = isKotlin137x ? "$project.name-native" : project.name
+                    if (!isKotlin137x) {
+                        publishPlatformArtifactsInRootModule(publications["jvm"])
                     }
                     break
-
                 case 'metadata':
-                    it.artifactId = isKotlin137x ? "$variantName-common" : "$variantName-metadata"
+                    // As the old -common dependencies will fail to resolve with Gradle module metadata, rename the module
+                    // to '*-metadata' so that the resolution failure are more clear
+                    it.artifactId = isKotlin137x ? "$project.name-common" : "$project.name-metadata"
                     break
-
                 case 'jvm':
-                    it.artifactId = isKotlin137x ? "$variantName" : "$variantName-jvm"
-                    /*
-                    def files = tasks.getByName("shadowJarMd5").outputs.files + tasks.getByName("shadowJvmJar").outputs.files
-                    for (f in files) {
-                        artifact f
-                    }
-                    */
+                    it.artifactId = isKotlin137x ? project.name : "$project.name-jvm"
                     break
-
                 case 'js':
-                    it.artifactId = "$variantName-$type"
+                case 'native':
+                    it.artifactId = "$project.name-$type"
                     break
             }
-            logger.info("Artifact id = ${it.artifactId}")
-
-            pom.withXml(configureMavenCentralMetadata)
-
-            // The 'root' module publishes the JVM module's Javadoc JAR as per publishPlatformArtifactsInRootModule, and
+            // Hierarchical project structures are not fully supported in 1.3.7x MPP
+            if (isKotlin137x) {
+                // disable metadata everywhere, but in native and js modules
+                if (type == 'maven' || type == 'metadata' || type == 'jvm') {
+                    moduleDescriptorGenerator = null
+                }
+            }
 
-            if (name != "kotlinMultiplatform")
-                artifact stubJavadoc
         }
 
         if (isKotlin137x) {
@@ -160,9 +125,13 @@ afterEvaluate {
     }
 }
 
+tasks.matching { it.name == "generatePomFileForKotlinMultiplatformPublication" }.configureEach {
+    dependsOn(tasks["generatePomFileForJvmPublication"])
+}
+
 
-if (upload.Bintray.isBintrayAvailable(project)) {
-    apply from: rootProject.file("gradle/bintray.gradle")
+if (Bintray.isBintrayAvailable(project)) {
+    project.configureBintray()
 }
 
 /*

+ 0 - 138
gradle/publishOld.gradle

@@ -1,138 +0,0 @@
-/*
- * Copyright 2019-2020 Mamoe Technologies and contributors.
- *
- *  此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- *  Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- *  https://github.com/mamoe/mirai/blob/master/LICENSE
- */
-
-import upload.Bintray
-
-// 部分源码来自 kotlinx.coroutines
-// Source code from kotlinx.coroutines
-
-task ensureBintrayAvailable() {
-    doLast {
-        if (!Bintray.isBintrayAvailable(project)) {
-            throw new IllegalStateException("bintray isn't available. ")
-        }
-    }
-}
-
-if (!Bintray.isBintrayAvailable(project)) {
-    println("bintray isn't available. NO PUBLICATIONS WILL BE SET")
-    return
-}
-
-def miraiGitHubUrl = "https://github.com/mamoe/mirai"
-
-bintray {
-    user = Bintray.getUser(project)
-    key = Bintray.getKey(project)
-
-    pkg {
-        repo = 'mirai'
-        name = "mirai-core"
-        licenses = ['AGPL']
-        vcsUrl = miraiGitHubUrl
-        websiteUrl = miraiGitHubUrl
-        githubRepo = miraiGitHubUrl
-        issueTrackerUrl = "$miraiGitHubUrl/issues"
-       /* version {
-            name = project.version
-        }*/
-    }
-}
-
-afterEvaluate {
-    project.publishing.publications.forEach { publication ->
-        publication.pom.withXml {
-            def root = asNode()
-            //root.appendNode('groupId', project.group)
-            //root.appendNode('artifactId', project.name)
-            //root.appendNode('version', project.version)
-            root.appendNode('name', project.name)
-            root.appendNode('description', project.description)
-            root.appendNode('url', miraiGitHubUrl)
-            root.children().last() + {
-                licenses {
-                    license {
-                        name "AGPL-V3"
-                        url "https://www.gnu.org/licenses/agpl-3.0.txt"
-                        distribution "repo"
-                    }
-                }
-                developers {
-                    developer {
-                        id "mamoe"
-                        name "Mamoe Technologies"
-                        email "support@mamoe.net"
-                    }
-                }
-                scm {
-                    url miraiGitHubUrl
-                }
-            }
-        }
-    }
-}
-
-bintrayUpload.doFirst {
-    publications = project.publishing.publications
-}
-
-bintrayUpload.dependsOn {
-    def list = new LinkedList<Task>()
-    list.add(tasks.getByName("build"))
-
-    list.addAll(tasks.findAll { task -> task.name.contains('Jar') })
-    list.addAll(tasks.findAll { task -> task.name.startsWith('generateMetadataFileFor') })
-    list.addAll(tasks.findAll { task -> task.name.startsWith('generatePomFileFor') })
-
-    list
-}
-
-try {
-
-// empty xxx-javadoc.jar
-    task javadocJar(type: Jar) {
-        archiveClassifier = 'javadoc'
-    }
-
-} catch (Exception ignored) {
-
-}
-publishing {
-    publications.all {
-        // add empty javadocs (no need for MPP root publication which publishes only pom file)
-        if (it.name != 'kotlinMultiplatform') {
-            it.artifact(javadocJar)
-        }
-
-        // Rename MPP artifacts for backward compatibility
-        def type = it.name
-        switch (type) {
-            case 'kotlinMultiplatform':
-                it.artifactId = "$project.name-native"
-                break
-            case 'metadata':
-                it.artifactId = "$project.name-common"
-                break
-            case 'jvm':
-                it.artifactId = "$project.name"
-                break
-            case 'js':
-            case 'native':
-                it.artifactId = "$project.name-$type"
-                break
-        }
-
-        // disable metadata everywhere, but in native modules
-        if (type == 'maven' || type == 'metadata' || type == 'jvm' || type == 'js') {
-            moduleDescriptorGenerator = null
-        }
-    }
-}
-
-// bintrayUpload.dependsOn publishToMavenLocal

+ 20 - 68
mirai-core-api/build.gradle.kts

@@ -12,26 +12,18 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
 
 plugins {
     kotlin("multiplatform")
-    id("kotlinx-atomicfu")
     kotlin("plugin.serialization")
+
+    id("kotlinx-atomicfu")
     id("signing")
     id("net.mamoe.kotlin-jvm-blocking-bridge")
+
     `maven-publish`
     id("com.jfrog.bintray")
 }
 
 description = "Mirai API module"
 
-val isAndroidSDKAvailable: Boolean by project
-
-afterEvaluate {
-    tasks.getByName("compileKotlinCommon").enabled = false
-    tasks.getByName("compileTestKotlinCommon").enabled = false
-
-    tasks.getByName("compileCommonMainKotlinMetadata").enabled = false
-    tasks.getByName("compileKotlinMetadata").enabled = false
-}
-
 kotlin {
     explicitApi()
 
@@ -41,18 +33,7 @@ kotlin {
             publishAllLibraryVariants()
         }
     } else {
-        println(
-            """Android SDK 可能未安装.
-                $name 的 Android 目标编译将不会进行. 
-                这不会影响 Android 以外的平台的编译.
-            """.trimIndent()
-        )
-        println(
-            """Android SDK might not be installed.
-                Android target of $name will not be compiled. 
-                It does no influence on the compilation of other platforms.
-            """.trimIndent()
-        )
+        printAndroidNotInstalled()
     }
 
     jvm("common") {
@@ -66,28 +47,30 @@ kotlin {
 //    }
 
     sourceSets {
-        val commonMain by getting {
+        commonMain {
             dependencies {
                 implementation(project(":mirai-core-utils"))
                 api(kotlin("serialization"))
                 api(kotlin("reflect"))
 
-                api1(`kotlinx-serialization-core`)
-                api1(`kotlinx-serialization-json`)
-                implementation1(`kotlinx-serialization-protobuf`)
-                api1(`kotlinx-io-jvm`)
-                api1(`kotlinx-coroutines-io-jvm`)
+                api(`kotlinx-serialization-core`)
+                api(`kotlinx-serialization-json`)
+                implementation(`kotlinx-serialization-protobuf`)
                 api(`kotlinx-coroutines-core`)
-               // api(`kotlinx-coroutines-jdk8`)
+                // api(`kotlinx-coroutines-jdk8`)
 
-                implementation1(`kotlinx-atomicfu`)
-
-                api1(`ktor-client-okhttp`)
-                api1(`ktor-client-core`)
-                api1(`ktor-network`)
+                api(`ktor-client-okhttp`)
+                api(`ktor-client-core`)
+                api(`ktor-network`)
 
                 compileOnly(`log4j-api`)
                 compileOnly(slf4j)
+
+
+                // they use Kotlin 1.3 so we need to ignore transitive dependencies
+                api1(`kotlinx-io-jvm`)
+                api1(`kotlinx-coroutines-io-jvm`)
+                implementation1(`kotlinx-atomicfu`)
             }
         }
 
@@ -101,29 +84,14 @@ kotlin {
 
         val jvmMain by getting
 
-        val jvmTest by getting {
+        jvmTest {
             dependencies {
-                api("org.pcap4j:pcap4j-distribution:1.8.2")
-
                 runtimeOnly(files("build/classes/kotlin/jvm/test")) // classpath is not properly set by IDE
             }
         }
     }
 }
 
-val NamedDomainObjectContainer<org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet>.androidMain: NamedDomainObjectProvider<org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet>
-    get() = named<org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet>("androidMain")
-
-val NamedDomainObjectContainer<org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet>.androidTest: NamedDomainObjectProvider<org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet>
-    get() = named<org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet>("androidTest")
-
-
-val NamedDomainObjectContainer<org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet>.jvmMain: NamedDomainObjectProvider<org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet>
-    get() = named<org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet>("jvmMain")
-
-val NamedDomainObjectContainer<org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet>.jvmTest: NamedDomainObjectProvider<org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet>
-    get() = named<org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet>("jvmTest")
-
 
 fun org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler.implementation1(dependencyNotation: String) =
     implementation(dependencyNotation) {
@@ -143,20 +111,4 @@ fun org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler.api1(dependencyNo
         exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core-metadata")
     }
 
-apply(from = rootProject.file("gradle/publish.gradle"))
-
-tasks.withType<com.jfrog.bintray.gradle.tasks.BintrayUploadTask> {
-    doFirst {
-        publishing.publications
-            .filterIsInstance<MavenPublication>()
-            .forEach { publication ->
-                val moduleFile = buildDir.resolve("publications/${publication.name}/module.json")
-                if (moduleFile.exists()) {
-                    publication.artifact(object :
-                        org.gradle.api.publish.maven.internal.artifact.FileBasedMavenArtifact(moduleFile) {
-                        override fun getDefaultExtension() = "module"
-                    })
-                }
-            }
-    }
-}
+configureMppPublishing()

+ 5 - 34
mirai-core-utils/build.gradle.kts

@@ -1,5 +1,5 @@
 /*
- * Copyright 2019-2020 Mamoe Technologies and contributors.
+ * Copyright 2019-2021 Mamoe Technologies and contributors.
  *
  *  此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
  *  Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@@ -13,14 +13,15 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
 
 plugins {
     kotlin("multiplatform")
-    id("kotlinx-atomicfu")
     kotlin("plugin.serialization")
+
+    id("kotlinx-atomicfu")
     id("net.mamoe.kotlin-jvm-blocking-bridge")
     `maven-publish`
     id("com.jfrog.bintray")
 }
 
-description = "mirai-core ultilities"
+description = "mirai-core utilities"
 
 val isAndroidSDKAvailable: Boolean by project
 
@@ -103,20 +104,6 @@ kotlin {
     }
 }
 
-val NamedDomainObjectContainer<org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet>.androidMain: NamedDomainObjectProvider<org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet>
-    get() = named<org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet>("androidMain")
-
-val NamedDomainObjectContainer<org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet>.androidTest: NamedDomainObjectProvider<org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet>
-    get() = named<org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet>("androidTest")
-
-
-val NamedDomainObjectContainer<org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet>.jvmMain: NamedDomainObjectProvider<org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet>
-    get() = named<org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet>("jvmMain")
-
-val NamedDomainObjectContainer<org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet>.jvmTest: NamedDomainObjectProvider<org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet>
-    get() = named<org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet>("jvmTest")
-
-
 fun org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler.implementation1(dependencyNotation: String) =
     implementation(dependencyNotation) {
         exclude("org.jetbrains.kotlin", "kotlin-stdlib")
@@ -135,20 +122,4 @@ fun org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler.api1(dependencyNo
         exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core-metadata")
     }
 
-apply(from = rootProject.file("gradle/publish.gradle"))
-
-tasks.withType<com.jfrog.bintray.gradle.tasks.BintrayUploadTask> {
-    doFirst {
-        publishing.publications
-            .filterIsInstance<MavenPublication>()
-            .forEach { publication ->
-                val moduleFile = buildDir.resolve("publications/${publication.name}/module.json")
-                if (moduleFile.exists()) {
-                    publication.artifact(object :
-                        org.gradle.api.publish.maven.internal.artifact.FileBasedMavenArtifact(moduleFile) {
-                        override fun getDefaultExtension() = "module"
-                    })
-                }
-            }
-    }
-}
+configureMppPublishing()

+ 2 - 45
mirai-core/build.gradle.kts

@@ -10,7 +10,6 @@
 @file:Suppress("UNUSED_VARIABLE")
 
 import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
-import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
 
 plugins {
     kotlin("multiplatform")
@@ -41,18 +40,7 @@ kotlin {
             publishAllLibraryVariants()
         }
     } else {
-        println(
-            """Android SDK 可能未安装.
-                $name 的 Android 目标编译将不会进行. 
-                这不会影响 Android 以外的平台的编译.
-            """.trimIndent()
-        )
-        println(
-            """Android SDK might not be installed.
-                Android target of $name will not be compiled. 
-                It does no influence on the compilation of other platforms.
-            """.trimIndent()
-        )
+        printAndroidNotInstalled()
     }
 
     jvm("common") {
@@ -127,20 +115,6 @@ kotlin {
     }
 }
 
-val NamedDomainObjectContainer<KotlinSourceSet>.androidMain: NamedDomainObjectProvider<KotlinSourceSet>
-    get() = named<KotlinSourceSet>("androidMain")
-
-val NamedDomainObjectContainer<KotlinSourceSet>.androidTest: NamedDomainObjectProvider<KotlinSourceSet>
-    get() = named<KotlinSourceSet>("androidTest")
-
-
-val NamedDomainObjectContainer<KotlinSourceSet>.jvmMain: NamedDomainObjectProvider<KotlinSourceSet>
-    get() = named<KotlinSourceSet>("jvmMain")
-
-val NamedDomainObjectContainer<KotlinSourceSet>.jvmTest: NamedDomainObjectProvider<KotlinSourceSet>
-    get() = named<KotlinSourceSet>("jvmTest")
-
-
 fun org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler.implementation1(dependencyNotation: String) =
     implementation(dependencyNotation) {
         exclude("org.jetbrains.kotlin", "kotlin-stdlib")
@@ -159,21 +133,4 @@ fun org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler.api1(dependencyNo
         exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core-metadata")
     }
 
-apply(from = rootProject.file("gradle/publish.gradle"))
-
-
-tasks.withType<com.jfrog.bintray.gradle.tasks.BintrayUploadTask> {
-    doFirst {
-        publishing.publications
-            .filterIsInstance<MavenPublication>()
-            .forEach { publication ->
-                val moduleFile = buildDir.resolve("publications/${publication.name}/module.json")
-                if (moduleFile.exists()) {
-                    publication.artifact(object :
-                        org.gradle.api.publish.maven.internal.artifact.FileBasedMavenArtifact(moduleFile) {
-                        override fun getDefaultExtension() = "module"
-                    })
-                }
-            }
-    }
-}
+configureMppPublishing()