mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-27 17:00:14 +08:00
Configure shadow relocation and add checks for multiplatform publishing
This commit is contained in:
parent
dc747ea438
commit
fd67ba9204
11
.github/workflows/build.yml
vendored
11
.github/workflows/build.yml
vendored
@ -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 }}
|
||||
|
6
.github/workflows/snapshots.yml
vendored
6
.github/workflows/snapshots.yml
vendored
@ -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
|
||||
|
@ -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()
|
||||
)
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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")
|
||||
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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 }
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
276
buildSrc/src/main/kotlin/Shadow.kt
Normal file
276
buildSrc/src/main/kotlin/Shadow.kt
Normal 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))
|
||||
}
|
@ -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}"
|
||||
|
@ -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>()
|
||||
}
|
@ -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"))
|
||||
|
@ -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()
|
@ -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"
|
||||
//}
|
@ -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"
|
||||
//}
|
@ -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
1
mirai-deps-test/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
src/BuildConfig.kt
|
3
mirai-deps-test/README.md
Normal file
3
mirai-deps-test/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
# native-deps-test
|
||||
|
||||
测试 Native
|
100
mirai-deps-test/build.gradle.kts
Normal file
100
mirai-deps-test/build.gradle.kts
Normal 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
|
9
mirai-deps-test/gradle.properties
Normal file
9
mirai-deps-test/gradle.properties
Normal 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
|
||||
#
|
||||
|
173
mirai-deps-test/test/AbstractTest.kt
Normal file
173
mirai-deps-test/test/AbstractTest.kt
Normal 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())
|
||||
}
|
||||
}
|
||||
}
|
167
mirai-deps-test/test/CoreDependencyResolutionTest.kt
Normal file
167
mirai-deps-test/test/CoreDependencyResolutionTest.kt
Normal 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")
|
||||
}
|
||||
}
|
48
mirai-deps-test/test/CoreShadowRelocationTest.kt
Normal file
48
mirai-deps-test/test/CoreShadowRelocationTest.kt
Normal 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")
|
||||
}
|
||||
}
|
10
mirai-deps-test/test/package.kt
Normal file
10
mirai-deps-test/test/package.kt
Normal 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
|
@ -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) }
|
||||
}
|
Loading…
Reference in New Issue
Block a user