mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-25 15:40:28 +08:00
Plugin publishing via gradle plugin
This commit is contained in:
parent
08c61dee0e
commit
9a2ea32e93
18
tools/gradle-plugin/src/BuildMiraiPluginTask.kt
Normal file
18
tools/gradle-plugin/src/BuildMiraiPluginTask.kt
Normal file
@ -0,0 +1,18 @@
|
||||
package net.mamoe.mirai.console.gradle
|
||||
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
import org.gradle.api.tasks.CacheableTask
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
|
||||
import java.io.File
|
||||
|
||||
@CacheableTask
|
||||
public open class BuildMiraiPluginTask : ShadowJar() {
|
||||
internal var targetField: KotlinTarget? = null
|
||||
|
||||
public val target: KotlinTarget get() = targetField!!
|
||||
|
||||
/**
|
||||
* ShadowJar 打包结果
|
||||
*/
|
||||
public val output: File get() = outputs.files.singleFile
|
||||
}
|
@ -13,8 +13,10 @@ package net.mamoe.mirai.console.gradle
|
||||
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
import com.jfrog.bintray.gradle.BintrayExtension
|
||||
import com.jfrog.bintray.gradle.BintrayPlugin
|
||||
import org.gradle.api.JavaVersion
|
||||
import org.gradle.api.XmlProvider
|
||||
import org.gradle.api.plugins.PluginContainer
|
||||
import org.gradle.api.publish.maven.MavenPublication
|
||||
|
||||
/**
|
||||
@ -126,31 +128,44 @@ public open class MiraiConsoleExtension {
|
||||
/**
|
||||
* Bintray 插件成品 JAR 发布 配置.
|
||||
*
|
||||
* @see Publishing
|
||||
* @see PluginPublishing
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public val publishing: Publishing = Publishing()
|
||||
public val publishing: PluginPublishing = PluginPublishing()
|
||||
|
||||
/**
|
||||
* 控制自动配置 Bintray 发布
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public var publishingEnabled: Boolean = true
|
||||
|
||||
/**
|
||||
* Bintray 插件成品 JAR 发布 配置.
|
||||
* 控制自动配置 Bintray 发布. 默认为 `false`, 表示不自动配置发布.
|
||||
*
|
||||
* 开启后将会:
|
||||
* - 创建名为 "mavenJava" 的 [MavenPublication]
|
||||
* - [应用][PluginContainer.apply] [BintrayPlugin], 配置 Bintray 相关参数
|
||||
* - 创建 task "publishPlugin"
|
||||
*
|
||||
* @see [Publishing]
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public inline fun publishing(block: Publishing.() -> Unit): Unit = publishing.run(block)
|
||||
public var publishingEnabled: Boolean = false
|
||||
|
||||
/**
|
||||
* 开启自动配置 Bintray 插件成品 JAR 发布, 并以 [configure] 配置 [PluginPublishing].
|
||||
*
|
||||
* @see [PluginPublishing]
|
||||
* @see publishingEnabled
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public fun disablePublishing() {
|
||||
publishingEnabled = false
|
||||
public inline fun publishing(crossinline configure: PluginPublishing.() -> Unit) {
|
||||
publishingEnabled = true
|
||||
publishing.run(configure)
|
||||
}
|
||||
|
||||
/**
|
||||
* 开启自动配置 Bintray 插件成品 JAR 发布.
|
||||
*
|
||||
* @see [PluginPublishing]
|
||||
* @see publishingEnabled
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public fun publishing() {
|
||||
publishingEnabled = true
|
||||
}
|
||||
|
||||
/**
|
||||
@ -166,36 +181,37 @@ public open class MiraiConsoleExtension {
|
||||
* 4. [System.getenv] "PROP"
|
||||
*
|
||||
* @see publishing
|
||||
* @see publishingEnabled
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public class Publishing internal constructor() {
|
||||
public class PluginPublishing internal constructor() {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Required arguments
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Bintray 账户名. 必须.
|
||||
* 若为 `null`, 将会以 [Publishing] 中描述的步骤获取 "bintray.user"
|
||||
* 若为 `null`, 将会以 [PluginPublishing] 中描述的步骤获取 "bintray.user"
|
||||
*
|
||||
* @see [Publishing]
|
||||
* @see [PluginPublishing]
|
||||
*/
|
||||
public var user: String? = null
|
||||
|
||||
/**
|
||||
* Bintray 账户 key. 必须.
|
||||
* 若为 `null`, 将会以 [Publishing] 中描述的步骤获取 "bintray.key"
|
||||
* 若为 `null`, 将会以 [PluginPublishing] 中描述的步骤获取 "bintray.key"
|
||||
*/
|
||||
public var key: String? = null
|
||||
|
||||
/**
|
||||
* 目标仓库名称. 必须.
|
||||
* 若为 `null`, 将会以 [Publishing] 中描述的步骤获取 "bintray.repo"
|
||||
* 若为 `null`, 将会以 [PluginPublishing] 中描述的步骤获取 "bintray.repo"
|
||||
*/
|
||||
public var repo: String? = null
|
||||
|
||||
/**
|
||||
* 目标仓库名称. 必须.
|
||||
* 若为 `null`, 将会以 [Publishing] 中描述的步骤获取 "bintray.package"
|
||||
* 若为 `null`, 将会以 [PluginPublishing] 中描述的步骤获取 "bintray.package"
|
||||
*/
|
||||
public var packageName: String? = null
|
||||
|
||||
@ -227,11 +243,16 @@ public open class MiraiConsoleExtension {
|
||||
*/
|
||||
public var version: String? = null
|
||||
|
||||
/**
|
||||
* 发布的描述, 默认为 `project.description`
|
||||
*/
|
||||
public var description: String? = null
|
||||
|
||||
// Bintray
|
||||
|
||||
/**
|
||||
* Bintray organization 名. 可选.
|
||||
* 若为 `null`, 将会以 [Publishing] 中描述的步骤获取 "bintray.org".
|
||||
* 若为 `null`, 将会以 [PluginPublishing] 中描述的步骤获取 "bintray.org".
|
||||
* 仍然无法获取时发布到 [user] 账号下的仓库 [repo], 否则发布到指定 [org] 下的仓库 [repo].
|
||||
*/
|
||||
public var org: String? = null
|
||||
@ -256,29 +277,29 @@ public open class MiraiConsoleExtension {
|
||||
/**
|
||||
* 自定义配置 [BintrayExtension],覆盖
|
||||
*/
|
||||
public fun bintray(config: BintrayExtension.() -> Unit) {
|
||||
bintrayConfigs.add(config)
|
||||
public fun bintray(configure: BintrayExtension.() -> Unit) {
|
||||
bintrayConfigs.add(configure)
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义配置 [BintrayExtension.PackageConfig]
|
||||
*/
|
||||
public fun packageConfig(config: BintrayExtension.PackageConfig.() -> Unit) {
|
||||
bintrayPackageConfigConfigs.add(config)
|
||||
public fun packageConfig(configure: BintrayExtension.PackageConfig.() -> Unit) {
|
||||
bintrayPackageConfigConfigs.add(configure)
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义配置 maven pom.xml [XmlProvider]
|
||||
*/
|
||||
public fun mavenPom(config: XmlProvider.() -> Unit) {
|
||||
mavenPomConfigs.add(config)
|
||||
public fun mavenPom(configure: XmlProvider.() -> Unit) {
|
||||
mavenPomConfigs.add(configure)
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义配置 [MavenPublication]
|
||||
*/
|
||||
public fun mavenPublication(config: MavenPublication.() -> Unit) {
|
||||
mavenPublicationConfigs.add(config)
|
||||
public fun mavenPublication(configure: MavenPublication.() -> Unit) {
|
||||
mavenPublicationConfigs.add(configure)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@
|
||||
package net.mamoe.mirai.console.gradle
|
||||
|
||||
import com.github.jengelman.gradle.plugins.shadow.ShadowPlugin
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
import com.jfrog.bintray.gradle.BintrayPlugin
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.plugins.JavaPlugin
|
||||
@ -101,18 +101,18 @@ public class MiraiConsoleGradlePlugin : Plugin<Project> {
|
||||
|
||||
tasks.findByName("shadowJar")?.enabled = false
|
||||
|
||||
fun registerBuildPluginTask(target: KotlinTarget, isSinglePlatform: Boolean) {
|
||||
tasks.create(if (isSinglePlatform) "buildPlugin" else "buildPlugin${target.name.capitalize()}", ShadowJar::class.java).apply shadow@{
|
||||
fun registerBuildPluginTask(target: KotlinTarget, isSingleTarget: Boolean) {
|
||||
tasks.create("buildPlugin".wrapNameWithPlatform(target, isSingleTarget), BuildMiraiPluginTask::class.java).apply shadow@{
|
||||
group = "mirai"
|
||||
targetField = target
|
||||
|
||||
archiveExtension.set("mirai.jar")
|
||||
|
||||
val compilations = target.compilations.filter { it.name == MAIN_COMPILATION_NAME }
|
||||
|
||||
compilations.forEach {
|
||||
dependsOn(it.compileKotlinTask)
|
||||
from(it.output)
|
||||
for (allKotlinSourceSet in it.allKotlinSourceSets) {
|
||||
from(allKotlinSourceSet.resources)
|
||||
}
|
||||
from(it.output.allOutputs)
|
||||
}
|
||||
|
||||
from(project.configurations.getByName("runtimeClasspath").copyRecursive { dependency ->
|
||||
@ -142,18 +142,20 @@ public class MiraiConsoleGradlePlugin : Plugin<Project> {
|
||||
}
|
||||
|
||||
override fun apply(target: Project): Unit = with(target) {
|
||||
target.extensions.create("mirai", MiraiConsoleExtension::class.java)
|
||||
extensions.create("mirai", MiraiConsoleExtension::class.java)
|
||||
|
||||
target.plugins.apply(JavaPlugin::class.java)
|
||||
target.plugins.apply(ShadowPlugin::class.java)
|
||||
|
||||
target.repositories.maven { it.setUrl(BINTRAY_REPOSITORY_URL) }
|
||||
plugins.apply(JavaPlugin::class.java)
|
||||
plugins.apply("org.gradle.maven-publish")
|
||||
plugins.apply("org.gradle.maven")
|
||||
plugins.apply(ShadowPlugin::class.java)
|
||||
plugins.apply(BintrayPlugin::class.java)
|
||||
repositories.maven { it.setUrl(BINTRAY_REPOSITORY_URL) }
|
||||
|
||||
afterEvaluate {
|
||||
configureCompileTarget()
|
||||
kotlinTargets.forEach { configureTarget(it) }
|
||||
registerBuildPluginTasks()
|
||||
registerPublishPluginTask()
|
||||
configurePublishing()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -171,4 +173,7 @@ internal val Project.kotlinTargets: Collection<KotlinTarget>
|
||||
is KotlinSingleTargetExtension -> listOf(kotlinExtension.target)
|
||||
else -> error("[MiraiConsole] Internal error: kotlinExtension is neither KotlinMultiplatformExtension nor KotlinSingleTargetExtension")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal val Project.kotlinJvmOrAndroidTargets: Collection<KotlinTarget>
|
||||
get() = kotlinTargets.filter { it.platformType == KotlinPlatformType.jvm || it.platformType == KotlinPlatformType.androidJvm }
|
||||
|
@ -9,13 +9,19 @@
|
||||
|
||||
package net.mamoe.mirai.console.gradle
|
||||
|
||||
import com.google.gson.Gson
|
||||
import com.jfrog.bintray.gradle.tasks.BintrayUploadTask
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.publish.maven.MavenPublication
|
||||
import org.gradle.api.tasks.TaskContainer
|
||||
import org.gradle.api.tasks.bundling.Jar
|
||||
import org.gradle.kotlin.dsl.get
|
||||
import org.gradle.kotlin.dsl.getValue
|
||||
import org.gradle.kotlin.dsl.provideDelegate
|
||||
import org.gradle.kotlin.dsl.registering
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
|
||||
import java.io.File
|
||||
|
||||
|
||||
private val Project.selfAndParentProjects: Sequence<Project>
|
||||
@ -29,17 +35,105 @@ private fun Project.findPropertySmart(propName: String): String? {
|
||||
}
|
||||
|
||||
private fun Project.findPropertySmartOrFail(propName: String): String {
|
||||
return findPropertySmart(propName) ?: error("[Mirai Console] Cannot find property for publication: $propName. Please check your 'mirai' configuration.")
|
||||
return findPropertySmart(propName)
|
||||
?: error("[Mirai Console] Cannot find property for publication: '$propName'. Please check your 'mirai' configuration.")
|
||||
}
|
||||
|
||||
internal fun Project.registerPublishPluginTask() {
|
||||
internal fun Project.configurePublishing() {
|
||||
if (!miraiExtension.publishingEnabled) return
|
||||
val isSingleTarget = kotlinJvmOrAndroidTargets.size == 1
|
||||
|
||||
kotlinJvmOrAndroidTargets.forEach {
|
||||
registerPublishPluginTasks(it, isSingleTarget)
|
||||
registerMavenPublications(it, isSingleTarget)
|
||||
}
|
||||
|
||||
registerBintrayPublish()
|
||||
}
|
||||
|
||||
private inline fun <reified T : Task> TaskContainer.getSingleTask(): T = filterIsInstance<T>().single()
|
||||
|
||||
private fun Project.registerPublishPluginTasks() {
|
||||
val isSingleTarget = kotlinJvmOrAndroidTargets.size == 1
|
||||
kotlinJvmOrAndroidTargets.forEach { registerPublishPluginTasks(it, isSingleTarget) }
|
||||
}
|
||||
|
||||
// effectively public
|
||||
internal data class PluginMetadata(
|
||||
val groupId: String,
|
||||
val artifactId: String,
|
||||
val version: String,
|
||||
val description: String?,
|
||||
val dependencies: List<String>
|
||||
)
|
||||
|
||||
internal fun String.wrapNameWithPlatform(target: KotlinTarget, isSingleTarget: Boolean): String {
|
||||
return if (isSingleTarget) this else "$this${target.name.capitalize()}"
|
||||
}
|
||||
|
||||
private fun Project.registerPublishPluginTasks(target: KotlinTarget, isSingleTarget: Boolean) {
|
||||
val generateMetadataTask =
|
||||
tasks.register("generatePluginMetadata".wrapNameWithPlatform(target, isSingleTarget)).get().apply {
|
||||
group = "mirai"
|
||||
|
||||
val metadataFile =
|
||||
project.buildDir.resolve("mirai").resolve(if (isSingleTarget) "mirai-plugin.metadata" else "mirai-plugin-${target.name}.metadata")
|
||||
outputs.file(metadataFile)
|
||||
|
||||
|
||||
|
||||
doLast {
|
||||
val mirai = miraiExtension
|
||||
|
||||
val output = outputs.files.singleFile
|
||||
output.parentFile.mkdir()
|
||||
|
||||
val dependencies = configurations[target.compilations["main"].apiConfigurationName].allDependencies.map {
|
||||
"${it.group}:${it.name}:${it.version}"
|
||||
}
|
||||
|
||||
val json = Gson().toJson(PluginMetadata(
|
||||
groupId = mirai.publishing.groupId ?: project.group.toString(),
|
||||
artifactId = mirai.publishing.artifactId ?: project.name,
|
||||
version = mirai.publishing.version ?: project.version.toString(),
|
||||
description = mirai.publishing.description ?: project.description,
|
||||
dependencies = dependencies
|
||||
))
|
||||
|
||||
logger.info("Generated mirai plugin metadata json: $json")
|
||||
|
||||
output.writeText(json)
|
||||
}
|
||||
}
|
||||
|
||||
val bintrayUpload = tasks.getByName(BintrayUploadTask.getTASK_NAME()).dependsOn(
|
||||
"buildPlugin".wrapNameWithPlatform(target, isSingleTarget),
|
||||
generateMetadataTask,
|
||||
// "shadowJar",
|
||||
tasks.filterIsInstance<BuildMiraiPluginTask>().single { it.target == target }
|
||||
)
|
||||
tasks.register("publishPlugin".wrapNameWithPlatform(target, isSingleTarget)).get().apply {
|
||||
group = "mirai"
|
||||
dependsOn(bintrayUpload)
|
||||
}
|
||||
}
|
||||
|
||||
internal inline fun File.renamed(block: File.(nameWithoutExtension: String) -> String): File = this.resolveSibling(block(this, nameWithoutExtension))
|
||||
|
||||
private fun Project.registerBintrayPublish() {
|
||||
val mirai = miraiExtension
|
||||
|
||||
bintray {
|
||||
user = mirai.publishing.user ?: findPropertySmartOrFail("bintray.user")
|
||||
key = mirai.publishing.key ?: findPropertySmartOrFail("bintray.key")
|
||||
|
||||
setPublications("mavenJava")
|
||||
val targets = kotlinJvmOrAndroidTargets
|
||||
if (targets.size == 1) {
|
||||
setPublications("mavenJava")
|
||||
} else {
|
||||
setPublications(*targets.map { "mavenJava".wrapNameWithPlatform(it, false) }.toTypedArray())
|
||||
}
|
||||
|
||||
setConfigurations("archives")
|
||||
|
||||
publish = mirai.publishing.publish
|
||||
@ -49,12 +143,17 @@ internal fun Project.registerPublishPluginTask() {
|
||||
repo = mirai.publishing.repo ?: findPropertySmartOrFail("bintray.repo")
|
||||
name = mirai.publishing.packageName ?: findPropertySmartOrFail("bintray.package")
|
||||
userOrg = mirai.publishing.org ?: findPropertySmart("bintray.org")
|
||||
desc = mirai.publishing.description ?: project.description
|
||||
|
||||
mirai.publishing.bintrayPackageConfigConfigs.forEach { it.invoke(this) }
|
||||
}
|
||||
|
||||
mirai.publishing.bintrayConfigs.forEach { it.invoke(this) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun Project.registerMavenPublications(target: KotlinTarget, isSingleTarget: Boolean) {
|
||||
val mirai = miraiExtension
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
val sourcesJar by tasks.registering(Jar::class) {
|
||||
@ -70,7 +169,7 @@ internal fun Project.registerPublishPluginTask() {
|
||||
url = uri("$buildDir/repo")
|
||||
}
|
||||
}*/
|
||||
publications.register("mavenJava", MavenPublication::class.java) { publication ->
|
||||
publications.register("mavenJava".wrapNameWithPlatform(target, isSingleTarget), MavenPublication::class.java) { publication ->
|
||||
with(publication) {
|
||||
from(components["java"])
|
||||
|
||||
@ -89,9 +188,11 @@ internal fun Project.registerPublishPluginTask() {
|
||||
}
|
||||
|
||||
artifact(sourcesJar.get())
|
||||
|
||||
// TODO: 2020/11/28 -miraip metadata artifact
|
||||
// TODO: 2020/11/28 -all shadowed artifact
|
||||
artifact(tasks.filterIsInstance<BuildMiraiPluginTask>().single { it.target == target })
|
||||
artifact(mapOf(
|
||||
"source" to tasks.getByName("generatePluginMetadata".wrapNameWithPlatform(target, isSingleTarget)).outputs.files.singleFile,
|
||||
"extension" to "metadata"
|
||||
))
|
||||
|
||||
mirai.publishing.mavenPublicationConfigs.forEach { it.invoke(this) }
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user