From e2050cdb9aa34fe7bc3052b49f48cb5c9a921100 Mon Sep 17 00:00:00 2001 From: Michael Rittmeister Date: Tue, 12 Nov 2024 17:35:03 +0100 Subject: [PATCH] Update to new plugin system --- example/build.gradle.kts | 1 + src/main/kotlin/LavalinkExtension.kt | 21 ++++ src/main/kotlin/LavalinkGradlePlugin.kt | 112 ++++++++++-------- .../tasks/GeneratePluginPropertiesTask.kt | 20 +++- src/main/kotlin/tasks/RunLavalinkTask.kt | 9 +- 5 files changed, 105 insertions(+), 58 deletions(-) diff --git a/example/build.gradle.kts b/example/build.gradle.kts index 1abc74a..bd349c7 100644 --- a/example/build.gradle.kts +++ b/example/build.gradle.kts @@ -11,6 +11,7 @@ dependencies { // And Kotlin is best dependency <3 implementation(kotlin("stdlib", "2.0.21")) implementation("org.jetbrains.kotlinx", "kotlinx-serialization-json", "1.7.3") + implementation("org.jetbrains.kotlinx", "kotlinx-coroutines-core", "1.9.0") } java { diff --git a/src/main/kotlin/LavalinkExtension.kt b/src/main/kotlin/LavalinkExtension.kt index 26ee7c2..d666ad8 100644 --- a/src/main/kotlin/LavalinkExtension.kt +++ b/src/main/kotlin/LavalinkExtension.kt @@ -40,8 +40,29 @@ interface LavalinkExtension { /** * The plugins root package (if different to [Project.getGroup]). */ + @Deprecated("This property is no longer required") val path: Property + /** + * The version of Lavalink this plugin requires (if different to [apiVersion]). + */ + val requires: Property + + /** + * An optional description of the plugin. + */ + val description: Property + + /** + * An optional mention of the plugin's author. + */ + val provider: Property + + /** + * An optional license of the plugin. + */ + val license: Property + /** * Whether to configure publishing automatically or nor. */ diff --git a/src/main/kotlin/LavalinkGradlePlugin.kt b/src/main/kotlin/LavalinkGradlePlugin.kt index 2729d2e..2e9aabe 100644 --- a/src/main/kotlin/LavalinkGradlePlugin.kt +++ b/src/main/kotlin/LavalinkGradlePlugin.kt @@ -4,14 +4,17 @@ import dev.arbjerg.lavalink.gradle.tasks.* import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.artifacts.Dependency +import org.gradle.api.artifacts.ModuleVersionIdentifier import org.gradle.api.provider.Provider import org.gradle.api.publish.PublishingExtension import org.gradle.api.publish.maven.MavenPublication import org.gradle.api.publish.maven.plugins.MavenPublishPlugin import org.gradle.api.tasks.Copy import org.gradle.api.tasks.SourceSetContainer -import org.gradle.jvm.tasks.Jar +import org.gradle.api.tasks.bundling.Jar +import org.gradle.api.tasks.bundling.Zip import org.gradle.kotlin.dsl.* +import org.gradle.language.base.plugins.LifecycleBasePlugin private const val lavalinkExtensionName = "lavalinkPlugin" @@ -22,10 +25,10 @@ class LavalinkGradlePlugin : Plugin { override fun apply(target: Project) { with(target) { check(plugins.hasPlugin("org.gradle.java")) { "Please apply the Java/Kotlin plugin before Lavalink" } - configureExtension() + val extension = configureExtension() configurePublishing() val serverDependency = configureDependencies() - configureTasks(serverDependency) + configureTasks(extension, serverDependency) configureSourceSets() } } @@ -36,12 +39,14 @@ class LavalinkGradlePlugin : Plugin { } private fun Project.configureExtension(): LavalinkExtension { + @Suppress("DEPRECATION") return extensions.create(lavalinkExtensionName).apply { version.convention(provider { project.version.toString() }) name.convention(project.name) path.convention(provider { project.group.toString() }) serverVersion.convention(apiVersion) configurePublishing.convention(true) + requires.convention(serverVersion) } } @@ -75,6 +80,7 @@ private fun Project.configurePublishing() { publications { create("maven") { from(components["java"]) + artifact(tasks.named("assemblePlugin")) } } } @@ -92,67 +98,79 @@ private fun Project.configureSourceSets() { } } -private fun Project.configureTasks(serverDependency: Provider) { +private fun Project.configureTasks(extension: LavalinkExtension, serverDependency: Provider) { tasks { val generatePluginProperties by registering(GeneratePluginPropertiesTask::class) named("processResources") { dependsOn(generatePluginProperties) } - val jar by named("jar") { - configurations.getByName("runtimeClasspath") - .incoming - .artifactView { -// componentFilter { it !is ProjectComponentIdentifier } - }.artifacts - .forEach { - from(zipTree(it.file)) { - exclude("META-INF/**") + val jar by getting(Jar::class) + val collectPluginDependencies by registering(Copy::class) { + val destinationDirectory = layout.buildDirectory.dir("dependencies") + delete(destinationDirectory) // Delete old data + + from({ + val dependency = + dependencies.create("dev.arbjerg.lavalink:Lavalink-Server:${extension.serverVersion.get()}") { + // Old sedmelluq artifacts are still referenced at some places + // but do not resolve anymore since jcenter is dead + exclude(group = "com.sedmelluq") } - } -// configurations.getByName("runtimeClasspath") -// .allDependencies -// .filterIsInstance() -// .forEach { dependency -> -// val project = dependency.dependencyProject -// if (project.plugins.hasPlugin("org.jetbrains.kotlin.multiplatform")) { -// val compilationName = provider { -// project.extensions.getByType() -// .targets -// .first { it is KotlinJvmTarget } -// .name -// } -// dependsOn(compilationName.flatMap { project.tasks.named("${it}MainClasses") }) -// from(compilationName.flatMap { targetName -> project.layout.buildDirectory.file("classes/kotlin/$targetName/main") }) { -// include("**/*.class") -// } -// } else { -// dependsOn(project.tasks.named("classes")) -// from(project.layout.buildDirectory.dir("classes")) { -// include("**/main/**/*.class") -// eachFile { -// path = path.substringAfter("main/") -// } -// } -// } -// } + // Collect all dependencies lavalink depends on + val serverDependencies = configurations + .detachedConfiguration(dependency) + .resolvedConfiguration + .resolvedArtifacts + .map { it.moduleVersion.id.dependencyNotation } + + // Remove them from the jar, to avoid conflicts + configurations.getByName("runtimeClasspath") + .resolvedConfiguration + .resolvedArtifacts + .asSequence() + .filter { it.moduleVersion.id.dependencyNotation !in serverDependencies } + .mapNotNull { it.file } + .toList() + + }) + into(destinationDirectory) } - val installPlugin by registering(Copy::class) { - from(jar) - into(project.testServerFolder) - // This always deletes old versions of the plugin in the test server - // So we don't install the same plugin twice - rename { "plugin.jar" } + register("assemblePlugin") { + group = LifecycleBasePlugin.BUILD_GROUP + destinationDirectory = layout.buildDirectory.dir("distributions") + archiveBaseName = extension.name.map { "plugin-$it" } + + dependsOn(jar) + + into("classes") { + with(jar) + exclude("plugin.properties") + // Do not include legacy manifest + exclude("lavalink-plugins/**") + } + + into("lib") { + from(collectPluginDependencies) + } + + from(generatePluginProperties) } val downloadLavalink by registering(DownloadLavalinkTask::class) { dependencyProvider = serverDependency } + val classes by existing + val processResources by existing + register("runLavaLink") { - dependsOn(installPlugin, downloadLavalink) + dependsOn(downloadLavalink, classes, processResources) } } } + +val ModuleVersionIdentifier.dependencyNotation: String + get() = "$group:$name" diff --git a/src/main/kotlin/tasks/GeneratePluginPropertiesTask.kt b/src/main/kotlin/tasks/GeneratePluginPropertiesTask.kt index f0f9273..619f135 100644 --- a/src/main/kotlin/tasks/GeneratePluginPropertiesTask.kt +++ b/src/main/kotlin/tasks/GeneratePluginPropertiesTask.kt @@ -22,10 +22,14 @@ abstract class GeneratePluginPropertiesTask : DefaultTask() { init { group = LifecycleBasePlugin.BUILD_GROUP val extension = project.extension + @Suppress("DEPRECATION") inputs.properties( "version" to extension.version, "name" to extension.name, "path" to extension.path, + "requires" to extension.requires, + "provider" to extension.provider.orElse(""), + "license" to extension.license.orElse(""), ) outputs.dir(project.generatedPluginManifest) @@ -37,15 +41,23 @@ abstract class GeneratePluginPropertiesTask : DefaultTask() { @TaskAction fun generateTask() { val properties = Properties().apply { - set("version", extension.version.get()) - set("name", extension.name.get()) - set("path", extension.path.get()) + set("plugin.id", extension.name.get()) + set("plugin.version", extension.version.get()) + set("plugin.requires", extension.requires.get()) + setIfPresent("plugin.provider", extension.provider) + setIfPresent("plugin.license", extension.license) } - val file = generatedPluginManifest.get().asFile.toPath() / "lavalink-plugins" / "${extension.name.get()}.properties" + val file = generatedPluginManifest.get().asFile.toPath() / "plugin.properties" file.parent.createDirectories() file.bufferedWriter(options = arrayOf(StandardOpenOption.CREATE)).use { writer -> properties.store(writer, null) } } } + +private fun Properties.setIfPresent(name: String, value: Provider) { + if (value.isPresent) { + setProperty(name, value.get()) + } +} diff --git a/src/main/kotlin/tasks/RunLavalinkTask.kt b/src/main/kotlin/tasks/RunLavalinkTask.kt index e485cbd..c7310ff 100644 --- a/src/main/kotlin/tasks/RunLavalinkTask.kt +++ b/src/main/kotlin/tasks/RunLavalinkTask.kt @@ -3,14 +3,10 @@ package dev.arbjerg.lavalink.gradle.tasks import dev.arbjerg.lavalink.gradle.LavalinkGradlePlugin import org.gradle.api.Project import org.gradle.api.tasks.JavaExec -import org.gradle.api.tasks.OutputDirectory import org.gradle.api.tasks.TaskAction import org.gradle.kotlin.dsl.assign import org.gradle.kotlin.dsl.environment -internal val Project.testServerFolder - get() = project.layout.buildDirectory.dir("lavalink-test-server-plugins") - abstract class RunLavalinkTask : JavaExec() { init { mainClass = "org.springframework.boot.loader.JarLauncher" @@ -18,15 +14,14 @@ abstract class RunLavalinkTask : JavaExec() { outputs.upToDateWhen { false } } - private val workingDir = project.rootDir - private val testServerFolder = project.testServerFolder + private val workingDir = project.layout.projectDirectory private val lavalinkJar = project.lavalinkJar.map { project.files(it) } @TaskAction override fun exec() { workingDir(workingDir) configureClassPath() - environment("lavalink.pluginsDir" to testServerFolder.get()) + environment("lavalink.plugins.developmentMode" to true) super.exec() }