diff --git a/CHANGELOG.md b/CHANGELOG.md index 4276497..0977ded 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,11 @@ - **Breaking change!** Refactor development server implementation to use [jpenilla/run-task](https://github.com/jpenilla/run-task/) plugin and integrate run-paper for server execution, improving maintainability and compatibility with various server versions. +- **Breaking change!** + Rename `bukkit.meta { ... }` to `bukkit.plugin { ... }`. + - Task `:parsePluginMetaFile` and `:mergePluginMeta` renamed to `:parsePluginYaml` and `:mergePluginYaml` respectively. + - `bukkit.disableMetaGeneration()` replaced by `bukkit.plugin.disablePluginYamlGeneration()` + - Package `.meta` renamed to `.plugin` to reflect this change - Set the default [JVM toolchain](https://docs.gradle.org/current/userguide/toolchains.html) version instead of setting JVM target and source compatibility to 1.8. By default, the minimal supported JVM version compatible with the specified `bukkit.server.version` is used. diff --git a/README.md b/README.md index 613c1cd..3bf736f 100644 --- a/README.md +++ b/README.md @@ -123,7 +123,7 @@ bukkit { apiVersion = "1.15.2" // Attributes for plugin.yml - meta { + plugin { name.set("MyPlugin") description.set("My amazing plugin, that doing nothing") main.set("com.example.plugin.MyPlugin") diff --git a/src/main/kotlin/Bukkit.kt b/src/main/kotlin/Bukkit.kt index 50a3114..71ef34e 100644 --- a/src/main/kotlin/Bukkit.kt +++ b/src/main/kotlin/Bukkit.kt @@ -1,13 +1,17 @@ package ru.endlesscode.bukkitgradle import org.gradle.api.provider.Provider -import ru.endlesscode.bukkitgradle.meta.extension.PluginMeta +import ru.endlesscode.bukkitgradle.plugin.extension.PluginConfiguration import ru.endlesscode.bukkitgradle.server.extension.ServerConfiguration public interface Bukkit { - /** Plugin meta. */ - public val meta: PluginMeta + /** Plugin plugin. */ + public val plugin: PluginConfiguration + + @Deprecated("Use 'plugin' field instead", ReplaceWith("plugin")) + public val meta: PluginConfiguration + get() = plugin /** Dev server configuration. */ public val server: ServerConfiguration @@ -16,5 +20,7 @@ public interface Bukkit { public val apiVersion: Provider /** Plugin Meta generation enabled. */ + @Deprecated("Use 'plugin.generatePluginYaml' instead", ReplaceWith("plugin.generatePluginYaml")) public val generateMeta: Provider + get() = plugin.generatePluginYaml } diff --git a/src/main/kotlin/BukkitExtension.kt b/src/main/kotlin/BukkitExtension.kt index e3cbe5b..6ab59ea 100644 --- a/src/main/kotlin/BukkitExtension.kt +++ b/src/main/kotlin/BukkitExtension.kt @@ -4,20 +4,19 @@ import org.gradle.api.Action import org.gradle.api.Project import org.gradle.api.model.ObjectFactory import org.gradle.api.provider.Property -import org.gradle.api.provider.Provider import org.gradle.kotlin.dsl.assign import org.gradle.kotlin.dsl.getByType import org.gradle.kotlin.dsl.property import org.slf4j.LoggerFactory import ru.endlesscode.bukkitgradle.extensions.finalizedOnRead import ru.endlesscode.bukkitgradle.extensions.warnSyntaxChanged -import ru.endlesscode.bukkitgradle.meta.extension.PluginMetaImpl +import ru.endlesscode.bukkitgradle.plugin.extension.PluginConfigurationImpl import ru.endlesscode.bukkitgradle.server.ServerConstants import ru.endlesscode.bukkitgradle.server.extension.ServerConfigurationImpl // TODO 1.0: Remove deprecated fields on release public open class BukkitExtension internal constructor( - public final override val meta: PluginMetaImpl, + public final override val plugin: PluginConfigurationImpl, public final override val server: ServerConfigurationImpl, objects: ObjectFactory, ) : Bukkit { @@ -26,12 +25,6 @@ public open class BukkitExtension internal constructor( .convention(ServerConstants.DEFAULT_VERSION) .finalizedOnRead() - private val _generateMeta: Property = objects.property() - .convention(true) - .finalizedOnRead() - - public final override val generateMeta: Provider = _generateMeta - private val logger = LoggerFactory.getLogger("BukkitExtension") @Deprecated("Use 'server' instead", ReplaceWith("server")) @@ -51,8 +44,13 @@ public open class BukkitExtension internal constructor( body.execute(server) } - public fun meta(body: Action) { - body.execute(meta) + public fun plugin(body: Action) { + body.execute(plugin) + } + + @Deprecated("Use 'plugin' instead", ReplaceWith("plugin(body)")) + public fun meta(body: Action) { + plugin(body) } @Deprecated("Use apiVersion instead of version.", ReplaceWith("apiVersion = version")) @@ -61,9 +59,13 @@ public open class BukkitExtension internal constructor( apiVersion = version } - /** Disabled plugin.yml generation. */ + /** Disables plugin.yml generation. */ + @Deprecated( + "Use 'plugin.disablePluginYamlGeneration()' instead", + ReplaceWith("plugin.disablePluginYamlGeneration()") + ) public fun disableMetaGeneration() { - _generateMeta = false + plugin.disablePluginYamlGeneration() } } diff --git a/src/main/kotlin/BukkitGradlePlugin.kt b/src/main/kotlin/BukkitGradlePlugin.kt index 19b39c3..f4b771f 100644 --- a/src/main/kotlin/BukkitGradlePlugin.kt +++ b/src/main/kotlin/BukkitGradlePlugin.kt @@ -6,12 +6,12 @@ import org.gradle.api.plugins.JavaPluginExtension import org.gradle.api.tasks.compile.JavaCompile import org.gradle.kotlin.dsl.* import ru.endlesscode.bukkitgradle.dependencies.Dependencies -import ru.endlesscode.bukkitgradle.meta.PluginMetaPlugin -import ru.endlesscode.bukkitgradle.meta.extension.PluginMetaImpl -import ru.endlesscode.bukkitgradle.meta.util.MinecraftVersion -import ru.endlesscode.bukkitgradle.meta.util.StringUtils -import ru.endlesscode.bukkitgradle.meta.util.parsedApiVersion -import ru.endlesscode.bukkitgradle.meta.util.resolveMinimalJavaVersion +import ru.endlesscode.bukkitgradle.plugin.PluginConfigurationPlugin +import ru.endlesscode.bukkitgradle.plugin.extension.PluginConfigurationImpl +import ru.endlesscode.bukkitgradle.plugin.util.MinecraftVersion +import ru.endlesscode.bukkitgradle.plugin.util.StringUtils +import ru.endlesscode.bukkitgradle.plugin.util.parsedApiVersion +import ru.endlesscode.bukkitgradle.plugin.util.resolveMinimalJavaVersion import ru.endlesscode.bukkitgradle.server.DevServerPlugin import ru.endlesscode.bukkitgradle.server.extension.ServerConfigurationImpl @@ -30,11 +30,11 @@ public class BukkitGradlePlugin : Plugin { /** Adds needed plugins. */ private fun Project.addPlugins() { - val bukkit = extensions.create("bukkit", configurePluginMeta(), ServerConfigurationImpl()) + val bukkit = extensions.create("bukkit", createPluginConfiguration(), ServerConfigurationImpl()) with(plugins) { apply("java") - apply() + apply() apply() } @@ -45,8 +45,8 @@ public class BukkitGradlePlugin : Plugin { } } - private fun Project.configurePluginMeta(): PluginMetaImpl { - return PluginMetaImpl(objects).apply { + private fun Project.createPluginConfiguration(): PluginConfigurationImpl { + return PluginConfigurationImpl(objects).apply { name.convention(project.name) description.convention(provider { project.description }) main.convention(name.map { "${project.group}.${StringUtils.toPascalCase(it)}" }) diff --git a/src/main/kotlin/dependencies/Dependencies.kt b/src/main/kotlin/dependencies/Dependencies.kt index 462cca2..158be73 100644 --- a/src/main/kotlin/dependencies/Dependencies.kt +++ b/src/main/kotlin/dependencies/Dependencies.kt @@ -12,8 +12,8 @@ import org.gradle.kotlin.dsl.KotlinClosure0 import org.gradle.kotlin.dsl.extra import org.gradle.kotlin.dsl.maven import ru.endlesscode.bukkitgradle.bukkit -import ru.endlesscode.bukkitgradle.meta.util.MinecraftVersion -import ru.endlesscode.bukkitgradle.meta.util.parsedApiVersion +import ru.endlesscode.bukkitgradle.plugin.util.MinecraftVersion +import ru.endlesscode.bukkitgradle.plugin.util.parsedApiVersion private typealias RepositoryClosure = Closure diff --git a/src/main/kotlin/extensions/Accessors.kt b/src/main/kotlin/extensions/Accessors.kt new file mode 100644 index 0000000..e84c692 --- /dev/null +++ b/src/main/kotlin/extensions/Accessors.kt @@ -0,0 +1,8 @@ +package ru.endlesscode.bukkitgradle.extensions + +import org.gradle.api.Project +import org.gradle.api.plugins.JavaPluginExtension +import org.gradle.kotlin.dsl.the + +internal val Project.java: JavaPluginExtension + get() = the() diff --git a/src/main/kotlin/meta/PluginMetaPlugin.kt b/src/main/kotlin/meta/PluginMetaPlugin.kt deleted file mode 100644 index 0283975..0000000 --- a/src/main/kotlin/meta/PluginMetaPlugin.kt +++ /dev/null @@ -1,73 +0,0 @@ -package ru.endlesscode.bukkitgradle.meta - -import com.charleskorn.kaml.SequenceStyle -import com.charleskorn.kaml.Yaml -import com.charleskorn.kaml.YamlConfiguration -import org.gradle.api.Plugin -import org.gradle.api.Project -import org.gradle.api.file.CopySpec -import org.gradle.api.file.DuplicatesStrategy -import org.gradle.api.plugins.JavaPluginExtension -import org.gradle.kotlin.dsl.get -import org.gradle.kotlin.dsl.getByType -import org.gradle.kotlin.dsl.named -import org.gradle.kotlin.dsl.register -import ru.endlesscode.bukkitgradle.bukkit -import ru.endlesscode.bukkitgradle.meta.extension.PluginMetaImpl -import ru.endlesscode.bukkitgradle.meta.task.MergePluginMeta -import ru.endlesscode.bukkitgradle.meta.task.ParsePluginMetaFile -import java.io.File - -public class PluginMetaPlugin : Plugin { - - override fun apply(project: Project) { - val yaml = Yaml( - configuration = YamlConfiguration( - encodeDefaults = false, - sequenceStyle = SequenceStyle.Flow - ) - ) - val metaFile = project.findMetaFile() - - val parsePluginMeta = project.tasks.register("parsePluginMetaFile") { - val bukkit = project.bukkit - - this.yaml = yaml - this.meta = bukkit.meta as PluginMetaImpl - this.metaFile.set(metaFile) - - val generateMeta = bukkit.generateMeta - onlyIf { generateMeta.get() } - } - - val mergePluginMeta = project.tasks.register("mergePluginMeta") { - val bukkit = project.bukkit - - this.yaml = yaml - this.meta = bukkit.meta - metaYaml.set(parsePluginMeta.map { it.pluginMetaYaml.get() }) - dependsOn(parsePluginMeta) - - val generateMeta = bukkit.generateMeta - onlyIf { generateMeta.get() } - } - - project.tasks.named("processResources").configure { - from(mergePluginMeta.map { it.target }) - duplicatesStrategy = DuplicatesStrategy.INCLUDE - } - } - - /** Finds and returns project metaFile if it exists. */ - private fun Project.findMetaFile(): File? { - val java = extensions.getByType() - val mainSourceSet = java.sourceSets["main"] - val resourceDir = mainSourceSet.resources.srcDirs.first() - - return File(resourceDir, FILE_NAME).takeIf { it.isFile } - } - - internal companion object { - const val FILE_NAME: String = "plugin.yml" - } -} diff --git a/src/main/kotlin/meta/task/MergePluginMeta.kt b/src/main/kotlin/meta/task/MergePluginMeta.kt deleted file mode 100644 index 935f4b8..0000000 --- a/src/main/kotlin/meta/task/MergePluginMeta.kt +++ /dev/null @@ -1,65 +0,0 @@ -package ru.endlesscode.bukkitgradle.meta.task - -import com.charleskorn.kaml.Yaml -import kotlinx.serialization.encodeToString -import org.gradle.api.DefaultTask -import org.gradle.api.file.ProjectLayout -import org.gradle.api.file.RegularFileProperty -import org.gradle.api.provider.Property -import org.gradle.api.provider.ProviderFactory -import org.gradle.api.tasks.* -import ru.endlesscode.bukkitgradle.TASKS_GROUP_BUKKIT -import ru.endlesscode.bukkitgradle.meta.PluginMetaPlugin -import ru.endlesscode.bukkitgradle.meta.PluginMetaYaml -import ru.endlesscode.bukkitgradle.meta.extension.PluginMeta -import java.io.File -import javax.inject.Inject - -/** - * Task that generates plugin.yml for bukkit plugin. - * - * @see ru.endlesscode.bukkitgradle.meta.PluginMetaPlugin - */ -public abstract class MergePluginMeta @Inject internal constructor( - projectLayout: ProjectLayout, - providers: ProviderFactory -): DefaultTask() { - - @get:Internal - internal lateinit var yaml: Yaml - - @get:Nested - internal lateinit var meta: PluginMeta - - @get:Input - internal abstract val metaYaml: Property - - @get:OutputFile - public abstract val target: RegularFileProperty - - init { - group = TASKS_GROUP_BUKKIT - description = "Generate plugin.yml file" - - val defaultTargetProvider = providers.provider { File(temporaryDir, PluginMetaPlugin.FILE_NAME) } - target.convention(projectLayout.file(defaultTargetProvider)) - } - - /** Writes meta to target file */ - @TaskAction - public fun mergePluginMeta() { - val mergedMeta = metaYaml.get().copy( - main = meta.main.get(), - name = meta.name.get(), - description = meta.description.orNull, - version = meta.version.get(), - apiVersion = meta.apiVersion.orNull?.takeIf { it.isNotEmpty() }, - website = meta.url.orNull, - authors = meta.authors.get().takeIf { it.isNotEmpty() } - ) - - target.get() - .asFile - .writeText(yaml.encodeToString(mergedMeta)) - } -} diff --git a/src/main/kotlin/meta/task/ParsePluginMetaFile.kt b/src/main/kotlin/meta/task/ParsePluginMetaFile.kt deleted file mode 100644 index 7754b7f..0000000 --- a/src/main/kotlin/meta/task/ParsePluginMetaFile.kt +++ /dev/null @@ -1,64 +0,0 @@ -package ru.endlesscode.bukkitgradle.meta.task - -import com.charleskorn.kaml.Yaml -import kotlinx.serialization.decodeFromString -import org.gradle.api.DefaultTask -import org.gradle.api.file.RegularFileProperty -import org.gradle.api.provider.Provider -import org.gradle.api.provider.ProviderFactory -import org.gradle.api.tasks.InputFile -import org.gradle.api.tasks.Internal -import org.gradle.api.tasks.Optional -import org.gradle.api.tasks.TaskAction -import ru.endlesscode.bukkitgradle.TASKS_GROUP_BUKKIT -import ru.endlesscode.bukkitgradle.meta.PluginMetaYaml -import ru.endlesscode.bukkitgradle.meta.extension.PluginMetaImpl -import javax.inject.Inject - -internal abstract class ParsePluginMetaFile @Inject constructor( - providers: ProviderFactory -) : DefaultTask() { - - @get:Internal - lateinit var yaml: Yaml - - @get:Internal - lateinit var meta: PluginMetaImpl - - @get:Optional - @get:InputFile - abstract val metaFile: RegularFileProperty - - @get:Internal - val pluginMetaYaml: Provider = providers.provider { checkNotNull(metaYaml) } - - private var metaYaml: PluginMetaYaml? = null - - init { - group = TASKS_GROUP_BUKKIT - description = "Parse plugin.yml file if it exists" - } - - @TaskAction - fun parse() { - metaYaml = readMetaFromFile() - } - - /** Reads meta from metaFile and adds conventions for specified fields. */ - private fun readMetaFromFile(): PluginMetaYaml { - if (!metaFile.isPresent) return PluginMetaYaml() - - val text = metaFile.get().asFile.readText() - if (text.isBlank()) return PluginMetaYaml() - - return yaml.decodeFromString(text).apply { - main?.let(meta.main::convention) - name?.let(meta.name::convention) - description?.let(meta.description::convention) - version?.let(meta.version::convention) - apiVersion?.let(meta.apiVersion::convention) - website?.let(meta.url::convention) - authors?.let(meta.authors::convention) - } - } -} diff --git a/src/main/kotlin/plugin/PluginConfigurationPlugin.kt b/src/main/kotlin/plugin/PluginConfigurationPlugin.kt new file mode 100644 index 0000000..2f0893d --- /dev/null +++ b/src/main/kotlin/plugin/PluginConfigurationPlugin.kt @@ -0,0 +1,69 @@ +package ru.endlesscode.bukkitgradle.plugin + +import com.charleskorn.kaml.SequenceStyle +import com.charleskorn.kaml.Yaml +import com.charleskorn.kaml.YamlConfiguration +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.file.CopySpec +import org.gradle.api.file.DuplicatesStrategy +import org.gradle.kotlin.dsl.get +import org.gradle.kotlin.dsl.named +import org.gradle.kotlin.dsl.register +import ru.endlesscode.bukkitgradle.bukkit +import ru.endlesscode.bukkitgradle.extensions.java +import ru.endlesscode.bukkitgradle.plugin.extension.PluginConfigurationImpl +import ru.endlesscode.bukkitgradle.plugin.task.MergePluginYaml +import ru.endlesscode.bukkitgradle.plugin.task.ParsePluginYaml +import java.io.File + +public class PluginConfigurationPlugin : Plugin { + + override fun apply(project: Project) { + val yaml = Yaml( + configuration = YamlConfiguration( + encodeDefaults = false, + sequenceStyle = SequenceStyle.Flow + ) + ) + + val parsePluginYaml = project.tasks.register("parsePluginYaml") { + val bukkit = project.bukkit + + this.yaml = yaml + this.plugin = bukkit.plugin as PluginConfigurationImpl + this.pluginYamlFile.set(project.findPluginYaml()) + + val predicate = bukkit.plugin.generatePluginYaml + onlyIf { predicate.get() } + } + + val mergePluginYaml = project.tasks.register("mergePluginYaml") { + val bukkit = project.bukkit + + this.yaml = yaml + this.plugin = bukkit.plugin + pluginYaml.set(parsePluginYaml.map { it.pluginYaml.get() }) + + val predicate = bukkit.plugin.generatePluginYaml + onlyIf { predicate.get() } + } + + project.tasks.named("processResources") { + from(mergePluginYaml) + duplicatesStrategy = DuplicatesStrategy.INCLUDE + } + } + + /** Finds and returns project's plugin.yaml if it exists. */ + private fun Project.findPluginYaml(): File? { + val mainSourceSet = java.sourceSets["main"] + val resourceDir = mainSourceSet.resources.srcDirs.first() + + return File(resourceDir, FILE_NAME).takeIf { it.isFile } + } + + internal companion object { + const val FILE_NAME: String = "plugin.yml" + } +} diff --git a/src/main/kotlin/meta/PluginMetaYaml.kt b/src/main/kotlin/plugin/PluginYaml.kt similarity index 75% rename from src/main/kotlin/meta/PluginMetaYaml.kt rename to src/main/kotlin/plugin/PluginYaml.kt index bc62303..78a0666 100644 --- a/src/main/kotlin/meta/PluginMetaYaml.kt +++ b/src/main/kotlin/plugin/PluginYaml.kt @@ -1,10 +1,10 @@ -package ru.endlesscode.bukkitgradle.meta +package ru.endlesscode.bukkitgradle.plugin import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @Serializable -internal data class PluginMetaYaml( +internal data class PluginYaml( /** The class of the plugin that extends JavaPlugin. */ val main: String? = null, @@ -32,11 +32,14 @@ internal data class PluginMetaYaml( val author: String? = null, /** - * Allows to list multiple authors, if it is a collaborative project. + * Allows listing multiple authors if it is a collaborative project. * @see author */ val authors: List? = null, + /** The contributors to the plugin that aren't the managing author(s). */ + val contributors: List? = null, + /** The plugin's or author's website. */ val website: String? = null, @@ -49,6 +52,14 @@ internal data class PluginMetaYaml( /** A list of plugins that should be loaded after your plugin. */ val loadbefore: List? = null, + /** + * This can be used to tell the server that this plugin will provide the functionality + * of some library or other plugin (like an alias system). + * Plugins that (soft)depend on the other plugin will treat your plugin + * as if the other plugin exists when resolving dependencies or using `PluginManager#getPlugin(String)`. + */ + val provides: List? = null, + /** A list of libraries your plugin needs which can be loaded from Maven Central. */ val libraries: List? = null, @@ -56,7 +67,11 @@ internal data class PluginMetaYaml( val commands: Map? = null, /** Permission that the plugin wishes to register. */ - val permissions: Map? = null + val permissions: Map? = null, + + /** The default value that permissions that don't have a `default` specified will have. */ + @SerialName("default-permission") + val defaultPermission: String? = null, ) : java.io.Serializable @Serializable diff --git a/src/main/kotlin/meta/extension/PluginMeta.kt b/src/main/kotlin/plugin/extension/PluginConfiguration.kt similarity index 74% rename from src/main/kotlin/meta/extension/PluginMeta.kt rename to src/main/kotlin/plugin/extension/PluginConfiguration.kt index 6be7a89..9a796ff 100644 --- a/src/main/kotlin/meta/extension/PluginMeta.kt +++ b/src/main/kotlin/plugin/extension/PluginConfiguration.kt @@ -1,10 +1,14 @@ -package ru.endlesscode.bukkitgradle.meta.extension +package ru.endlesscode.bukkitgradle.plugin.extension import org.gradle.api.provider.Provider import org.gradle.api.tasks.Input +import org.gradle.api.tasks.Internal import org.gradle.api.tasks.Optional -public interface PluginMeta { +public interface PluginConfiguration { + + @get:Internal + public val generatePluginYaml: Provider @get:Input public val name: Provider diff --git a/src/main/kotlin/meta/extension/PluginMetaImpl.kt b/src/main/kotlin/plugin/extension/PluginConfigurationImpl.kt similarity index 59% rename from src/main/kotlin/meta/extension/PluginMetaImpl.kt rename to src/main/kotlin/plugin/extension/PluginConfigurationImpl.kt index 3ff88ac..2625cbf 100644 --- a/src/main/kotlin/meta/extension/PluginMetaImpl.kt +++ b/src/main/kotlin/plugin/extension/PluginConfigurationImpl.kt @@ -1,4 +1,4 @@ -package ru.endlesscode.bukkitgradle.meta.extension +package ru.endlesscode.bukkitgradle.plugin.extension import org.gradle.api.model.ObjectFactory import org.gradle.api.provider.ListProperty @@ -6,10 +6,16 @@ import org.gradle.api.provider.Property import org.gradle.kotlin.dsl.listProperty import org.gradle.kotlin.dsl.property import org.slf4j.LoggerFactory +import ru.endlesscode.bukkitgradle.extensions.finalizedOnRead import ru.endlesscode.bukkitgradle.extensions.warnSyntaxChanged // TODO 1.0: Remove deprecated methods -public class PluginMetaImpl(objects: ObjectFactory) : PluginMeta { +public class PluginConfigurationImpl(objects: ObjectFactory) : PluginConfiguration { + + private val _generatePluginYaml: Property = objects.property() + .convention(true) + .finalizedOnRead() + override val generatePluginYaml: Property = _generatePluginYaml override val name: Property = objects.property() override val description: Property = objects.property() @@ -19,41 +25,46 @@ public class PluginMetaImpl(objects: ObjectFactory) : PluginMeta { override val url: Property = objects.property() override val authors: ListProperty = objects.listProperty() - private val logger = LoggerFactory.getLogger("PluginMeta") + private val logger = LoggerFactory.getLogger("PluginConfiguration") @Deprecated("Use property syntax instead", ReplaceWith("this.name.set(name)")) public fun setName(name: String) { - logger.warnSyntaxChanged("bukkit.meta.name = '...'", "bukkit.meta.name.set('...')") + logger.warnSyntaxChanged("bukkit.plugin.name = '...'", "bukkit.plugin.name.set('...')") this.name.set(name) } @Deprecated("Use property syntax instead", ReplaceWith("this.description.set(description)")) public fun setDescription(description: String) { - logger.warnSyntaxChanged("bukkit.meta.description = '...'", "bukkit.meta.description.set('...')") + logger.warnSyntaxChanged("bukkit.plugin.description = '...'", "bukkit.plugin.description.set('...')") this.description.set(description) } @Deprecated("Use property syntax instead", ReplaceWith("this.main.set(main)")) public fun setMain(main: String) { - logger.warnSyntaxChanged("bukkit.meta.main = '...'", "bukkit.meta.main.set('...')") + logger.warnSyntaxChanged("bukkit.plugin.main = '...'", "bukkit.plugin.main.set('...')") this.main.set(main) } @Deprecated("Use property syntax instead", ReplaceWith("this.version.set(version)")) public fun setVersion(version: String) { - logger.warnSyntaxChanged("bukkit.meta.version = '...'", "bukkit.meta.version.set('...')") + logger.warnSyntaxChanged("bukkit.plugin.version = '...'", "bukkit.plugin.version.set('...')") this.version.set(version) } @Deprecated("Use property syntax instead", ReplaceWith("this.url.set(url)")) public fun setUrl(url: String) { - logger.warnSyntaxChanged("bukkit.meta.url = '...'", "bukkit.meta.url.set('...')") + logger.warnSyntaxChanged("bukkit.plugin.url = '...'", "bukkit.plugin.url.set('...')") this.url.set(url) } @Deprecated("Use property syntax instead", ReplaceWith("this.authors.set(authors)")) public fun setAuthors(authors: List) { - logger.warnSyntaxChanged("bukkit.meta.authors = [...]", "bukkit.meta.authors.set([...])") + logger.warnSyntaxChanged("bukkit.plugin.authors = [...]", "bukkit.plugin.authors.set([...])") this.authors.set(authors) } + + /** Disables plugin.yaml parsing and generation. */ + public fun disablePluginYamlGeneration() { + _generatePluginYaml.set(false) + } } diff --git a/src/main/kotlin/plugin/task/MergePluginYaml.kt b/src/main/kotlin/plugin/task/MergePluginYaml.kt new file mode 100644 index 0000000..9a4434f --- /dev/null +++ b/src/main/kotlin/plugin/task/MergePluginYaml.kt @@ -0,0 +1,65 @@ +package ru.endlesscode.bukkitgradle.plugin.task + +import com.charleskorn.kaml.Yaml +import kotlinx.serialization.encodeToString +import org.gradle.api.DefaultTask +import org.gradle.api.file.ProjectLayout +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.provider.Property +import org.gradle.api.provider.ProviderFactory +import org.gradle.api.tasks.* +import ru.endlesscode.bukkitgradle.TASKS_GROUP_BUKKIT +import ru.endlesscode.bukkitgradle.plugin.PluginConfigurationPlugin +import ru.endlesscode.bukkitgradle.plugin.PluginYaml +import ru.endlesscode.bukkitgradle.plugin.extension.PluginConfiguration +import java.io.File +import javax.inject.Inject + +/** + * Task that generates plugin.yml for bukkit plugin. + * + * @see ru.endlesscode.bukkitgradle.plugin.PluginConfigurationPlugin + */ +public abstract class MergePluginYaml @Inject internal constructor( + projectLayout: ProjectLayout, + providers: ProviderFactory +): DefaultTask() { + + @get:Internal + internal lateinit var yaml: Yaml + + @get:Nested + internal lateinit var plugin: PluginConfiguration + + @get:Input + internal abstract val pluginYaml: Property + + @get:OutputFile + public abstract val target: RegularFileProperty + + init { + group = TASKS_GROUP_BUKKIT + description = "Generate plugin.yml file" + + val defaultTargetProvider = providers.provider { File(temporaryDir, PluginConfigurationPlugin.FILE_NAME) } + target.convention(projectLayout.file(defaultTargetProvider)) + } + + /** Writes plugin to a target file */ + @TaskAction + public fun mergePluginYaml() { + val merged = pluginYaml.get().copy( + main = plugin.main.get(), + name = plugin.name.get(), + description = plugin.description.orNull, + version = plugin.version.get(), + apiVersion = plugin.apiVersion.orNull?.takeIf { it.isNotEmpty() }, + website = plugin.url.orNull, + authors = plugin.authors.get().takeIf { it.isNotEmpty() } + ) + + target.get() + .asFile + .writeText(yaml.encodeToString(merged)) + } +} diff --git a/src/main/kotlin/plugin/task/ParsePluginYaml.kt b/src/main/kotlin/plugin/task/ParsePluginYaml.kt new file mode 100644 index 0000000..81f761b --- /dev/null +++ b/src/main/kotlin/plugin/task/ParsePluginYaml.kt @@ -0,0 +1,69 @@ +package ru.endlesscode.bukkitgradle.plugin.task + +import com.charleskorn.kaml.EmptyYamlDocumentException +import com.charleskorn.kaml.Yaml +import com.charleskorn.kaml.decodeFromStream +import org.gradle.api.DefaultTask +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.provider.Provider +import org.gradle.api.provider.ProviderFactory +import org.gradle.api.tasks.InputFile +import org.gradle.api.tasks.Internal +import org.gradle.api.tasks.Optional +import org.gradle.api.tasks.TaskAction +import ru.endlesscode.bukkitgradle.TASKS_GROUP_BUKKIT +import ru.endlesscode.bukkitgradle.plugin.PluginYaml +import ru.endlesscode.bukkitgradle.plugin.extension.PluginConfigurationImpl +import javax.inject.Inject + +internal abstract class ParsePluginYaml @Inject constructor( + providers: ProviderFactory +) : DefaultTask() { + + @get:Internal + lateinit var yaml: Yaml + + @get:Internal + lateinit var plugin: PluginConfigurationImpl + + @get:Optional + @get:InputFile + abstract val pluginYamlFile: RegularFileProperty + + private var _pluginYaml: PluginYaml? = null + + @get:Internal + val pluginYaml: Provider = providers.provider { checkNotNull(_pluginYaml) } + + init { + group = TASKS_GROUP_BUKKIT + description = "Parse plugin.yml file if it exists" + } + + @TaskAction + fun parse() { + _pluginYaml = readFromFile() + } + + /** Reads plugin.yaml from [pluginYamlFile] and adds conventions for specified fields. */ + private fun readFromFile(): PluginYaml { + if (!pluginYamlFile.isPresent) return PluginYaml() + + val file = pluginYamlFile.get().asFile + val pluginYaml = try { + file.inputStream().use { yaml.decodeFromStream(it) } + } catch (cause: EmptyYamlDocumentException) { + return PluginYaml() + } + + return pluginYaml.apply { + main?.let(plugin.main::convention) + name?.let(plugin.name::convention) + description?.let(plugin.description::convention) + version?.let(plugin.version::convention) + apiVersion?.let(plugin.apiVersion::convention) + website?.let(plugin.url::convention) + authors?.let(plugin.authors::convention) + } + } +} diff --git a/src/main/kotlin/meta/util/MinecraftVersion.kt b/src/main/kotlin/plugin/util/MinecraftVersion.kt similarity index 97% rename from src/main/kotlin/meta/util/MinecraftVersion.kt rename to src/main/kotlin/plugin/util/MinecraftVersion.kt index 3f63af8..6623b88 100644 --- a/src/main/kotlin/meta/util/MinecraftVersion.kt +++ b/src/main/kotlin/plugin/util/MinecraftVersion.kt @@ -1,4 +1,4 @@ -package ru.endlesscode.bukkitgradle.meta.util +package ru.endlesscode.bukkitgradle.plugin.util import org.gradle.jvm.toolchain.JavaLanguageVersion import ru.endlesscode.bukkitgradle.Bukkit diff --git a/src/main/kotlin/meta/util/StringUtils.kt b/src/main/kotlin/plugin/util/StringUtils.kt similarity index 87% rename from src/main/kotlin/meta/util/StringUtils.kt rename to src/main/kotlin/plugin/util/StringUtils.kt index 38a7d63..a589bd0 100644 --- a/src/main/kotlin/meta/util/StringUtils.kt +++ b/src/main/kotlin/plugin/util/StringUtils.kt @@ -1,4 +1,4 @@ -package ru.endlesscode.bukkitgradle.meta.util +package ru.endlesscode.bukkitgradle.plugin.util internal object StringUtils { diff --git a/src/main/kotlin/server/DevServerPlugin.kt b/src/main/kotlin/server/DevServerPlugin.kt index a7a8857..5968d15 100644 --- a/src/main/kotlin/server/DevServerPlugin.kt +++ b/src/main/kotlin/server/DevServerPlugin.kt @@ -11,7 +11,7 @@ import org.gradle.jvm.toolchain.JavaToolchainService import org.gradle.kotlin.dsl.* import ru.endlesscode.bukkitgradle.Bukkit import ru.endlesscode.bukkitgradle.bukkit -import ru.endlesscode.bukkitgradle.meta.util.resolveMinimalJavaVersion +import ru.endlesscode.bukkitgradle.plugin.util.resolveMinimalJavaVersion import ru.endlesscode.bukkitgradle.server.extension.ServerConfiguration import ru.endlesscode.bukkitgradle.server.task.CreateIdeaGradleRunConfiguration import ru.endlesscode.bukkitgradle.server.task.PrepareServer diff --git a/src/test/groovy/ru/endlesscode/bukkitgradle/meta/task/MergePluginMetaSpec.groovy b/src/test/groovy/ru/endlesscode/bukkitgradle/plugin/task/MergePluginYamlSpec.groovy similarity index 60% rename from src/test/groovy/ru/endlesscode/bukkitgradle/meta/task/MergePluginMetaSpec.groovy rename to src/test/groovy/ru/endlesscode/bukkitgradle/plugin/task/MergePluginYamlSpec.groovy index 7dc8288..977d4ce 100644 --- a/src/test/groovy/ru/endlesscode/bukkitgradle/meta/task/MergePluginMetaSpec.groovy +++ b/src/test/groovy/ru/endlesscode/bukkitgradle/plugin/task/MergePluginYamlSpec.groovy @@ -1,58 +1,58 @@ -package ru.endlesscode.bukkitgradle.meta.task +package ru.endlesscode.bukkitgradle.plugin.task import org.gradle.testkit.runner.TaskOutcome import ru.endlesscode.bukkitgradle.PluginSpecification -import ru.endlesscode.bukkitgradle.meta.PluginMetaPlugin +import ru.endlesscode.bukkitgradle.plugin.PluginConfigurationPlugin import ru.endlesscode.bukkitgradle.util.CharsetUtils -class MergePluginMetaSpec extends PluginSpecification { +class MergePluginYamlSpec extends PluginSpecification { - private final static TASK_PATH = ':mergePluginMeta' + private final static MERGE_PLUGIN_YAML = ':mergePluginYaml' - private File sourceMetaFile - private File metaFile + private File sourcePluginYamlFile + private File pluginYamlFile def setup() { - sourceMetaFile = file("src/main/resources/$PluginMetaPlugin.FILE_NAME") - metaFile = file("build/tmp/mergePluginMeta/$PluginMetaPlugin.FILE_NAME") + sourcePluginYamlFile = file("src/main/resources/$PluginConfigurationPlugin.FILE_NAME") + pluginYamlFile = file("build/tmp/mergePluginYaml/$PluginConfigurationPlugin.FILE_NAME") buildFile << """ bukkit.apiVersion = "1.16.2" """.stripIndent() } - def 'when run processResources - should also run generatePluginMeta'() { - when: "run processResources" + def 'when run processResources - should also run mergePluginYaml'() { + when: run(':processResources') - then: "task generatePluginMeta completed successfully" - taskOutcome(TASK_PATH) == TaskOutcome.SUCCESS + then: + taskOutcome(MERGE_PLUGIN_YAML) == TaskOutcome.SUCCESS - and: "task generatePluginMeta completed successfully" - taskOutcome(":parsePluginMetaFile") == TaskOutcome.SUCCESS + and: + taskOutcome(":parsePluginYaml") == TaskOutcome.SUCCESS } - def 'when run processResources - and meta generation disabled - should not run generatePluginMeta'() { - given: "meta generation disabled" - buildFile << "bukkit.disableMetaGeneration()" + def 'when run processResources - and plugin.yaml generation disabled - should not run mergePluginYaml'() { + given: "plugin generation disabled" + buildFile << "bukkit.plugin.disablePluginYamlGeneration()" when: "run processResources" run(':processResources') - then: "task generatePluginMeta completed successfully" - taskOutcome(TASK_PATH) == TaskOutcome.SKIPPED + then: "task mergePluginYaml completed successfully" + taskOutcome(MERGE_PLUGIN_YAML) == TaskOutcome.SKIPPED - and: "task generatePluginMeta completed successfully" - taskOutcome(":parsePluginMetaFile") == TaskOutcome.SKIPPED + and: "task mergePluginYaml completed successfully" + taskOutcome(":parsePluginYaml") == TaskOutcome.SKIPPED } - def 'when merge meta - should generate default plugin meta successfully'() { - when: "run generate meta task" - run(TASK_PATH) + def 'when merge plugin.yaml - should generate default plugin.yaml successfully'() { + when: + run(MERGE_PLUGIN_YAML) - then: "meta file content corresponds to default config" - metaFile.text == """ + then: "plugin file content corresponds to default config" + pluginYamlFile.text == """ main: "com.example.testplugin.TestPlugin" name: "test-plugin" version: "1.0" @@ -60,17 +60,17 @@ class MergePluginMetaSpec extends PluginSpecification { """.stripIndent().trim() } - def 'when merge meta - should set api-version'(String apiVersion, String expectedResult) { + def 'when merge plugin.yaml - should set api-version'(String apiVersion, String expectedResult) { when: "api version is $apiVersion" buildFile << """ bukkit.apiVersion = "$apiVersion" """.stripIndent() - and: "run generate meta task" - run(TASK_PATH) + and: + run(MERGE_PLUGIN_YAML) - then: "meta file content corresponds to default config" - metaFile.text == """ + then: "plugin file content corresponds to default config" + pluginYamlFile.text == """ main: "com.example.testplugin.TestPlugin" name: "test-plugin" version: "1.0" @@ -85,32 +85,32 @@ class MergePluginMetaSpec extends PluginSpecification { "1.21.1" | "1.21.1" } - def 'when merge meta - and generate it again - should skip second task run'() { - when: "run generate meta task" - run(TASK_PATH) + def 'when merge plugin.yaml - and generate it again - should skip second task run'() { + when: + run(MERGE_PLUGIN_YAML) - and: "run generate meta again" - run(TASK_PATH) + and: "run generate again" + run(MERGE_PLUGIN_YAML) then: "the task is skipped due to up-to-date" - taskOutcome(TASK_PATH) == TaskOutcome.UP_TO_DATE + taskOutcome(MERGE_PLUGIN_YAML) == TaskOutcome.UP_TO_DATE } - def 'when merge meta - and generate changed meta - should generate new meta'() { - when: "run generate meta task" - run(TASK_PATH) + def 'when merge plugin.yaml - and changed plugin configuration - should update plugin.yaml'() { + when: + run(MERGE_PLUGIN_YAML) - and: "change description" + and: "changed description" buildFile << 'description = "Plugin can has description"' - and: "run generate meta task again" - run(TASK_PATH) + and: "run the task again" + run(MERGE_PLUGIN_YAML) then: "the task is successful" - taskOutcome(TASK_PATH) == TaskOutcome.SUCCESS + taskOutcome(MERGE_PLUGIN_YAML) == TaskOutcome.SUCCESS - and: "meta generated with new description" - metaFile.text == """ + and: "plugin generated with new description" + pluginYamlFile.text == """ main: "com.example.testplugin.TestPlugin" name: "test-plugin" description: "Plugin can has description" @@ -119,12 +119,12 @@ class MergePluginMetaSpec extends PluginSpecification { """.stripIndent().trim() } - void 'when merge meta - and all properties configured - should write all lines'() { - given: "configured all meta properties" + void 'when merge plugin.yaml - and all properties configured - should write all lines'() { + given: "configured all plugin properties" //language=gradle buildFile << """ bukkit { - meta { + plugin { name.set('TestPlugin') description.set('Test plugin description') main.set('com.example.plugin.Plugin') @@ -137,10 +137,10 @@ class MergePluginMetaSpec extends PluginSpecification { """.stripIndent() when: "run processResources" - run(TASK_PATH) + run(MERGE_PLUGIN_YAML) then: "should write all lines" - metaFile.text == """ + pluginYamlFile.text == """ main: "com.example.plugin.Plugin" name: "TestPlugin" description: "Test plugin description" @@ -151,12 +151,12 @@ class MergePluginMetaSpec extends PluginSpecification { """.stripIndent().trim() } - void 'when merge meta - and all properties configured old way - should write all lines'() { - given: "configured all meta properties in old way" + void 'when merge plugin.yaml - and all properties configured old way - should write all lines'() { + given: "configured all plugin properties in old way" //language=gradle buildFile << """ bukkit { - meta { + plugin { name = 'TestPlugin' description = 'Test plugin description' main = 'com.example.plugin.Plugin' @@ -168,10 +168,10 @@ class MergePluginMetaSpec extends PluginSpecification { """.stripIndent() when: "run processResources" - run(TASK_PATH) + run(MERGE_PLUGIN_YAML) then: "should write all lines" - metaFile.text == """ + pluginYamlFile.text == """ main: "com.example.plugin.Plugin" name: "TestPlugin" description: "Test plugin description" @@ -182,9 +182,9 @@ class MergePluginMetaSpec extends PluginSpecification { """.stripIndent().trim() } - void 'when merge meta - and there are extra fields in source - should write all lines'() { - given: "source meta file with extra fields" - sourceMetaFile << """ + void 'when merge plugin.yaml - and there are extra fields in source - should write all lines'() { + given: "source plugin file with extra fields" + sourcePluginYamlFile << """ depend: [Vault, ProtocolLib] commands: example: @@ -195,10 +195,10 @@ class MergePluginMetaSpec extends PluginSpecification { """.stripIndent() when: "run processResources" - run(TASK_PATH) + run(MERGE_PLUGIN_YAML) - then: "should write meta with the extra fields" - metaFile.text == """ + then: "should write plugin with the extra fields" + pluginYamlFile.text == """ main: "com.example.testplugin.TestPlugin" name: "test-plugin" version: "1.0" @@ -214,9 +214,9 @@ class MergePluginMetaSpec extends PluginSpecification { } // BukkitGradle-26 - void 'when merge meta - and there are exotic chars in source - should read it correctly'() { - given: "source meta file with exotic chars" - sourceMetaFile << """ + void 'when merge plugin.yaml - and there are exotic chars in source - should read it correctly'() { + given: "source plugin file with exotic chars" + sourcePluginYamlFile << """ commands: 퀘스트: description: 퀘스트 명령어 입니다. @@ -226,11 +226,11 @@ class MergePluginMetaSpec extends PluginSpecification { CharsetUtils.setDefaultCharset('CP866') when: "run processResources" - run(TASK_PATH) + run(MERGE_PLUGIN_YAML) CharsetUtils.setDefaultCharset('UTF-8') then: - metaFile.text == """ + pluginYamlFile.text == """ main: "com.example.testplugin.TestPlugin" name: "test-plugin" version: "1.0" @@ -241,18 +241,18 @@ class MergePluginMetaSpec extends PluginSpecification { """.stripIndent().trim() } - void 'when merge meta - and there are fields in source - should prefer values from source'() { - given: "source meta file with extra fields" - sourceMetaFile << """ + void 'when merge plugin.yaml - and there are fields in source - should prefer values from source'() { + given: "source plugin file with extra fields" + sourcePluginYamlFile << """ name: SourceValue version: 1.2 """.stripIndent() when: "run processResources" - run(TASK_PATH, "--stacktrace") + run(MERGE_PLUGIN_YAML) - then: "should write meta and prefer source fields" - metaFile.text == """ + then: "should write plugin and prefer source fields" + pluginYamlFile.text == """ main: "com.example.testplugin.SourceValue" name: "SourceValue" version: "1.2" @@ -260,28 +260,28 @@ class MergePluginMetaSpec extends PluginSpecification { """.stripIndent().trim() } - void 'when merge meta - and there are conflicting fields in source and in build script - should prefer values from build script'() { - given: "source meta file with extra fields" - sourceMetaFile << """ + void 'when merge plugin.yaml - and there are conflicting fields in source and in build script - should prefer values from build script'() { + given: "source plugin.yaml file with extra fields" + sourcePluginYamlFile << """ name: SourceValue version: 1.2 """.stripIndent() - and: "conflicting gields in build script" + and: "conflicting fields in build script" buildFile << """ bukkit { - meta { + plugin { name.set("BuildscriptValue") version.set("1.3") } } """.stripIndent() - when: "run processResources" - run(TASK_PATH, "--stacktrace") + when: + run(MERGE_PLUGIN_YAML) - then: "should write meta and prefer source fields" - metaFile.text == """ + then: "should overwrite source fields" + pluginYamlFile.text == """ main: "com.example.testplugin.BuildscriptValue" name: "BuildscriptValue" version: "1.3" diff --git a/src/test/groovy/ru/endlesscode/bukkitgradle/meta/util/StringUtilsSpec.groovy b/src/test/groovy/ru/endlesscode/bukkitgradle/plugin/util/StringUtilsSpec.groovy similarity index 90% rename from src/test/groovy/ru/endlesscode/bukkitgradle/meta/util/StringUtilsSpec.groovy rename to src/test/groovy/ru/endlesscode/bukkitgradle/plugin/util/StringUtilsSpec.groovy index 4f6f341..ab4e4d3 100644 --- a/src/test/groovy/ru/endlesscode/bukkitgradle/meta/util/StringUtilsSpec.groovy +++ b/src/test/groovy/ru/endlesscode/bukkitgradle/plugin/util/StringUtilsSpec.groovy @@ -1,4 +1,4 @@ -package ru.endlesscode.bukkitgradle.meta.util +package ru.endlesscode.bukkitgradle.plugin.util import spock.lang.Specification