Configure shadow relocation and add checks for multiplatform publishing

This commit is contained in:
Him188 2022-06-26 16:03:15 +08:00
parent dc747ea438
commit fd67ba9204
25 changed files with 1034 additions and 187 deletions

View File

@ -280,6 +280,9 @@ jobs:
- name: "Assemble"
run: ./gradlew assemble ${{ env.gradleArgs }}
- name: Publish Local Artifacts
run: ./gradlew :mirai-deps-test:publishMiraiLocalArtifacts ${{ env.gradleArgs }}
- name: "Check"
run: ./gradlew check ${{ env.gradleArgs }}
@ -402,4 +405,10 @@ jobs:
run: ./gradlew :mirai-core-api:${{ matrix.targetName }}Test ${{ env.gradleArgs }}
- name: "Test mirai-core for ${{ matrix.os }}"
run: ./gradlew :mirai-core:${{ matrix.targetName }}Test ${{ env.gradleArgs }}
run: ./gradlew :mirai-core:${{ matrix.targetName }}Test ${{ env.gradleArgs }}
- name: Publish Local Artifacts
run: ./gradlew :mirai-deps-test:publishMiraiLocalArtifacts ${{ env.gradleArgs }}
- name: Check Publication
run: ./gradlew :mirai-deps-test:check ${{ env.gradleArgs }}

View File

@ -37,9 +37,13 @@ jobs:
- name: Assemble
run: ./gradlew assemble --scan
- name: Publish Local Artifacts
run: >
./gradlew :mirai-deps-test:publishMiraiLocalArtifacts --scan
- name: Check
run: >
./gradlew check --scan --no-parallel
./gradlew check --scan
-Dmirai.network.show.all.components=true
-Dkotlinx.coroutines.debug=on
-Dmirai.network.show.packet.details=true

View File

@ -12,8 +12,6 @@
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import org.jetbrains.dokka.base.DokkaBase
import org.jetbrains.dokka.base.DokkaBaseConfiguration
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import java.time.LocalDateTime
buildscript {
@ -35,12 +33,13 @@ buildscript {
}
plugins {
kotlin("jvm") // version Versions.kotlinCompiler
kotlin("plugin.serialization") version Versions.kotlinCompiler
kotlin("jvm") apply false // version Versions.kotlinCompiler
kotlin("plugin.serialization") version Versions.kotlinCompiler apply false
id("com.google.osdetector")
id("org.jetbrains.dokka") version Versions.dokka
id("me.him188.kotlin-jvm-blocking-bridge") version Versions.blockingBridge
id("me.him188.kotlin-dynamic-delegation") version Versions.dynamicDelegation
id("me.him188.kotlin-dynamic-delegation") version Versions.dynamicDelegation apply false
id("me.him188.maven-central-publish") version Versions.mavenCentralPublish apply false
id("com.gradle.plugin-publish") version "1.0.0-rc-3" apply false
id("org.jetbrains.kotlinx.binary-compatibility-validator") version Versions.binaryValidator apply false
}
@ -179,43 +178,3 @@ fun Project.configureDokka() {
}
}
}
fun Project.configureMppShadow() {
val kotlin =
runCatching {
(this as ExtensionAware).extensions.getByName("kotlin") as? KotlinMultiplatformExtension
}.getOrNull() ?: return
if (project.configurations.findByName("jvmRuntimeClasspath") != null) {
val shadowJvmJar by tasks.creating(ShadowJar::class) sd@{
group = "mirai"
archiveClassifier.set("-all")
val compilations =
kotlin.targets.filter { it.platformType == KotlinPlatformType.jvm }
.map { it.compilations["main"] }
compilations.forEach {
dependsOn(it.compileKotlinTask)
from(it.output)
}
from(project.configurations.findByName("jvmRuntimeClasspath"))
this.exclude { file ->
file.name.endsWith(".sf", ignoreCase = true)
}
/*
this.manifest {
this.attributes(
"Manifest-Version" to 1,
"Implementation-Vendor" to "Mamoe Technologies",
"Implementation-Title" to this.name.toString(),
"Implementation-Version" to this.version.toString()
)
}*/
}
}
}

View File

@ -57,6 +57,7 @@ dependencies {
api(asm("tree"))
api(asm("util"))
api(asm("commons"))
api("org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.2")
api("gradle.plugin.com.google.gradle:osdetector-gradle-plugin:1.7.0")

View File

@ -25,7 +25,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType
import org.jetbrains.kotlin.gradle.plugin.mpp.TestExecutable
import java.io.File
private val miraiPlatform = Attribute.of(
val MIRAI_PLATFORM_ATTRIBUTE = Attribute.of(
"net.mamoe.mirai.platform", String::class.java
)
@ -140,7 +140,7 @@ fun Project.configureJvmTargetsHierarchical() {
this.compileKotlinTask.enabled = false // IDE complain
}
attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.common) // magic
attributes.attribute(miraiPlatform, "jvmBase") // avoid resolution
attributes.attribute(MIRAI_PLATFORM_ATTRIBUTE, "jvmBase") // avoid resolution
}
}
@ -160,7 +160,7 @@ fun Project.configureJvmTargetsHierarchical() {
jvm("android") {
attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.androidJvm)
if (IDEA_ACTIVE) {
attributes.attribute(miraiPlatform, "android") // avoid resolution
attributes.attribute(MIRAI_PLATFORM_ATTRIBUTE, "android") // avoid resolution
}
}
val androidMain by sourceSets.getting

View File

@ -1,10 +1,10 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
* Copyright 2019-2022 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.
* 此源代码的使用受 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
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
import org.gradle.api.NamedDomainObjectCollection
@ -13,17 +13,10 @@ import org.gradle.api.Project
import org.gradle.api.artifacts.DependencySubstitutions
import org.gradle.api.artifacts.ResolutionStrategy
import org.gradle.api.artifacts.component.ComponentSelector
import org.gradle.api.plugins.ExtensionAware
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import java.util.*
/*
* 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
*/
private object ProjectAndroidSdkAvailability {
val map: MutableMap<String, Boolean> = mutableMapOf()
@ -117,3 +110,10 @@ fun ResolutionStrategy.substituteDependencies(action: ResolutionStrategyDsl.() -
action(ResolutionStrategyDsl(this))
}
}
val Project.kotlinMpp
get() = runCatching {
(this as ExtensionAware).extensions.getByName("kotlin") as? KotlinMultiplatformExtension
}.getOrNull()

View File

@ -11,6 +11,7 @@ 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.api.tasks.TaskProvider
import org.gradle.jvm.tasks.Jar
import org.gradle.kotlin.dsl.get
import org.gradle.kotlin.dsl.register
@ -43,30 +44,39 @@ fun Project.configureMppPublishing() {
publishing {
logPublishing("Publications: ${publications.joinToString { it.name }}")
publications.filterIsInstance<MavenPublication>().forEach { publication ->
// Maven Central always require javadoc.jar
publication.artifact(stubJavadoc)
val (nonJvmPublications, jvmPublications) = publications.filterIsInstance<MavenPublication>()
.partition { publication -> tasks.findByName("relocate${publication.name.titlecase()}Dependencies") == null }
publication.setupPom(project)
logPublishing(publication.name)
when (val type = publication.name) {
"kotlinMultiplatform" -> {
publication.artifactId = project.name
// publishPlatformArtifactsInRootModule(publications.getByName("jvm") as MavenPublication)
// TODO: 2021/1/30 现在添加 JVM 到 root module 会导致 Gradle 依赖无法解决
// https://github.com/mamoe/mirai/issues/932
}
"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"
for (publication in nonJvmPublications) {
configureMultiplatformPublication(publication, stubJavadoc, publication.name)
}
for (publication in jvmPublications) {
// publications.remove(publication)
// val newPublication =
// publications.register(publication.name + "Shadowed", MavenPublication::class.java) {
// val target = kotlinTargets.orEmpty().single { it.targetName == publication.name }
// from(target.components.single())
// this.groupId = publication.groupId
// this.artifactId = publication.artifactId
// this.version = publication.version
// artifacts {
// publication.artifacts
// .filter { !(it.classifier.isNullOrEmpty() && it.extension == "jar") } // not .jar
// .forEach { artifact(it) } // copy Kotlin metadata artifacts
// }
// artifacts.removeAll { it.classifier.isNullOrEmpty() && it.extension == "jar" }
// // add relocated jar
// tasks.findByName("relocate${publication.name.titlecase()}Dependencies")?.let { relocation ->
// artifact(relocation) {
// classifier = ""
// extension = "jar"
// }
// }
// }
configureMultiplatformPublication(publication, stubJavadoc, publication.name)
publication.apply {
artifacts.filter { it.classifier.isNullOrEmpty() && it.extension == "jar" }.forEach {
it.builtBy(tasks.findByName("relocate${publication.name.titlecase()}Dependencies"))
}
}
}
@ -75,6 +85,35 @@ fun Project.configureMppPublishing() {
}
}
private fun Project.configureMultiplatformPublication(
publication: MavenPublication,
stubJavadoc: TaskProvider<Jar>,
moduleName: String,
) {
// Maven Central always require javadoc.jar
publication.artifact(stubJavadoc)
publication.setupPom(project)
logPublishing(publication.name + ": moduleName = $moduleName")
when (moduleName) {
"kotlinMultiplatform" -> {
publication.artifactId = project.name
// publishPlatformArtifactsInRootModule(publications.getByName("jvm") as MavenPublication)
// TODO: 2021/1/30 现在添加 JVM 到 root module 会导致 Gradle 依赖无法解决
// https://github.com/mamoe/mirai/issues/932
}
"metadata" -> { // TODO: 2021/1/21 seems no use. none `type` is "metadata"
publication.artifactId = "${project.name}-metadata"
}
else -> {
// "jvm", "native", "js", "common"
publication.artifactId = "${project.name}-$moduleName"
}
}
}
val publishPlatformArtifactsInRootModule: Project.(MavenPublication) -> Unit = { platformPublication ->
lateinit var platformPomBuilder: XmlProvider
platformPublication.pom.withXml { platformPomBuilder = this }

View File

@ -111,8 +111,8 @@ fun Project.configureKotlinTestSettings() {
dependencies {
"testImplementation"(kotlin("test-junit5"))?.because(b)
"testApi"("org.junit.jupiter:junit-jupiter-api:${Versions.junit}")?.because(b)
"testRuntimeOnly"("org.junit.jupiter:junit-jupiter-engine:${Versions.junit}")?.because(b)
"testApi"(`junit-jupiter-api`)?.because(b)
"testRuntimeOnly"(`junit-jupiter-engine`)?.because(b)
}
}
isKotlinMpp -> {
@ -121,8 +121,8 @@ fun Project.configureKotlinTestSettings() {
sourceSet.dependencies {
implementation(kotlin("test-junit5"))?.because(b)
implementation("org.junit.jupiter:junit-jupiter-api:${Versions.junit}")?.because(b)
runtimeOnly("org.junit.jupiter:junit-jupiter-engine:${Versions.junit}")?.because(b)
implementation(`junit-jupiter-api`)?.because(b)
runtimeOnly(`junit-jupiter-engine`)?.because(b)
}
}

View File

@ -0,0 +1,276 @@
/*
* Copyright 2019-2022 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/dev/LICENSE
*/
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import org.gradle.api.DomainObjectCollection
import org.gradle.api.Project
import org.gradle.api.publish.tasks.GenerateModuleMetadata
import org.gradle.kotlin.dsl.create
import org.gradle.kotlin.dsl.creating
import org.gradle.kotlin.dsl.extra
import org.gradle.kotlin.dsl.get
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import java.io.File
fun Project.configureMppShadow() {
val kotlin = kotlinMpp ?: return
configure(kotlin.targets.filter {
it.platformType == org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType.jvm
&& it.attributes.getAttribute(MIRAI_PLATFORM_ATTRIBUTE) == null
}) {
configureRelocationForTarget(project)
}
// regular shadow file, with suffix `-all`
configureRegularShadowJar(kotlin)
}
/**
* Relocate some dependencies for `.jar`
*/
private fun KotlinTarget.configureRelocationForTarget(project: Project) = project.run {
val relocateDependencies =
// e.g. relocateJvmDependencies
tasks.create("relocate${targetName.titlecase()}Dependencies", ShadowJar::class) {
group = "mirai"
description = "Relocate dependencies to internal package"
destinationDirectory.set(buildDir.resolve("libs"))
// archiveClassifier.set("")
archiveBaseName.set("${project.name}-${targetName.toLowerCase()}")
dependsOn(compilations["main"].compileKotlinTask) // compileKotlinJvm
// Run after all *Jar tasks from all projects, since Kotlin compiler may depend on the .jar file, concurrently modifying the jar will cause Kotlin compiler to fail.
// allprojects
// .asSequence()
// .flatMap { it.tasks }
// .filter { it.name.contains("compileKotlin") }
// .forEach { jar ->
// mustRunAfter(jar)
// }
from(compilations["main"].output)
// // change name to
// doLast {
// outputs.files.singleFile.renameTo(
// outputs.files.singleFile.parentFile.resolve(
// "${project.name}-${targetName.toLowerCase()}-${project.version}.jar"
// )
// )
// }
// Filter only those should be relocated
afterEvaluate {
setRelocations()
var fileFiltered = relocationFilters.isEmpty()
from(project.configurations.getByName("${targetName}RuntimeClasspath")
.files
.filter { file ->
relocationFilters.any { filter ->
// file.absolutePath example: /Users/xxx/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jdk8/1.7.0-RC/7f9f07fc65e534c15a820f61d846b9ffdba8f162/kotlin-stdlib-jdk8-1.7.0-RC.jar
filter.matchesFile(file)
}.also {
fileFiltered = fileFiltered || it
if (it) {
println("Including file: ${file.absolutePath}")
}
}
}
)
check(fileFiltered) { "[Shadow Relocation] Expected at least one file filtered for target $targetName. Filters: $relocationFilters" }
}
}
val allTasks = rootProject.allprojects.asSequence().flatMap { it.tasks }
allTasks
.filter {
it.name.startsWith("publish${targetName.titlecase()}PublicationTo")
}
.onEach { it.dependsOn(relocateDependencies) }
.count().let {
check(it > 0) { "[Shadow Relocation] Expected at least one publication matched for target $targetName." }
}
// Ensure all compilation has finished, otherwise Kotlin compiler will complain.
allTasks
.filter { it.name.endsWith("Jar") }
.onEach { relocateDependencies.dependsOn(it) }
.count().let {
check(it > 0) { "[Shadow Relocation] Expected at least one task matched for target $targetName." }
}
allTasks
.filter { it.name.startsWith("compileKotlin") }
.onEach { relocateDependencies.dependsOn(it) }
.count().let {
check(it > 0) { "[Shadow Relocation] Expected at least one task matched for target $targetName." }
}
val metadataTask =
tasks.getByName("generateMetadataFileFor${targetName.capitalize()}Publication") as GenerateModuleMetadata
relocateDependencies.dependsOn(metadataTask)
afterEvaluate {
// remove dependencies in Maven pom
mavenPublication {
pom.withXml {
val node = this.asNode().getSingleChild("dependencies")
val dependencies = node.childrenNodes()
logger.trace("[Shadow Relocation] deps: $dependencies")
dependencies.forEach { dep ->
val groupId = dep.getSingleChild("groupId").value().toString()
val artifactId = dep.getSingleChild("artifactId").value().toString()
logger.trace("[Shadow Relocation] Checking $groupId:$artifactId")
if (
relocationFilters.any { filter ->
filter.matchesDependency(groupId = groupId, artifactId = artifactId)
}
) {
println("[Shadow Relocation] Filtering out $groupId:$artifactId from pom")
check(node.remove(dep)) { "Failed to remove dependency node" }
}
}
}
}
// remove dependencies in Kotlin module metadata
relocateDependencies.doLast {
// mirai-core-jvm-2.13.0.module
val file = metadataTask.outputFile.asFile.get()
val metadata = Gson().fromJson(
file.readText(),
com.google.gson.JsonElement::class.java
).asJsonObject
val metadataVersion = metadata["formatVersion"]?.asString
check(metadataVersion == "1.1") {
"Unsupported Kotlin metadata version. version=$metadataVersion, file=${file.absolutePath}"
}
for (variant in metadata["variants"]!!.asJsonArray) {
val dependencies = variant.asJsonObject["dependencies"]!!.asJsonArray
dependencies.removeAll { dependency ->
val dep = dependency.asJsonObject
val groupId = dep["group"]!!.asString
val artifactId = dep["module"]!!.asString
relocationFilters.any { filter ->
filter.matchesDependency(
groupId = groupId,
artifactId = artifactId
)
}.also {
println("[Shadow Relocation] Filtering out $groupId:$artifactId from Kotlin module")
}
}
}
file.writeText(GsonBuilder().setPrettyPrinting().create().toJson(metadata))
}
}
}
private fun Project.configureRegularShadowJar(kotlin: KotlinMultiplatformExtension) {
if (project.configurations.findByName("jvmRuntimeClasspath") != null) {
val shadowJvmJar by tasks.creating(ShadowJar::class) sd@{
group = "mirai"
archiveClassifier.set("-all")
val compilations =
kotlin.targets.filter { it.platformType == KotlinPlatformType.jvm }
.map { it.compilations["main"] }
compilations.forEach {
dependsOn(it.compileKotlinTask)
from(it.output)
}
setRelocations()
from(project.configurations.findByName("jvmRuntimeClasspath"))
this.exclude { file ->
file.name.endsWith(".sf", ignoreCase = true)
}
/*
this.manifest {
this.attributes(
"Manifest-Version" to 1,
"Implementation-Vendor" to "Mamoe Technologies",
"Implementation-Title" to this.name.toString(),
"Implementation-Version" to this.version.toString()
)
}*/
}
}
}
data class RelocationFilter(
val groupId: String,
val artifactId: String? = null,
val shadowFilter: String = groupId,
val filesFilter: String = groupId.replace(".", "/")
) {
fun matchesFile(file: File): Boolean {
val path = file.absolutePath.replace("\\", "/")
return filesFilter in path
|| groupId in path
}
fun matchesDependency(groupId: String?, artifactId: String?): Boolean {
if (this.groupId == groupId) return true
if (this.artifactId != null && this.artifactId == artifactId) return true
return false
}
}
val Project.relocationFilters: DomainObjectCollection<RelocationFilter>
get() {
if (project.extra.has("relocationFilters")) {
@Suppress("UNCHECKED_CAST")
return project.extra.get("relocationFilters") as DomainObjectCollection<RelocationFilter>
} else {
val container = project.objects.domainObjectSet(RelocationFilter::class.java)
project.extra.set("relocationFilters", container)
return container
}
}
private const val relocationRootPackage = "net.mamoe.mirai.internal.deps"
private fun ShadowJar.setRelocations() {
project.relocationFilters.forEach { relocation ->
relocate(relocation.shadowFilter, "$relocationRootPackage.${relocation.groupId}")
}
}
fun Project.configureRelocationForCore() {
relocateAllFromGroupId("io.ktor")
}
fun Project.relocateAllFromGroupId(groupId: String) {
relocationFilters.add(RelocationFilter(groupId))
}
// This does not include transitive dependencies
fun Project.relocateExactArtifact(groupId: String, artifactId: String) {
relocationFilters.add(RelocationFilter(groupId, artifactId))
}

View File

@ -13,6 +13,9 @@ import org.gradle.api.attributes.Attribute
import org.gradle.kotlin.dsl.exclude
import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler
// DO NOT CHANGE FILENAME OR RELATIVE PATH TO ROOT PROJECT.
// mirai-deps-test DEPENDS ON THE PATH.
object Versions {
val project = System.getenv("mirai.build.project.version")
?: /*PROJECT_VERSION_START*/"2.13.0"/*PROJECT_VERSION_END*/
@ -22,11 +25,11 @@ object Versions {
val consoleIntellij = "221-$project-162-1" // idea-mirai-kotlin-patch
val consoleTerminal = project
const val kotlinCompiler = "1.7.0-RC"
const val kotlinCompiler = "1.7.0"
const val kotlinStdlib = kotlinCompiler
const val dokka = "1.6.21"
const val kotlinCompilerForIdeaPlugin = "1.7.0-RC"
const val kotlinCompilerForIdeaPlugin = "1.7.0"
const val coroutines = "1.6.2"
const val atomicFU = "0.17.2"
@ -40,6 +43,7 @@ object Versions {
const val blockingBridge = "2.1.0-170.1"
const val dynamicDelegation = "0.3.0-170.1"
const val mavenCentralPublish = "1.0.0-dev-3"
const val androidGradlePlugin = "4.1.1"
const val android = "4.1.1.4"
@ -138,7 +142,9 @@ const val `kotlin-stdlib-jdk8` = "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${Vers
const val `kotlin-reflect` = "org.jetbrains.kotlin:kotlin-reflect:${Versions.kotlinStdlib}"
const val `kotlin-test` = "org.jetbrains.kotlin:kotlin-test:${Versions.kotlinStdlib}"
const val `kotlin-test-junit5` = "org.jetbrains.kotlin:kotlin-test-junit5:${Versions.kotlinStdlib}"
const val `junit-jupiter-api` = "org.junit.jupiter:junit-jupiter-api:${Versions.junit}"
const val `junit-jupiter-params` = "org.junit.jupiter:junit-jupiter-params:${Versions.junit}"
const val `junit-jupiter-engine` = "org.junit.jupiter:junit-jupiter-engine:${Versions.junit}"
//const val `mirai-core-api` = "net.mamoe:mirai-core-api:${Versions.core}"
//const val `mirai-core` = "net.mamoe:mirai-core:${Versions.core}"

View File

@ -1,5 +1,5 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
* Copyright 2019-2022 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,6 +7,8 @@
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
import groovy.util.Node
import groovy.util.NodeList
import java.io.InputStream
import java.io.OutputStream
import java.security.MessageDigest
@ -60,3 +62,14 @@ fun InputStream.md5(): ByteArray {
}
return digest.digest()
}
fun Node.getSingleChild(name: String): Node {
return (this.get(name) as NodeList).single() as Node
}
fun Node.childrenNodes(): List<Node> {
return this.children().filterIsInstance<Node>()
}

View File

@ -46,14 +46,13 @@ dependencies {
implementation(`log4j-core`)
testApi(kotlin("test-junit5"))
testApi("org.junit.jupiter:junit-jupiter-api:${Versions.junit}")
testApi("org.junit.jupiter:junit-jupiter-params:${Versions.junit}")
testApi(`junit-jupiter-api`)
testApi(`junit-jupiter-params`)
"integTestApi"(kotlin("test-junit5"))
"integTestApi"("org.junit.jupiter:junit-jupiter-api:${Versions.junit}")
"integTestApi"("org.junit.jupiter:junit-jupiter-params:${Versions.junit}")
"integTestImplementation"("org.junit.jupiter:junit-jupiter-engine:${Versions.junit}")
// "integTestImplementation"("org.spockframework:spock-core:1.3-groovy-2.5")
"integTestApi"(`junit-jupiter-api`)
"integTestApi"(`junit-jupiter-params`)
"integTestImplementation"(`junit-jupiter-engine`)
"integTestImplementation"(gradleTestKit())
kotlinVersionForIntegrationTest(kotlin("gradle-plugin", "1.5.21"))

View File

@ -1,10 +1,10 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
* Copyright 2019-2022 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.
* 此源代码的使用受 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
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
@file:Suppress("UnusedImport")
@ -27,4 +27,6 @@ dependencies {
if (System.getenv("MIRAI_IS_SNAPSHOTS_PUBLISHING")?.toBoolean() != true) {
configurePublishing("mirai-core-all")
}
}
configureRelocationForCore()

View File

@ -18,6 +18,7 @@ plugins {
id("signing")
id("me.him188.kotlin-jvm-blocking-bridge")
id("me.him188.kotlin-dynamic-delegation")
// id("me.him188.maven-central-publish")
`maven-publish`
}
@ -105,4 +106,13 @@ if (tasks.findByName("androidMainClasses") != null) {
}
configureMppPublishing()
configureBinaryValidators(setOf("jvm", "android").filterTargets())
configureBinaryValidators(setOf("jvm", "android").filterTargets())
configureRelocationForCore()
//mavenCentralPublish {
// artifactId = "mirai-core-api"
// githubProject("mamoe", "mirai")
// developer("Mamoe Technologies", email = "support@mamoe.net", url = "https://github.com/mamoe")
// licenseFromGitHubProject("AGPLv3", "dev")
// publishPlatformArtifactsInRootModule = "jvm"
//}

View File

@ -15,6 +15,7 @@ plugins {
id("kotlinx-atomicfu")
id("me.him188.kotlin-jvm-blocking-bridge")
// id("me.him188.maven-central-publish")
`maven-publish`
}
@ -94,22 +95,13 @@ if (tasks.findByName("androidMainClasses") != null) {
tasks.getByName("androidTest").dependsOn("checkAndroidApiLevel")
}
fun org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler.implementation1(dependencyNotation: String) =
implementation(dependencyNotation) {
exclude("org.jetbrains.kotlin", "kotlin-stdlib")
exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core")
exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core-common")
exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core-jvm")
exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core-metadata")
}
fun org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler.api1(dependencyNotation: String) =
api(dependencyNotation) {
exclude("org.jetbrains.kotlin", "kotlin-stdlib")
exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core")
exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core-common")
exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core-jvm")
exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core-metadata")
}
configureMppPublishing()
configureRelocationForCore()
//mavenCentralPublish {
// artifactId = "mirai-core-utils"
// githubProject("mamoe", "mirai")
// developer("Mamoe Technologies", email = "support@mamoe.net", url = "https://github.com/mamoe")
// licenseFromGitHubProject("AGPLv3", "dev")
// publishPlatformArtifactsInRootModule = "jvm"
//}

View File

@ -19,6 +19,7 @@ plugins {
kotlin("plugin.serialization")
id("me.him188.kotlin-jvm-blocking-bridge")
id("me.him188.kotlin-dynamic-delegation")
// id("me.him188.maven-central-publish")
`maven-publish`
}
@ -202,4 +203,13 @@ if (tasks.findByName("androidMainClasses") != null) {
}
configureMppPublishing()
configureBinaryValidators(setOf("jvm", "android").filterTargets())
configureBinaryValidators(setOf("jvm", "android").filterTargets())
configureRelocationForCore()
//mavenCentralPublish {
// artifactId = "mirai-core"
// githubProject("mamoe", "mirai")
// developer("Mamoe Technologies", email = "support@mamoe.net", url = "https://github.com/mamoe")
// licenseFromGitHubProject("AGPLv3", "dev")
// publishPlatformArtifactsInRootModule = "jvm"
//}

1
mirai-deps-test/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
src/BuildConfig.kt

View File

@ -0,0 +1,3 @@
# native-deps-test
测试 Native

View File

@ -0,0 +1,100 @@
/*
* Copyright 2019-2022 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/dev/LICENSE
*/
@file:Suppress("UnusedImport")
plugins {
kotlin("jvm")
id("java-gradle-plugin")
}
dependencies {
implementation(gradleApi())
implementation(gradleKotlinDsl())
implementation(kotlin("gradle-plugin-api"))
implementation(kotlin("gradle-plugin"))
implementation(kotlin("stdlib"))
api("com.github.jengelman.gradle.plugins:shadow:6.0.0")
api(`jetbrains-annotations`)
testImplementation(kotlin("test-junit5"))
testImplementation(`junit-jupiter-api`)
testImplementation(`junit-jupiter-params`)
testRuntimeOnly(`junit-jupiter-engine`)
}
tasks.getByName("test", Test::class) {
environment("mirai.root.project.dir", rootProject.projectDir.absolutePath)
}
val publishMiraiArtifactsToMavenLocal by tasks.registering {
group = "mirai"
description = "Publish all mirai artifacts to MavenLocal"
val publishTasks = rootProject.allprojects.mapNotNull { proj ->
proj.tasks.findByName("publishToMavenLocal")
}
dependsOn(publishTasks)
doLast {
// delete shadowed Jars, since Kotlin can't compile modules that depend on them.
rootProject.subprojects
.asSequence()
.flatMap { proj -> proj.tasks.filter { task -> task.name.contains("relocate") } }
.flatMap { it.outputs.files }
.filter { it.isFile && it.name.endsWith(".jar") }
.forEach { it.delete() }
}
}
tasks.register("generateBuildConfig") {
group = "mirai"
doLast {
val text = """
package net.mamoe.mirai.deps.test
/**
* This file was generated by Gradle task `generateBuildConfig`.
*/
object BuildConfig {
/**
* Kotlin version used to compile mirai-core
*/
const val kotlinVersion = "${Versions.kotlinCompiler}"
}
""".trimIndent() + "\n"
val file = project.projectDir.resolve("src/BuildConfig.kt")
if (!file.exists() || file.readText() != text) {
file.writeText(text)
}
}
tasks.getByName("assemble").dependsOn(this) // if src is empty, compileKotlin will be skipped.
tasks.getByName("compileKotlin").dependsOn(this)
tasks.getByName("compileTestKotlin").dependsOn(this)
}
tasks.register("publishMiraiLocalArtifacts", Exec::class) {
group = "mirai"
description = "Starts a child process to publish v2.99.0-deps-test artifacts to MavenLocal"
workingDir(rootProject.projectDir)
environment("mirai.build.project.version", "2.99.0-deps-test")
commandLine(
"./gradlew",
publishMiraiArtifactsToMavenLocal.name,
"--no-daemon",
"-Pkotlin.compiler.execution.strategy=in-process"
)
standardOutput = System.out
errorOutput = System.err
}
version = Versions.core

View File

@ -0,0 +1,9 @@
#
# Copyright 2019-2022 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/dev/LICENSE
#

View File

@ -0,0 +1,173 @@
/*
* Copyright 2019-2022 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/dev/LICENSE
*/
package net.mamoe.mirai.deps.test
import org.gradle.api.internal.artifacts.mvnsettings.DefaultMavenFileLocations
import org.gradle.testkit.runner.GradleRunner
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.extension.AfterEachCallback
import org.junit.jupiter.api.extension.RegisterExtension
import org.junit.jupiter.api.io.TempDir
import java.io.File
// Copied from mirai-console-gradle
abstract class AbstractTest {
companion object {
const val miraiLocalVersion = "2.99.0-deps-test" // do Search Everywhere before changing this
const val REASON_LOCAL_ARTIFACT_NOT_AVAILABLE = "local artifacts not available"
private val mavenLocalDir: File by lazy {
org.gradle.api.internal.artifacts.mvnsettings.DefaultLocalMavenRepositoryLocator(
org.gradle.api.internal.artifacts.mvnsettings.DefaultMavenSettingsProvider(DefaultMavenFileLocations())
).localMavenRepository
}
@JvmStatic
fun isMiraiLocalAvailable(): Boolean {
return if (mavenLocalDir.resolve("net/mamoe/mirai-core/$miraiLocalVersion").exists()) {
println(
"""
[mirai-deps-test] Found local artifacts `$miraiLocalVersion`!
Please note that you may need to manually update local artifacts if you have:
- added/removed a dependency for mirai-core series modules
- changed version of any of the dependencies for mirai-core series modules
You can update by running `./gradlew publishMiraiLocalArtifacts`.
""".trimIndent()
)
true
} else {
System.err.println(
"""
[mirai-deps-test] ERROR: Test is not run, because there are no local artifacts available for dependencies testing.
Please build and publish local artifacts with version `$miraiLocalVersion` before running this test(:mirai-deps-test:test).
This could have be automated but it will take a huge amount of time for your routine testing.
You can run this test manually if you have:
- added/removed a dependency for mirai-core series modules
- changed version of any of the dependencies for mirai-core series modules
Note that you can ignore this test if you did not change project (dependency) structure.
And you don't need to worry if you does not run this test this test is always executed on the CI when you make a PR.
You can run `./gradlew publishMiraiLocalArtifacts` to publish local artifacts.
Then you can run this test again. (By your original way or ./gradlew :mirai-deps-test:test)
""".trimIndent()
)
false
}
}
}
@JvmField
@TempDir
var tempDirField: File? = null
val tempDir: File get() = tempDirField!!
val kotlinVersion = BuildConfig.kotlinVersion
lateinit var mainSrcDir: File
lateinit var commonMainSrcDir: File
lateinit var nativeMainSrcDir: File
lateinit var testDir: File
lateinit var buildFile: File
lateinit var settingsFile: File
lateinit var propertiesFile: File
@OptIn(ExperimentalStdlibApi::class)
fun runGradle(vararg arguments: String) {
System.gc()
GradleRunner.create()
.withProjectDir(tempDir)
.withPluginClasspath()
.withGradleVersion("7.2")
.forwardOutput()
.withEnvironment(System.getenv())
.withArguments(buildList {
addAll(arguments)
add("-Pkotlin.compiler.execution.strategy=in-process")
add("-Dorg.gradle.jvmargs=-Xmx512m -Dfile.encoding=UTF-8")
add("--stacktrace")
})
.build()
}
@BeforeEach
fun setup() {
println("Temp path is " + tempDir.absolutePath)
settingsFile = File(tempDir, "settings.gradle")
settingsFile.delete()
settingsFile.writeText(
"""
pluginManagement {
repositories {
gradlePluginPortal()
mavenCentral()
mavenLocal()
}
}
"""
)
File(tempDir, "gradle.properties").apply {
delete()
writeText(
"""
org.gradle.daemon=false
org.gradle.jvmargs=-Xmx4096m -Dfile.encoding=UTF-8
""".trimIndent()
)
}
mainSrcDir = tempDir.resolve("src/main/kotlin").apply { mkdirs() }
commonMainSrcDir = tempDir.resolve("src/commonMain/kotlin").apply { mkdirs() }
nativeMainSrcDir = tempDir.resolve("src/nativeMain/kotlin").apply { mkdirs() }
testDir = tempDir.resolve("src/test/kotlin").apply { mkdirs() }
buildFile = tempDir.resolve("build.gradle.kts")
buildFile.writeText(
"""
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("jvm") version "1.7.0"
}
group = "org.example"
version = "1.0-SNAPSHOT"
repositories {
mavenCentral()
mavenLocal()
}
dependencies {
testImplementation(kotlin("test"))
}
tasks.test {
useJUnitPlatform()
}
tasks.withType<KotlinCompile> {
kotlinOptions.jvmTarget = "1.8"
}
""".trimIndent() + "\n\n"
)
}
@JvmField
@RegisterExtension
internal val after: AfterEachCallback = AfterEachCallback { context ->
if (context.executionException.isPresent) {
val inst = context.requiredTestInstance as AbstractTest
println("====================== build.gradle ===========================")
println(inst.tempDir.resolve("build.gradle").readText())
println("==================== settings.gradle ==========================")
println(inst.tempDir.resolve("settings.gradle").readText())
}
}
}

View File

@ -0,0 +1,167 @@
/*
* Copyright 2019-2022 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/dev/LICENSE
*/
package net.mamoe.mirai.deps.test
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.condition.EnabledIf
class CoreDependencyResolutionTest : AbstractTest() {
@Test
@EnabledIf("isMiraiLocalAvailable", disabledReason = REASON_LOCAL_ARTIFACT_NOT_AVAILABLE)
fun `test resolve JVM root from Kotlin JVM`() {
mainSrcDir.resolve("main.kt").writeText(
"""
package test
fun main () {
println(net.mamoe.mirai.BotFactory)
}
""".trimIndent()
)
buildFile.writeText(
"""
plugins {
id("org.jetbrains.kotlin.jvm") version "$kotlinVersion"
}
repositories {
mavenCentral()
mavenLocal()
}
dependencies {
implementation("net.mamoe:mirai-core:$miraiLocalVersion")
}
""".trimIndent()
)
runGradle("build")
}
@Test
@EnabledIf("isMiraiLocalAvailable", disabledReason = REASON_LOCAL_ARTIFACT_NOT_AVAILABLE)
fun `test resolve JVM from Kotlin JVM`() {
mainSrcDir.resolve("main.kt").writeText(
"""
package test
fun main () {
println(net.mamoe.mirai.BotFactory)
}
""".trimIndent()
)
buildFile.writeText(
"""
plugins {
id("org.jetbrains.kotlin.jvm") version "$kotlinVersion"
}
repositories {
mavenCentral()
mavenLocal()
}
dependencies {
implementation("net.mamoe:mirai-core-jvm:$miraiLocalVersion")
}
""".trimIndent()
)
runGradle("build")
}
@Test
@EnabledIf("isMiraiLocalAvailable", disabledReason = REASON_LOCAL_ARTIFACT_NOT_AVAILABLE)
fun `test resolve JVM and Native from common`() {
commonMainSrcDir.resolve("main.kt").writeText(
"""
package test
fun main () {
println(net.mamoe.mirai.BotFactory)
}
""".trimIndent()
)
buildFile.writeText(
"""
|import org.apache.tools.ant.taskdefs.condition.Os
|import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
|plugins {
| id("org.jetbrains.kotlin.multiplatform") version "$kotlinVersion"
|}
|repositories {
| mavenCentral()
| mavenLocal()
|}
|kotlin {
| targets {
| jvm()
| val nativeMainSets = mutableListOf<KotlinSourceSet>()
| val nativeTestSets = mutableListOf<KotlinSourceSet>()
| when {
| Os.isFamily(Os.FAMILY_MAC) -> if (Os.isArch("aarch64")) macosArm64("native") else macosX64("native")
| Os.isFamily(Os.FAMILY_WINDOWS) -> mingwX64("native")
| else -> linuxX64("native")
| }
| }
| sourceSets {
| val commonMain by getting {
| dependencies {
| api("net.mamoe:mirai-core:$miraiLocalVersion")
| }
| }
| }
|}
""".trimMargin()
)
runGradle("build")
}
@Test
@EnabledIf("isMiraiLocalAvailable", disabledReason = REASON_LOCAL_ARTIFACT_NOT_AVAILABLE)
fun `test resolve Native from common`() {
nativeMainSrcDir.resolve("main.kt").writeText(
"""
package test
fun main () {
println(net.mamoe.mirai.BotFactory)
}
""".trimIndent()
)
buildFile.writeText(
"""
|import org.apache.tools.ant.taskdefs.condition.Os
|import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
|plugins {
| id("org.jetbrains.kotlin.multiplatform") version "$kotlinVersion"
|}
|repositories {
| mavenCentral()
| mavenLocal()
|}
|kotlin {
| targets {
| jvm()
| val nativeMainSets = mutableListOf<KotlinSourceSet>()
| val nativeTestSets = mutableListOf<KotlinSourceSet>()
| when {
| Os.isFamily(Os.FAMILY_MAC) -> if (Os.isArch("aarch64")) macosArm64("native") else macosX64("native")
| Os.isFamily(Os.FAMILY_WINDOWS) -> mingwX64("native")
| else -> linuxX64("native")
| }
| }
| sourceSets {
| val nativeMain by getting {
| dependencies {
| api("net.mamoe:mirai-core:$miraiLocalVersion")
| }
| }
| }
|}
""".trimMargin()
)
runGradle("build")
}
}

View File

@ -0,0 +1,48 @@
/*
* Copyright 2019-2022 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/dev/LICENSE
*/
package net.mamoe.mirai.deps.test
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.condition.EnabledIf
class CoreShadowRelocationTest : AbstractTest() {
@Test
@EnabledIf("isMiraiLocalAvailable", disabledReason = REASON_LOCAL_ARTIFACT_NOT_AVAILABLE)
fun `test OkHttp filtered out`() {
testDir.resolve("test.kt").writeText(
"""
package test
import org.junit.jupiter.api.*
class MyTest {
@Test
fun `test base dependency`() {
assertThrows<ClassNotFoundException> {
Class.forName("io.ktor.client.engine.okhttp.OkHttp")
}
}
@Test
fun `test transitive dependency`() {
assertThrows<ClassNotFoundException> {
Class.forName("okhttp3.OkHttpClient")
}
}
}
""".trimIndent()
)
buildFile.appendText(
"""
dependencies {
implementation("net.mamoe:mirai-core:$miraiLocalVersion")
}
""".trimIndent()
)
runGradle("check")
}
}

View File

@ -0,0 +1,10 @@
/*
* Copyright 2019-2022 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/dev/LICENSE
*/
package net.mamoe.mirai.deps.test

View File

@ -1,15 +1,15 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
* Copyright 2019-2022 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.
* 此源代码的使用受 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
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
pluginManagement {
repositories {
if (System.getProperty("use.maven.local") == "true") {
if (System.getProperty("use.maven.local") == "true") { // you can enable by adding `systemProp.use.maven.local=true` in 'gradle.properties'.
mavenLocal()
}
gradlePluginPortal()
@ -18,24 +18,31 @@ pluginManagement {
}
}
val allProjects = mutableListOf<ProjectDescriptor>()
rootProject.name = "mirai"
/**
* Projects included so far
*/
val allProjects = mutableListOf<ProjectDescriptor>()
fun includeProject(projectPath: String, dir: String? = null) {
include(projectPath)
if (dir != null) project(projectPath).projectDir = file(dir)
allProjects.add(project(projectPath))
}
fun includeConsoleProject(projectPath: String, dir: String? = null) =
includeProject(projectPath, "mirai-console/$dir")
includeProject(":mirai-core-utils")
includeProject(":mirai-core-api")
includeProject(":mirai-core")
includeProject(":mirai-core-all")
includeProject(":mirai-bom")
includeProject(":mirai-dokka")
//includeProject(":binary-compatibility-validator")
//includeProject(":binary-compatibility-validator-android", "binary-compatibility-validator/android")
includeProject(":mirai-deps-test")
includeProject(":mirai-logging-log4j2", "logging/mirai-logging-log4j2")
includeProject(":mirai-logging-slf4j", "logging/mirai-logging-slf4j")
@ -43,55 +50,50 @@ includeProject(":mirai-logging-slf4j-simple", "logging/mirai-logging-slf4j-simpl
includeProject(":mirai-logging-slf4j-logback", "logging/mirai-logging-slf4j-logback")
val disableOldFrontEnds = true
fun includeConsoleProject(projectPath: String, dir: String? = null) =
includeProject(projectPath, "mirai-console/$dir")
includeConsoleProject(":mirai-console-compiler-annotations", "tools/compiler-annotations")
includeConsoleProject(":mirai-console", "backend/mirai-console")
includeConsoleProject(":mirai-console.codegen", "backend/codegen")
includeConsoleProject(":mirai-console-terminal", "frontend/mirai-console-terminal")
// region mirai-console.integration-test
includeConsoleProject(":mirai-console.integration-test", "backend/integration-test")
val consoleIntegrationTestSubPluginBuildGradleKtsTemplate by lazy {
rootProject.projectDir
.resolve("mirai-console/backend/integration-test/testers")
.resolve("tester.template.gradle.kts")
.readText()
}
@Suppress("SimpleRedundantLet")
fun includeConsoleITPlugin(prefix: String, path: File) {
path.resolve("build.gradle.kts").takeIf { !it.isFile }?.let { initScript ->
initScript.writeText(consoleIntegrationTestSubPluginBuildGradleKtsTemplate)
}
val projectPath = "$prefix${path.name}"
include(projectPath)
project(projectPath).projectDir = path
path.listFiles()?.asSequence().orEmpty()
.filter { it.isDirectory }
.filter { it.resolve(".nested-module.txt").exists() }
.forEach { includeConsoleITPlugin("${projectPath}:", it) }
}
rootProject.projectDir
.resolve("mirai-console/backend/integration-test/testers")
.listFiles()?.asSequence().orEmpty()
.filter { it.isDirectory }
.forEach { includeConsoleITPlugin(":mirai-console.integration-test:", it) }
// endregion
includeConsoleIntegrationTestProjects()
includeConsoleProject(":mirai-console-compiler-common", "tools/compiler-common")
includeConsoleProject(":mirai-console-intellij", "tools/intellij-plugin")
includeConsoleProject(":mirai-console-gradle", "tools/gradle-plugin")
@Suppress("ConstantConditionIf")
if (!disableOldFrontEnds) {
includeConsoleProject(":mirai-console-terminal", "frontend/mirai-console-terminal")
//includeConsoleFrontendGraphical()
includeProject(":ci-release-helper")
includeBinaryCompatibilityValidatorProjects()
/**
* Configures a project `:validator:path-to-project:target-name` for binary compatibility validation.
*
* To enable validation for a project,
* create a subdirectory with name of the target under "compatibility-validation",
* then sync **twice**. See `:mirai-core-api` for an example.
*
* **Note**: This function depends on [allProjects], and should be used at the end.
*/
fun includeBinaryCompatibilityValidatorProjects() {
val result = mutableListOf<ProjectDescriptor>()
for (project in allProjects) {
val validationDir = project.projectDir.resolve("compatibility-validation")
if (!validationDir.exists()) continue
validationDir.listFiles().orEmpty<File>().forEach { dir ->
if (dir.resolve("build.gradle.kts").isFile) {
val path = ":validator" + project.path + ":${dir.name}"
include(path)
project(path).projectDir = dir
// project(path).name = "${project.name}-validator-${dir.name}"
result.add(project(path))
}
}
}
}
fun includeConsoleLegacyFrontendProjects() {
println("JDK version: ${JavaVersion.current()}")
if (JavaVersion.current() >= JavaVersion.VERSION_1_9) {
@ -101,20 +103,34 @@ if (!disableOldFrontEnds) {
}
}
includeProject(":ci-release-helper")
fun includeConsoleIntegrationTestProjects() {
includeConsoleProject(":mirai-console.integration-test", "backend/integration-test")
val result = mutableListOf<ProjectDescriptor>()
for (project in allProjects) {
val validationDir = project.projectDir.resolve("compatibility-validation")
if (!validationDir.exists()) continue
validationDir.listFiles().orEmpty<File>().forEach { dir ->
if (dir.resolve("build.gradle.kts").isFile) {
val path = ":validator" + project.path + ":${dir.name}"
include(path)
project(path).projectDir = dir
// project(path).name = "${project.name}-validator-${dir.name}"
result.add(project(path))
}
val consoleIntegrationTestSubPluginBuildGradleKtsTemplate by lazy {
rootProject.projectDir
.resolve("mirai-console/backend/integration-test/testers")
.resolve("tester.template.gradle.kts")
.readText()
}
}
@Suppress("SimpleRedundantLet")
fun includeConsoleITPlugin(prefix: String, path: File) {
path.resolve("build.gradle.kts").takeIf { !it.isFile }?.let { initScript ->
initScript.writeText(consoleIntegrationTestSubPluginBuildGradleKtsTemplate)
}
val projectPath = "$prefix${path.name}"
include(projectPath)
project(projectPath).projectDir = path
path.listFiles()?.asSequence().orEmpty()
.filter { it.isDirectory }
.filter { it.resolve(".nested-module.txt").exists() }
.forEach { includeConsoleITPlugin("${projectPath}:", it) }
}
rootProject.projectDir
.resolve("mirai-console/backend/integration-test/testers")
.listFiles()?.asSequence().orEmpty()
.filter { it.isDirectory }
.forEach { includeConsoleITPlugin(":mirai-console.integration-test:", it) }
}