Explorar el Código

Add GeneratePluginDescriptionTask

Him188 hace 5 años
padre
commit
0fb07a9f79

+ 1 - 0
tools/gradle-plugin/build.gradle.kts

@@ -22,6 +22,7 @@ plugins {
 }
 
 dependencies {
+    implementation(project(":mirai-console-compiler-annotations"))
     compileOnly(gradleApi())
     compileOnly(gradleKotlinDsl())
     compileOnly(kotlin("gradle-plugin-api").toString()) {

+ 98 - 0
tools/gradle-plugin/src/GeneratePluginDescriptionTask.kt

@@ -0,0 +1,98 @@
+/*
+ * 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("MemberVisibilityCanBePrivate", "unused")
+
+package net.mamoe.mirai.console.gradle
+
+import net.mamoe.mirai.console.compiler.common.CheckerConstants
+import org.gradle.api.Action
+import org.gradle.api.DefaultTask
+import org.gradle.api.Project
+import org.gradle.api.tasks.CacheableTask
+import org.gradle.api.tasks.Input
+import org.gradle.api.tasks.OutputFile
+import org.gradle.api.tasks.TaskAction
+import org.gradle.kotlin.dsl.get
+import java.io.File
+
+public class PluginDescription(
+    project: Project
+) {
+    public var id: String? = null
+    public var name: String? = project.displayName
+    public var info: String? = project.runHierarchically { description }
+    public var author: String? = null
+    public var version: String? = project.version.toString()
+    public var dependencies: MutableList<String> = mutableListOf()
+
+    public fun addDependency(pluginId: String, version: String) {
+        dependencies.add("$pluginId:$version")
+    }
+}
+
+/**
+ * Generates `JvmPluginDescription` YAML file, e.g. `plugin.yml`.
+ */
+@CacheableTask
+public class GeneratePluginDescriptionTask : DefaultTask() {
+
+    @Input
+    public val pluginDescription: PluginDescription = PluginDescription(project)
+
+    @Input
+    public var filename: String = "plugin.yml"
+
+    public fun pluginDescription(
+        action: Action<PluginDescription>
+    ) {
+        return action.execute(pluginDescription)
+    }
+
+    @OutputFile
+    public fun getOutputFile(): File {
+        val resources = project.sourceSets["main"].resources.sourceDirectories
+        if (resources.isEmpty) {
+            error("Source set 'main' does not have directory 'resources'.")
+        }
+        return resources.files.first().resolve(filename)
+    }
+
+    @TaskAction
+    public fun generateFile() {
+        val text = generateFileContent()
+        getOutputFile().writeText(text)
+    }
+
+    private fun generateFileContent(): String = buildString {
+        pluginDescription.run {
+            val pluginId = id
+            require(pluginId?.matches(CheckerConstants.PLUGIN_ID_REGEX) == true) { "Invalid pluginId: '$pluginId'" }
+            val pluginName = name
+            require(pluginName == null || CheckerConstants.PLUGIN_FORBIDDEN_NAMES.none { it == pluginName }) { "Invalid pluginName: '$pluginName'" }
+
+            appendLine("id: $pluginId")
+            pluginName?.let { appendLine("name: $it") }
+            version?.let { appendLine("version: $it") }
+            author?.let { appendLine("author: $it") }
+            info?.let { appendLine("info: $it") }
+
+            val dependencies = dependencies
+            if (dependencies.isNotEmpty()) {
+                appendLine("dependencies: ")
+                for (dependency in dependencies) {
+                    appendLine("  - '$dependency'")
+                }
+            }
+        }
+    }
+}
+
+private fun StringBuilder.appendLine(text: String = ""): StringBuilder = append(text).append("\n")

+ 32 - 4
tools/gradle-plugin/src/MiraiConsoleExtension.kt

@@ -1,10 +1,10 @@
 /*
- * Copyright 2019-2020 Mamoe Technologies and contributors.
+ * Copyright 2019-2021 Mamoe Technologies and contributors.
  *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 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/master/LICENSE
  */
 
 @file:Suppress("unused", "MemberVisibilityCanBePrivate")
@@ -14,6 +14,7 @@ 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.Action
 import org.gradle.api.JavaVersion
 import org.gradle.api.XmlProvider
 import org.gradle.api.plugins.PluginContainer
@@ -28,6 +29,29 @@ import org.gradle.api.publish.maven.MavenPublication
  */
 // must be open
 public open class MiraiConsoleExtension {
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Plugin Description generation
+    ///////////////////////////////////////////////////////////////////////////
+
+    internal val pluginDescriptionActions = mutableListOf<Action<GeneratePluginDescriptionTask>>()
+
+    /**
+     * 配置自动生成 `JvmPluginDescription` 的 "plugin.yml".
+     *
+     * 本函数被调用后就会在之后配置项目时创建相关 task, 通常的 task 名称为 "". "src/main/resources"
+     */
+    public fun pluginDescription(
+        action: Action<GeneratePluginDescriptionTask>
+    ) {
+        pluginDescriptionActions.add(action)
+    }
+
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Dependency configuration
+    ///////////////////////////////////////////////////////////////////////////
+
     /**
      * 为 `true` 时不自动添加 mirai-core-api 的依赖
      *
@@ -125,6 +149,10 @@ public open class MiraiConsoleExtension {
         excludedDependencies.add(ExcludedDependency(group, name))
     }
 
+    ///////////////////////////////////////////////////////////////////////////
+    // Publishing to JCenter
+    ///////////////////////////////////////////////////////////////////////////
+
     /**
      * Bintray 插件成品 JAR 发布 配置.
      *

+ 22 - 4
tools/gradle-plugin/src/MiraiConsoleGradlePlugin.kt

@@ -1,10 +1,10 @@
 /*
- * Copyright 2019-2020 Mamoe Technologies and contributors.
+ * Copyright 2019-2021 Mamoe Technologies and contributors.
  *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 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/master/LICENSE
  */
 
 @file:JvmMultifileClass
@@ -140,6 +140,23 @@ public class MiraiConsoleGradlePlugin : Plugin<Project> {
         }
     }
 
+    private fun Project.configureGeneratePluginDescriptionTasks() {
+        fun registerTask(target: KotlinTarget, isSingleTarget: Boolean) {
+            tasks.create("generatePluginDescription".wrapNameWithPlatform(target, isSingleTarget), GeneratePluginDescriptionTask::class.java).apply shadow@{
+                group = "mirai"
+                for (action in miraiExtension.pluginDescriptionActions) {
+                    action.execute(this)
+                }
+            }
+        }
+
+        val targets = kotlinTargets
+        val isSingleTarget = targets.size == 1
+        targets.forEach { target ->
+            registerTask(target, isSingleTarget)
+        }
+    }
+
     override fun apply(target: Project): Unit = with(target) {
         extensions.create("mirai", MiraiConsoleExtension::class.java)
 
@@ -154,6 +171,7 @@ public class MiraiConsoleGradlePlugin : Plugin<Project> {
             configureCompileTarget()
             kotlinTargets.forEach { configureTarget(it) }
             registerBuildPluginTasks()
+            configureGeneratePluginDescriptionTasks()
             configurePublishing()
         }
     }

+ 20 - 0
tools/gradle-plugin/src/utils.kt

@@ -0,0 +1,20 @@
+/*
+ * 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
+ */
+
+
+package net.mamoe.mirai.console.gradle
+
+import org.gradle.api.Project
+
+internal fun <R : Any> Project.runHierarchically(action: Project.() -> R?): R? {
+    for (project in allprojects) {
+        project.run(action)?.let { return it }
+    }
+    return null
+}