Plugin publishing fundamentals, #227

This commit is contained in:
Him188 2020-11-28 13:53:53 +08:00
parent b201583136
commit fab3727b44
4 changed files with 285 additions and 1 deletions

View File

@ -15,6 +15,7 @@ plugins {
dependencies {
compileOnly(gradleApi())
compileOnly(gradleKotlinDsl())
compileOnly(kotlin("gradle-plugin-api").toString()) {
exclude("org.jetbrains.kotlin", "kotlin-stdlib")
}
@ -26,6 +27,7 @@ dependencies {
api("com.github.jengelman.gradle.plugins:shadow:6.0.0")
api(`jetbrains-annotations`)
api("com.jfrog.bintray.gradle:gradle-bintray-plugin:${Versions.bintray}")
}
version = Versions.console

View File

@ -12,7 +12,10 @@
package net.mamoe.mirai.console.gradle
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import com.jfrog.bintray.gradle.BintrayExtension
import org.gradle.api.JavaVersion
import org.gradle.api.XmlProvider
import org.gradle.api.publish.maven.MavenPublication
/**
* ```
@ -119,6 +122,165 @@ open class MiraiConsoleExtension {
fun excludeDependency(group: String, name: String) {
excludedDependencies.add(ExcludedDependency(group, name))
}
/**
* Bintray 插件成品 JAR 发布 配置.
*
* @see Publishing
* @since 1.1.0
*/
val publishing: Publishing = Publishing()
/**
* 控制自动配置 Bintray 发布
* @since 1.1.0
*/
var publishingEnabled = true
/**
* Bintray 插件成品 JAR 发布 配置.
*
* @see [Publishing]
* @since 1.1.0
*/
inline fun publishing(block: Publishing.() -> Unit) = publishing.run(block)
/**
* @see publishingEnabled
* @since 1.1.0
*/
fun disablePublishing() {
publishingEnabled = false
}
/**
* Bintray 插件成品 JAR 发布 配置.
*
* 对于一个属性 PROP, 会按以下顺序依次尝试读取:
* 1. Gradle 参数
* - "gradle.properties"
* - ext
* - Gradle -P 启动参数
* 2. [System.getProperty] "PROP"
* 3. 当前和所有父 project 根目录下 "PROP" 文件的内容
* 4. [System.getenv] "PROP"
*
* @see publishing
* @since 1.1.0
*/
class Publishing internal constructor() {
///////////////////////////////////////////////////////////////////////////
// Required arguments
///////////////////////////////////////////////////////////////////////////
/**
* Bintray 账户名. 必须.
* 若为 `null`, 将会以 [Publishing] 中描述的步骤获取 "bintray.user"
*
* @see [Publishing]
*/
var user: String? = null
/**
* Bintray 账户 key. 必须.
* 若为 `null`, 将会以 [Publishing] 中描述的步骤获取 "bintray.key"
*/
var key: String? = null
/**
* 目标仓库名称. 必须.
* 若为 `null`, 将会以 [Publishing] 中描述的步骤获取 "bintray.repo"
*/
var repo: String? = null
/**
* 目标仓库名称. 必须.
* 若为 `null`, 将会以 [Publishing] 中描述的步骤获取 "bintray.package"
*/
var packageName: String? = null
///////////////////////////////////////////////////////////////////////////
// Optional arguments
///////////////////////////////////////////////////////////////////////////
// Artifact
/**
* 发布的 artifact id. 默认为 `project.name`.
*
* artifact id 是类似于 "net.mamoe:mirai-console:1.1.0" 中的 "mirai-console"
*/
var artifactId: String? = null
/**
* 发布的 group id. 默认为 `project.group`.
*
* group id 是类似于 "net.mamoe:mirai-console:1.1.0" 中的 "net.mamoe"
*/
var groupId: String? = null
/**
* 发布的版本号, 默认为 `project.version`
*
* 版本号是类似于 "net.mamoe:mirai-console:1.1.0" 中的 "1.1.0"
*/
var version: String? = null
// Bintray
/**
* Bintray organization . 可选.
* 若为 `null`, 将会以 [Publishing] 中描述的步骤获取 "bintray.org".
* 仍然无法获取时发布到 [user] 账号下的仓库 [repo], 否则发布到指定 [org] 下的仓库 [repo].
*/
var org: String? = null
/**
* 上传后自动发布. 默认 `true`.
*/
var publish: Boolean = true
/**
* 当文件冲突时覆盖. 默认 `false`.
*/
var override: Boolean = false
// Custom configurations
internal val bintrayConfigs = mutableListOf<BintrayExtension.() -> Unit>()
internal val bintrayPackageConfigConfigs = mutableListOf<BintrayExtension.PackageConfig.() -> Unit>()
internal val mavenPomConfigs = mutableListOf<XmlProvider.() -> Unit>()
internal val mavenPublicationConfigs = mutableListOf<MavenPublication.() -> Unit>()
/**
* 自定义配置 [BintrayExtension]覆盖
*/
fun bintray(config: BintrayExtension.() -> Unit) {
bintrayConfigs.add(config)
}
/**
* 自定义配置 [BintrayExtension.PackageConfig]
*/
fun packageConfig(config: BintrayExtension.PackageConfig.() -> Unit) {
bintrayPackageConfigConfigs.add(config)
}
/**
* 自定义配置 maven pom.xml [XmlProvider]
*/
fun mavenPom(config: XmlProvider.() -> Unit) {
mavenPomConfigs.add(config)
}
/**
* 自定义配置 [MavenPublication]
*/
fun mavenPublication(config: MavenPublication.() -> Unit) {
mavenPublicationConfigs.add(config)
}
}
}
enum class MiraiConsoleFrontEndKind {

View File

@ -151,8 +151,9 @@ class MiraiConsoleGradlePlugin : Plugin<Project> {
afterEvaluate {
configureCompileTarget()
registerBuildPluginTasks()
kotlinTargets.forEach { configureTarget(it) }
registerBuildPluginTasks()
registerPublishPluginTask()
}
}
}

View File

@ -0,0 +1,119 @@
/*
* 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
*/
package net.mamoe.mirai.console.gradle
import org.gradle.api.Project
import org.gradle.api.publish.maven.MavenPublication
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
private val Project.selfAndParentProjects: Sequence<Project>
get() = generateSequence(this) { it.parent }
private fun Project.findPropertySmart(propName: String): String? {
return findProperty(propName)?.toString()
?: System.getProperty(propName)
?: selfAndParentProjects.map { it.projectDir.resolve(propName) }.find { it.exists() }?.readText()
?: System.getenv(propName)
}
private fun Project.findPropertySmartOrFail(propName: String): String {
return findPropertySmart(propName) ?: error("[Mirai Console] Cannot find property for publication: $propName. Please check your 'mirai' configuration.")
}
internal fun Project.registerPublishPluginTask() {
val mirai = miraiExtension
bintray {
user = mirai.publishing.user ?: findPropertySmartOrFail("bintray.user")
key = mirai.publishing.key ?: findPropertySmartOrFail("bintray.key")
setPublications("mavenJava")
setConfigurations("archives")
publish = mirai.publishing.publish
override = mirai.publishing.override
pkg.apply {
repo = mirai.publishing.repo ?: findPropertySmartOrFail("bintray.repo")
name = mirai.publishing.packageName ?: findPropertySmartOrFail("bintray.package")
userOrg = mirai.publishing.org ?: findPropertySmart("bintray.org")
mirai.publishing.bintrayPackageConfigConfigs.forEach { it.invoke(this) }
}
mirai.publishing.bintrayConfigs.forEach { it.invoke(this) }
}
@Suppress("DEPRECATION")
val sourcesJar by tasks.registering(Jar::class) {
classifier = "sources"
from(sourceSets["main"].allSource)
}
publishing {
/*
repositories {
maven {
// change to point to your repo, e.g. http://my.org/repo
url = uri("$buildDir/repo")
}
}*/
publications.register("mavenJava", MavenPublication::class.java) { publication ->
with(publication) {
from(components["java"])
this.groupId = mirai.publishing.groupId ?: project.group.toString()
this.artifactId = mirai.publishing.artifactId ?: project.name
this.version = mirai.publishing.version ?: project.version.toString()
pom.withXml { xml ->
val root = xml.asNode()
root.appendNode("description", project.description)
root.appendNode("name", project.name)
// root.appendNode("url", vcs)
root.children().last()
mirai.publishing.mavenPomConfigs.forEach { it.invoke(xml) }
}
artifact(sourcesJar.get())
// TODO: 2020/11/28 -miraip metadata artifact
// TODO: 2020/11/28 -all shadowed artifact
mirai.publishing.mavenPublicationConfigs.forEach { it.invoke(this) }
}
}
}
}
/**
* Configures the [bintray][com.jfrog.bintray.gradle.BintrayExtension] extension.
*/
@PublishedApi
internal fun Project.bintray(configure: com.jfrog.bintray.gradle.BintrayExtension.() -> Unit): Unit =
(this as org.gradle.api.plugins.ExtensionAware).extensions.configure("bintray", configure)
@PublishedApi
internal val Project.sourceSets: org.gradle.api.tasks.SourceSetContainer
get() = (this as org.gradle.api.plugins.ExtensionAware).extensions.getByName("sourceSets") as org.gradle.api.tasks.SourceSetContainer
/**
* Configures the [publishing][org.gradle.api.publish.PublishingExtension] extension.
*/
@PublishedApi
internal fun Project.publishing(configure: org.gradle.api.publish.PublishingExtension.() -> Unit): Unit =
(this as org.gradle.api.plugins.ExtensionAware).extensions.configure("publishing", configure)