Generalize binary validator

This commit is contained in:
Him188 2021-12-27 17:15:56 +00:00
parent 3844630550
commit 3d864362aa
14 changed files with 144 additions and 99 deletions

View File

@ -1,3 +0,0 @@
binary-compability-validator
使用 [Kotlin/binary-compatibility-validator](https://github.com/Kotlin/binary-compatibility-validator),用于验证二进制兼容性。

View File

@ -1,28 +0,0 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
@file:Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")
plugins {
kotlin("jvm")
kotlin("plugin.serialization")
id("kotlinx-atomicfu")
id("me.him188.kotlin-jvm-blocking-bridge")
}
description = "Mirai API binary compatibility validator"
tasks.withType(kotlinx.validation.KotlinApiBuildTask::class) {
inputClassesDirs =
files(inputClassesDirs.files, project(":mirai-core-api").buildDir.resolve("classes/kotlin/android/main"))
}
// tasks["apiDump"].dependsOn(project(":mirai-core-api").tasks["build"])
// this dependency is set in mirai-core-api since binary validator is configured before mirai-core-api

View File

@ -1,28 +0,0 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
@file:Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")
plugins {
kotlin("jvm")
kotlin("plugin.serialization")
id("kotlinx-atomicfu")
id("me.him188.kotlin-jvm-blocking-bridge")
}
description = "Mirai API binary compatibility validator"
tasks.withType(kotlinx.validation.KotlinApiBuildTask::class) {
inputClassesDirs =
files(inputClassesDirs.files, project(":mirai-core-api").buildDir.resolve("classes/kotlin/jvm/main"))
}
// tasks["apiDump"].dependsOn(project(":mirai-core-api").tasks["build"])
// this dependency is set in mirai-core-api since binary validator is configured before mirai-core-api

View File

@ -10,10 +10,10 @@
@file:Suppress("UnstableApiUsage", "UNUSED_VARIABLE", "NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
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 {
@ -30,7 +30,6 @@ buildscript {
dependencies {
classpath("com.android.tools.build:gradle:${Versions.androidGradlePlugin}")
classpath("org.jetbrains.kotlinx:atomicfu-gradle-plugin:${Versions.atomicFU}")
classpath("org.jetbrains.kotlinx:binary-compatibility-validator:${Versions.binaryValidator}")
classpath("org.jetbrains.dokka:dokka-base:${Versions.dokka}")
}
}
@ -44,27 +43,6 @@ plugins {
id("com.gradle.plugin-publish") version "0.12.0" apply false
}
// https://github.com/kotlin/binary-compatibility-validator
apply(plugin = "binary-compatibility-validator")
configure<kotlinx.validation.ApiValidationExtension> {
allprojects.forEach { subproject ->
ignoredProjects.add(subproject.name)
}
ignoredProjects.remove("binary-compatibility-validator")
ignoredProjects.remove("binary-compatibility-validator-android")
// Enable validator for module `binary-compatibility-validator` and `-android` only.
ignoredPackages.add("net.mamoe.mirai.internal")
ignoredPackages.add("net.mamoe.mirai.console.internal")
nonPublicMarkers.add("net.mamoe.mirai.utils.MiraiInternalApi")
nonPublicMarkers.add("net.mamoe.mirai.utils.MiraiInternalFile")
nonPublicMarkers.add("net.mamoe.mirai.console.utils.ConsoleInternalApi")
nonPublicMarkers.add("net.mamoe.mirai.console.utils.ConsoleExperimentalApi")
nonPublicMarkers.add("net.mamoe.mirai.utils.MiraiExperimentalApi")
}
GpgSigner.setup(project)
analyzes.CompiledCodeVerify.run { registerAllVerifyTasks() }

View File

@ -0,0 +1,78 @@
import org.gradle.api.Project
import org.gradle.configurationcache.extensions.useToRun
import org.gradle.kotlin.dsl.get
import java.io.File
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
object BinaryCompatibilityConfigurator {
fun Project.configureBinaryValidators(vararg targetNames: String) {
targetNames.forEach { configureBinaryValidator(it) }
}
fun Project.configureBinaryValidator(targetName: String?) {
val validationDir = projectDir.resolve("compatibility-validation")
val dir = validationDir.resolve(targetName ?: "jvm")
dir.mkdirs()
createValidator(this, dir, targetName)
val apiDumpAll = tasks.maybeCreate("apiDumpAll").apply {
group = "mirai"
}
val apiCheckAll = tasks.maybeCreate("apiCheckAll").apply {
group = "mirai"
}
project.afterEvaluate {
val validatorProject = findProject(project.path + ":validator-${dir.name}")
validatorProject
?.getTasksByName("apiDump", false)
?.let { apiDumpAll.dependsOn(it) }
validatorProject
?.getTasksByName("apiCheck", false)
?.let { apiCheckAll.dependsOn(it) }
}
}
/**
* @param targetName `null` for JVM projects.
*/
fun createValidator(project: Project, dir: File, targetName: String?) {
dir.resolve("build.gradle.kts").writeText(
applyTemplate(
project.path,
if (targetName == null) "classes/kotlin/main" else "classes/kotlin/$targetName/main"
)
)
dir.resolve(".gitignore").writeText(
this::class.java.classLoader
.getResourceAsStream("binary-compatibility-validator-ignore.txt")!!.readBytes().decodeToString()
)
project.afterEvaluate {
findProject(project.path + ":validator-${dir.name}")
?.afterEvaluate {
tasks["apiBuild"].dependsOn(project.tasks["build"])
}
}
}
fun applyTemplate(projectPath: String, buildDir: String): String {
return this::class.java.classLoader
.getResourceAsStream("binary-compatibility-validator-build.txt")!!
.useToRun { readBytes() }
.decodeToString()
.replace("$\$PROJECT_PATH$$", projectPath)
.replace("$\$BUILD_DIR$$", buildDir)
.replace("$\$PLUGIN_VERSION$$", Versions.binaryValidator)
}
}

View File

@ -0,0 +1,30 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
plugins {
kotlin("jvm")
id("org.jetbrains.kotlinx.binary-compatibility-validator") version "$$PLUGIN_VERSION$$"
}
description = "Binary compatibility validator for project $$PROJECT_PATH$$"
tasks.withType(kotlinx.validation.KotlinApiBuildTask::class) {
inputClassesDirs =
files(inputClassesDirs.files, project("$$PROJECT_PATH$$").buildDir.resolve("$$BUILD_DIR$$"))
}
apiValidation {
ignoredPackages.add("net.mamoe.mirai.internal")
ignoredPackages.add("net.mamoe.mirai.console.internal")
nonPublicMarkers.add("net.mamoe.mirai.utils.MiraiInternalApi")
nonPublicMarkers.add("net.mamoe.mirai.utils.MiraiInternalFile")
nonPublicMarkers.add("net.mamoe.mirai.console.utils.ConsoleInternalApi")
nonPublicMarkers.add("net.mamoe.mirai.console.utils.ConsoleExperimentalApi")
nonPublicMarkers.add("net.mamoe.mirai.utils.MiraiExperimentalApi")
}

View File

@ -0,0 +1,2 @@
build.gradle.kts
.gitignore

View File

@ -8,6 +8,7 @@
*/
@file:Suppress("UNUSED_VARIABLE")
import BinaryCompatibilityConfigurator.configureBinaryValidators
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
plugins {
@ -107,8 +108,4 @@ if (isAndroidSDKAvailable) {
}
configureMppPublishing()
afterEvaluate {
project(":binary-compatibility-validator").tasks["apiBuild"].dependsOn(project(":mirai-core-api").tasks["build"])
project(":binary-compatibility-validator-android").tasks["apiBuild"].dependsOn(project(":mirai-core-api").tasks["build"])
}
configureBinaryValidators("jvm", "android")

View File

@ -9,6 +9,7 @@
@file:Suppress("UNUSED_VARIABLE")
import BinaryCompatibilityConfigurator.configureBinaryValidators
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
plugins {
@ -122,3 +123,4 @@ if (isAndroidSDKAvailable) {
}
configureMppPublishing()
configureBinaryValidators("jvm", "android")

View File

@ -18,23 +18,24 @@ pluginManagement {
}
}
val allProjects = mutableListOf<ProjectDescriptor>()
rootProject.name = "mirai"
fun includeProject(projectPath: String, dir: String? = null) {
include(projectPath)
if (dir != null) project(projectPath).projectDir = file(dir)
allProjects.add(project(projectPath))
}
include(":mirai-core-utils")
include(":mirai-core-api")
include(":mirai-core")
include(":mirai-core-all")
include(":mirai-bom")
include(":mirai-dokka")
includeProject(":mirai-core-utils")
includeProject(":mirai-core-api")
includeProject(":mirai-core")
includeProject(":mirai-core-all")
includeProject(":mirai-bom")
includeProject(":mirai-dokka")
include(":binary-compatibility-validator")
include(":binary-compatibility-validator-android")
project(":binary-compatibility-validator-android").projectDir = file("binary-compatibility-validator/android")
//includeProject(":binary-compatibility-validator")
//includeProject(":binary-compatibility-validator-android", "binary-compatibility-validator/android")
includeProject(":mirai-logging-log4j2", "logging/mirai-logging-log4j2")
includeProject(":mirai-logging-slf4j", "logging/mirai-logging-slf4j")
@ -96,4 +97,20 @@ if (!disableOldFrontEnds) {
}
}
include(":ci-release-helper")
includeProject(":ci-release-helper")
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 = project.path + ":validator-${dir.name}"
include(path)
project(path).projectDir = dir
// project(path).name = "${project.name}-validator-${dir.name}"
result.add(project(path))
}
}
}