mirror of
https://github.com/plexusorg/plugin-yml.git
synced 2024-12-22 16:25:06 +00:00
Fixup incremental builds
Get rid of all the Serializable mess and instead use @ Nested to tell Gradle to look at the plugin descriptions directly. This means that we need some annotation mess inside the plugin description classes though. :D
This commit is contained in:
parent
5fff9cf695
commit
886351c1ae
7 changed files with 139 additions and 106 deletions
|
@ -26,26 +26,34 @@ package net.minecrell.pluginyml
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonInclude
|
import com.fasterxml.jackson.annotation.JsonInclude
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper
|
import com.fasterxml.jackson.databind.ObjectMapper
|
||||||
|
import com.fasterxml.jackson.databind.module.SimpleModule
|
||||||
|
import com.fasterxml.jackson.databind.ser.std.StdDelegatingSerializer
|
||||||
|
import com.fasterxml.jackson.databind.util.Converter
|
||||||
|
import com.fasterxml.jackson.databind.util.StdConverter
|
||||||
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
|
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
|
||||||
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator
|
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator
|
||||||
import com.fasterxml.jackson.module.kotlin.registerKotlinModule
|
import com.fasterxml.jackson.module.kotlin.registerKotlinModule
|
||||||
import org.gradle.api.DefaultTask
|
import org.gradle.api.DefaultTask
|
||||||
|
import org.gradle.api.NamedDomainObjectCollection
|
||||||
|
import org.gradle.api.provider.Property
|
||||||
|
import org.gradle.api.provider.Provider
|
||||||
import org.gradle.api.tasks.Input
|
import org.gradle.api.tasks.Input
|
||||||
|
import org.gradle.api.tasks.Nested
|
||||||
import org.gradle.api.tasks.OutputFile
|
import org.gradle.api.tasks.OutputFile
|
||||||
import org.gradle.api.tasks.TaskAction
|
import org.gradle.api.tasks.TaskAction
|
||||||
|
import org.gradle.kotlin.dsl.property
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.Serializable
|
|
||||||
|
|
||||||
open class GeneratePluginDescription : DefaultTask() {
|
open class GeneratePluginDescription : DefaultTask() {
|
||||||
|
|
||||||
@Input
|
@Input
|
||||||
var fileName: String? = null
|
val fileName: Property<String> = project.objects.property()
|
||||||
|
|
||||||
@Input
|
@Nested
|
||||||
var pluginDescription: Serializable? = null
|
val pluginDescription: Property<PluginDescription> = project.objects.property()
|
||||||
|
|
||||||
val outputFile: File
|
val outputFile: Provider<File>
|
||||||
@OutputFile get() = File(temporaryDir, fileName)
|
@OutputFile get() = fileName.map { File(temporaryDir, it) }
|
||||||
|
|
||||||
@TaskAction
|
@TaskAction
|
||||||
fun generate() {
|
fun generate() {
|
||||||
|
@ -54,11 +62,24 @@ open class GeneratePluginDescription : DefaultTask() {
|
||||||
.enable(YAMLGenerator.Feature.MINIMIZE_QUOTES)
|
.enable(YAMLGenerator.Feature.MINIMIZE_QUOTES)
|
||||||
.enable(YAMLGenerator.Feature.INDENT_ARRAYS)
|
.enable(YAMLGenerator.Feature.INDENT_ARRAYS)
|
||||||
|
|
||||||
|
val module = SimpleModule()
|
||||||
|
@Suppress("UNCHECKED_CAST") // Too stupid to figure out the generics here...
|
||||||
|
module.addSerializer(StdDelegatingSerializer(NamedDomainObjectCollection::class.java,
|
||||||
|
NamedDomainObjectCollectionConverter as Converter<NamedDomainObjectCollection<*>, *>))
|
||||||
|
|
||||||
val mapper = ObjectMapper(factory)
|
val mapper = ObjectMapper(factory)
|
||||||
.registerKotlinModule()
|
.registerKotlinModule()
|
||||||
|
.registerModule(module)
|
||||||
.setSerializationInclusion(JsonInclude.Include.NON_EMPTY)
|
.setSerializationInclusion(JsonInclude.Include.NON_EMPTY)
|
||||||
|
|
||||||
mapper.writeValue(outputFile, pluginDescription)
|
mapper.writeValue(outputFile.get(), pluginDescription.get())
|
||||||
|
}
|
||||||
|
|
||||||
|
object NamedDomainObjectCollectionConverter : StdConverter<NamedDomainObjectCollection<Any>, Map<String, Any>>() {
|
||||||
|
override fun convert(value: NamedDomainObjectCollection<Any>): Map<String, Any> {
|
||||||
|
val namer = value.namer
|
||||||
|
return value.associateBy { namer.determineName(it) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,9 +31,8 @@ import org.gradle.api.tasks.AbstractCopyTask
|
||||||
import org.gradle.kotlin.dsl.named
|
import org.gradle.kotlin.dsl.named
|
||||||
import org.gradle.kotlin.dsl.register
|
import org.gradle.kotlin.dsl.register
|
||||||
import org.gradle.kotlin.dsl.withType
|
import org.gradle.kotlin.dsl.withType
|
||||||
import java.io.Serializable
|
|
||||||
|
|
||||||
abstract class PlatformPlugin<T : Serializable>(private val platformName: String, private val fileName: String) : Plugin<Project> {
|
abstract class PlatformPlugin<T : PluginDescription>(private val platformName: String, private val fileName: String) : Plugin<Project> {
|
||||||
|
|
||||||
protected abstract fun createExtension(project: Project): T
|
protected abstract fun createExtension(project: Project): T
|
||||||
|
|
||||||
|
@ -46,11 +45,14 @@ abstract class PlatformPlugin<T : Serializable>(private val platformName: String
|
||||||
|
|
||||||
// Create task
|
// Create task
|
||||||
val generateTask = tasks.register<GeneratePluginDescription>("generate${platformName}PluginDescription") {
|
val generateTask = tasks.register<GeneratePluginDescription>("generate${platformName}PluginDescription") {
|
||||||
fileName = this@PlatformPlugin.fileName
|
fileName.set(this@PlatformPlugin.fileName)
|
||||||
pluginDescription = description
|
pluginDescription.set(provider {
|
||||||
|
setDefaults(project, description)
|
||||||
|
description
|
||||||
|
})
|
||||||
|
|
||||||
doFirst {
|
doFirst {
|
||||||
prepare(project, description)
|
validate(description)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,11 +64,6 @@ abstract class PlatformPlugin<T : Serializable>(private val platformName: String
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun prepare(project: Project, description: T) {
|
|
||||||
setDefaults(project, description)
|
|
||||||
validate(description)
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract fun setDefaults(project: Project, description: T)
|
protected abstract fun setDefaults(project: Project, description: T)
|
||||||
protected abstract fun validate(description: T)
|
protected abstract fun validate(description: T)
|
||||||
|
|
||||||
|
|
27
src/main/kotlin/net/minecrell/pluginyml/PluginDescription.kt
Normal file
27
src/main/kotlin/net/minecrell/pluginyml/PluginDescription.kt
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017 Minecrell <https://github.com/Minecrell>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.minecrell.pluginyml
|
||||||
|
|
||||||
|
interface PluginDescription
|
|
@ -27,37 +27,34 @@ package net.minecrell.pluginyml.bukkit
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnore
|
import com.fasterxml.jackson.annotation.JsonIgnore
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
import groovy.lang.Closure
|
import groovy.lang.Closure
|
||||||
|
import net.minecrell.pluginyml.PluginDescription
|
||||||
import org.gradle.api.NamedDomainObjectContainer
|
import org.gradle.api.NamedDomainObjectContainer
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import java.io.Serializable
|
import org.gradle.api.tasks.Input
|
||||||
|
import org.gradle.api.tasks.Internal
|
||||||
|
import org.gradle.api.tasks.Nested
|
||||||
|
import org.gradle.api.tasks.Optional
|
||||||
|
|
||||||
class BukkitPluginDescription(project: Project) : Serializable {
|
class BukkitPluginDescription(project: Project) : PluginDescription {
|
||||||
|
|
||||||
@JsonProperty("api-version") var apiVersion: String? = null
|
@Input @Optional @JsonProperty("api-version") var apiVersion: String? = null
|
||||||
var name: String? = null
|
@Input var name: String? = null
|
||||||
var version: String? = null
|
@Input var version: String? = null
|
||||||
var main: String? = null
|
@Input var main: String? = null
|
||||||
var description: String? = null
|
@Input @Optional var description: String? = null
|
||||||
var load: PluginLoadOrder? = null
|
@Input @Optional var load: PluginLoadOrder? = null
|
||||||
var author: String? = null
|
@Input @Optional var author: String? = null
|
||||||
var authors: List<String>? = null
|
@Input @Optional var authors: List<String>? = null
|
||||||
var website: String? = null
|
@Input @Optional var website: String? = null
|
||||||
var depend: List<String>? = null
|
@Input @Optional var depend: List<String>? = null
|
||||||
@JsonProperty("softdepend") var softDepend: List<String>? = null
|
@Input @Optional @JsonProperty("softdepend") var softDepend: List<String>? = null
|
||||||
@JsonProperty("loadbefore") var loadBefore: List<String>? = null
|
@Input @Optional @JsonProperty("loadbefore") var loadBefore: List<String>? = null
|
||||||
var prefix: String? = null
|
@Input @Optional var prefix: String? = null
|
||||||
@JsonProperty("default-permission") var defaultPermission: Permission.Default? = null
|
@Input @Optional @JsonProperty("default-permission") var defaultPermission: Permission.Default? = null
|
||||||
var provides: List<String>? = null
|
@Input @Optional var provides: List<String>? = null
|
||||||
|
|
||||||
// DSL provider for commands and permissions (not serialized)
|
@Nested val commands: NamedDomainObjectContainer<Command> = project.container(Command::class.java)
|
||||||
@Transient @JsonIgnore val commands: NamedDomainObjectContainer<Command> = project.container(Command::class.java)
|
@Nested val permissions: NamedDomainObjectContainer<Permission> = project.container(Permission::class.java)
|
||||||
@Transient @JsonIgnore val permissions: NamedDomainObjectContainer<Permission> = project.container(Permission::class.java)
|
|
||||||
|
|
||||||
// Java/Jackson serialization for commands and permissions
|
|
||||||
internal val commandMap: Map<String, Command>
|
|
||||||
@JsonProperty("commands") get() = commands.associateBy { it.name }
|
|
||||||
internal val permissionMap: Map<String, Permission>
|
|
||||||
@JsonProperty("permissions") get() = permissions.associateBy { it.name }
|
|
||||||
|
|
||||||
// For Groovy DSL
|
// For Groovy DSL
|
||||||
fun commands(closure: Closure<Unit>) = commands.configure(closure)
|
fun commands(closure: Closure<Unit>) = commands.configure(closure)
|
||||||
|
@ -68,23 +65,23 @@ class BukkitPluginDescription(project: Project) : Serializable {
|
||||||
POSTWORLD
|
POSTWORLD
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Command(@Transient @JsonIgnore val name: String) : Serializable {
|
data class Command(@Input @JsonIgnore val name: String) {
|
||||||
var description: String? = null
|
@Input @Optional var description: String? = null
|
||||||
var aliases: List<String>? = null
|
@Input @Optional var aliases: List<String>? = null
|
||||||
var permission: String? = null
|
@Input @Optional var permission: String? = null
|
||||||
@JsonProperty("permission-message") var permissionMessage: String? = null
|
@Input @Optional @JsonProperty("permission-message") var permissionMessage: String? = null
|
||||||
var usage: String? = null
|
@Input @Optional var usage: String? = null
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Permission(@Transient @JsonIgnore val name: String) : Serializable {
|
data class Permission(@Input @JsonIgnore val name: String) {
|
||||||
var description: String? = null
|
@Input @Optional var description: String? = null
|
||||||
var default: Default? = null
|
@Input @Optional var default: Default? = null
|
||||||
var children: List<String>?
|
var children: List<String>?
|
||||||
@JsonIgnore get() = childrenMap?.filterValues { it }?.keys?.toList()
|
@Internal @JsonIgnore get() = childrenMap?.filterValues { it }?.keys?.toList()
|
||||||
set(value) {
|
set(value) {
|
||||||
childrenMap = value?.associateWith { true }
|
childrenMap = value?.associateWith { true }
|
||||||
}
|
}
|
||||||
@JsonProperty("children") var childrenMap: Map<String, Boolean>? = null
|
@Input @Optional @JsonProperty("children") var childrenMap: Map<String, Boolean>? = null
|
||||||
|
|
||||||
enum class Default {
|
enum class Default {
|
||||||
@JsonProperty("true") TRUE,
|
@JsonProperty("true") TRUE,
|
||||||
|
|
|
@ -24,14 +24,16 @@
|
||||||
|
|
||||||
package net.minecrell.pluginyml.bungee
|
package net.minecrell.pluginyml.bungee
|
||||||
|
|
||||||
import java.io.Serializable
|
import net.minecrell.pluginyml.PluginDescription
|
||||||
|
import org.gradle.api.tasks.Input
|
||||||
|
import org.gradle.api.tasks.Optional
|
||||||
|
|
||||||
class BungeePluginDescription : Serializable {
|
class BungeePluginDescription : PluginDescription {
|
||||||
var name: String? = null
|
@Input var name: String? = null
|
||||||
var main: String? = null
|
@Input var main: String? = null
|
||||||
var version: String? = null
|
@Input @Optional var version: String? = null
|
||||||
var author: String? = null
|
@Input @Optional var author: String? = null
|
||||||
var depends: Set<String>? = null
|
@Input @Optional var depends: Set<String>? = null
|
||||||
var softDepends: Set<String>? = null
|
@Input @Optional var softDepends: Set<String>? = null
|
||||||
var description: String? = null
|
@Input @Optional var description: String? = null
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ class NukkitPlugin : PlatformPlugin<NukkitPluginDescription>("Nukkit", "nukkit.y
|
||||||
if (main.isEmpty()) throw InvalidPluginDescriptionException("Main class cannot be empty")
|
if (main.isEmpty()) throw InvalidPluginDescriptionException("Main class cannot be empty")
|
||||||
if (main.startsWith("cn.nukkit.")) throw InvalidPluginDescriptionException("Main class cannot be within cn.nukkit. package")
|
if (main.startsWith("cn.nukkit.")) throw InvalidPluginDescriptionException("Main class cannot be within cn.nukkit. package")
|
||||||
|
|
||||||
if (description.api?.isEmpty() != false) throw InvalidPluginDescriptionException("Nukkit API version is not set")
|
if (description.api.isNullOrEmpty()) throw InvalidPluginDescriptionException("Nukkit API version is not set")
|
||||||
|
|
||||||
for (command in description.commands) {
|
for (command in description.commands) {
|
||||||
if (command.name.contains(':')) throw InvalidPluginDescriptionException("Command '${command.name}' cannot contain ':'")
|
if (command.name.contains(':')) throw InvalidPluginDescriptionException("Command '${command.name}' cannot contain ':'")
|
||||||
|
|
|
@ -27,40 +27,35 @@ package net.minecrell.pluginyml.nukkit
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnore
|
import com.fasterxml.jackson.annotation.JsonIgnore
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
import groovy.lang.Closure
|
import groovy.lang.Closure
|
||||||
|
import net.minecrell.pluginyml.PluginDescription
|
||||||
import org.gradle.api.NamedDomainObjectContainer
|
import org.gradle.api.NamedDomainObjectContainer
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import java.io.Serializable
|
import org.gradle.api.tasks.Input
|
||||||
|
import org.gradle.api.tasks.Internal
|
||||||
|
import org.gradle.api.tasks.Nested
|
||||||
|
import org.gradle.api.tasks.Optional
|
||||||
|
|
||||||
class NukkitPluginDescription(project: Project) : Serializable {
|
class NukkitPluginDescription(project: Project) : PluginDescription {
|
||||||
|
|
||||||
var name: String? = null
|
@Input var name: String? = null
|
||||||
var main: String? = null
|
@Input var main: String? = null
|
||||||
var version: String? = null
|
@Input var version: String? = null
|
||||||
var api: List<String>? = null
|
@Input var api: List<String>? = null
|
||||||
var description: String? = null
|
@Input @Optional var description: String? = null
|
||||||
var load: PluginLoadOrder? = null
|
@Input @Optional var load: PluginLoadOrder? = null
|
||||||
var author: String? = null
|
@Input @Optional var author: String? = null
|
||||||
var authors: List<String>? = null
|
@Input @Optional var authors: List<String>? = null
|
||||||
var website: String? = null
|
@Input @Optional var website: String? = null
|
||||||
var depend: List<String>? = null
|
@Input @Optional var depend: List<String>? = null
|
||||||
@JsonProperty("softdepend") var softDepend: List<String>? = null
|
@Input @Optional @JsonProperty("softdepend") var softDepend: List<String>? = null
|
||||||
@JsonProperty("loadbefore") var loadBefore: List<String>? = null
|
@Input @Optional @JsonProperty("loadbefore") var loadBefore: List<String>? = null
|
||||||
var prefix: String? = null
|
@Input @Optional var prefix: String? = null
|
||||||
|
|
||||||
// DSL provider for commands and permissions (not serialized)
|
@Nested val commands: NamedDomainObjectContainer<Command> = project.container(Command::class.java)
|
||||||
@Transient @JsonIgnore
|
@Nested val permissions: NamedDomainObjectContainer<Permission> = project.container(Permission::class.java) {
|
||||||
val commands: NamedDomainObjectContainer<Command> = project.container(Command::class.java)
|
|
||||||
@Transient @JsonIgnore
|
|
||||||
val permissions: NamedDomainObjectContainer<Permission> = project.container(Permission::class.java) {
|
|
||||||
Permission(project, it)
|
Permission(project, it)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Java/Jackson serialization for commands and permissions
|
|
||||||
internal val commandMap: Map<String, Command>
|
|
||||||
@JsonProperty("commands") get() = commands.associateBy { it.name }
|
|
||||||
internal val permissionMap: Map<String, Permission>
|
|
||||||
@JsonProperty("permissions") get() = permissions.associateBy { it.name }
|
|
||||||
|
|
||||||
// For Groovy DSL
|
// For Groovy DSL
|
||||||
fun commands(closure: Closure<Unit>) = commands.configure(closure)
|
fun commands(closure: Closure<Unit>) = commands.configure(closure)
|
||||||
fun permissions(closure: Closure<Unit>) = permissions.configure(closure)
|
fun permissions(closure: Closure<Unit>) = permissions.configure(closure)
|
||||||
|
@ -70,29 +65,23 @@ class NukkitPluginDescription(project: Project) : Serializable {
|
||||||
POSTWORLD
|
POSTWORLD
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Command(@Transient @JsonIgnore val name: String) : Serializable {
|
data class Command(@Input @JsonIgnore val name: String) {
|
||||||
var description: String? = null
|
@Input @Optional var description: String? = null
|
||||||
var aliases: List<String>? = null
|
@Input @Optional var aliases: List<String>? = null
|
||||||
var permission: String? = null
|
@Input @Optional var permission: String? = null
|
||||||
@JsonProperty("permission-message") var permissionMessage: String? = null
|
@Input @Optional @JsonProperty("permission-message") var permissionMessage: String? = null
|
||||||
var usage: String? = null
|
@Input @Optional var usage: String? = null
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Permission(@Transient @JsonIgnore val project: Project, @Transient @JsonIgnore val name: String) : Serializable {
|
data class Permission(@Internal @JsonIgnore val project: Project, @Input @JsonIgnore val name: String) {
|
||||||
|
|
||||||
var description: String? = null
|
@Input @Optional var description: String? = null
|
||||||
var default: Default? = null
|
@Input @Optional var default: Default? = null
|
||||||
|
|
||||||
// DSL provider for recursive children (not serialized)
|
@Nested val children: NamedDomainObjectContainer<Permission> = project.container(Permission::class.java) {
|
||||||
@Transient @JsonIgnore
|
|
||||||
val children: NamedDomainObjectContainer<Permission> = project.container(Permission::class.java) {
|
|
||||||
Permission(project, it)
|
Permission(project, it)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Java/Jackson serialization for commands and permissions
|
|
||||||
internal val childrenMap: Map<String, Permission>
|
|
||||||
@JsonProperty("children") get() = children.associateBy { it.name }
|
|
||||||
|
|
||||||
// For Groovy DSL
|
// For Groovy DSL
|
||||||
fun children(closure: Closure<Unit>) = children.configure(closure)
|
fun children(closure: Closure<Unit>) = children.configure(closure)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue