diff --git a/backend/mirai-console/build.gradle.kts b/backend/mirai-console/build.gradle.kts index 34f722ff1..3a056e285 100644 --- a/backend/mirai-console/build.gradle.kts +++ b/backend/mirai-console/build.gradle.kts @@ -66,12 +66,14 @@ kotlin { dependencies { compileAndRuntime("net.mamoe:mirai-core:${Versions.core}") - compileAndRuntime(kotlin("stdlib", Versions.kotlinStdlib)) + compileAndRuntime(kotlin("stdlib-jdk8", Versions.kotlinStdlib)) api("net.mamoe.yamlkt:yamlkt:0.3.1") api("org.jetbrains:annotations:19.0.0") api(kotlinx("coroutines-jdk8", Versions.coroutines)) + api("com.vdurmont:semver4j:3.1.0") + testApi("net.mamoe:mirai-core-qqandroid:${Versions.core}") testApi(kotlin("stdlib-jdk8")) testApi(kotlin("test")) @@ -80,6 +82,7 @@ dependencies { testImplementation("org.junit.jupiter:junit-jupiter-api:5.2.0") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.2.0") } + ext.apply { // 傻逼 compileAndRuntime 没 exclude 掉 // 傻逼 gradle 第二次配置 task 会覆盖掉第一次的配置 @@ -109,9 +112,11 @@ tasks { file.writeText(file.readText() .replace(Regex("""val buildDate: Date = Date\((.*)\) //(.*)""")) { """ - val buildDate: Date = Date(${System.currentTimeMillis()}L) // ${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").apply { - timeZone = TimeZone.getTimeZone("GMT+8") - }.format(Date())} + val buildDate: Date = Date(${System.currentTimeMillis()}L) // ${ + SimpleDateFormat("yyyy-MM-dd HH:mm:ss").apply { + timeZone = TimeZone.getTimeZone("GMT+8") + }.format(Date()) + } """.trimIndent() } .replace(Regex("""const val version: String = "(.*)"""")) { diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/MiraiConsole.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/MiraiConsole.kt index 563b447ce..ebb265e47 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/MiraiConsole.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/MiraiConsole.kt @@ -105,8 +105,8 @@ internal object MiraiConsoleInitializer { internal object MiraiConsoleBuildConstants { // auto-filled on build (task :mirai-console:fillBuildConstants) @JvmStatic - val buildDate: Date = Date(1594475138828L) // 2020-07-11 21:45:38 - const val version: String = "1.0-dev-3" + val buildDate: Date = Date(1595136353901L) // 2020-07-19 13:25:53 + const val version: String = "1.0-dev-4" } /** diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/description.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/description.kt index bad00afbe..76775f09c 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/description.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/description.kt @@ -9,10 +9,12 @@ package net.mamoe.mirai.console.plugin +import com.vdurmont.semver4j.Semver import kotlinx.serialization.KSerializer import kotlinx.serialization.Serializable import kotlinx.serialization.builtins.serializer import net.mamoe.mirai.console.setting.internal.map +import net.mamoe.mirai.console.utils.SemverAsStringSerializerIvy import net.mamoe.yamlkt.Yaml import net.mamoe.yamlkt.YamlDynamicSerializer import java.io.File @@ -45,7 +47,7 @@ public interface PluginDescription { public val name: String public val author: String - public val version: String + public val version: Semver public val info: String /** 此插件依赖的其他插件, 将会在这些插件加载之后加载此插件 */ @@ -59,42 +61,21 @@ public data class PluginDependency( public val name: String, /** * 依赖版本号. 为 null 时则为不限制版本. + * + * 版本遵循 [语义化版本 2.0 规范](https://semver.org/lang/zh-CN/), + * + * 允许 [Apache Ivy 格式版本号](http://ant.apache.org/ivy/history/latest-milestone/ivyfile/dependency.html) + * * @see versionKind 版本号类型 */ - public val version: String? = null, - /** 版本号类型 */ - public val versionKind: VersionKind = VersionKind.AT_LEAST, + public val version: @Serializable(SemverAsStringSerializerIvy::class) Semver? = null, /** * 若为 `false`, 插件在找不到此依赖时也能正常加载. */ public val isOptional: Boolean = false ) { - /** 版本号类型 */ - @Serializable(with = VersionKind.AsStringSerializer::class) - public enum class VersionKind( - private vararg val serialNames: String - ) { - /** 要求依赖精确的版本 */ - EXACT("exact"), - - /** 要求依赖最低版本 */ - AT_LEAST("at_least", "AtLeast", "least", "lowest", "+"), - - /** 要求依赖最高版本 */ - AT_MOST("at_most", "AtMost", "most", "highest", "-"); - - public object AsStringSerializer : KSerializer by String.serializer().map( - serializer = { it.serialNames.first() }, - deserializer = { str -> - values().firstOrNull { - it.serialNames.any { name -> name.equals(str, ignoreCase = true) } - } ?: AT_LEAST - } - ) - } - public override fun toString(): String { - return "$name ${versionKind.toEnglishString()}v$version" + return "$name v$version" } @@ -118,9 +99,3 @@ public data class PluginDependency( public interface FilePluginDescription : PluginDescription { public val file: File } - -internal fun PluginDependency.VersionKind.toEnglishString(): String = when (this) { - PluginDependency.VersionKind.EXACT -> "" - PluginDependency.VersionKind.AT_LEAST -> "at least " - PluginDependency.VersionKind.AT_MOST -> "at most " -} diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JarPluginLoader.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JarPluginLoader.kt index 8cd48173c..70387e446 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JarPluginLoader.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JarPluginLoader.kt @@ -89,7 +89,11 @@ internal object JarPluginLoaderImpl : override fun load(description: JvmPluginDescription): JvmPlugin = description.runCatching { ensureActive() - val main = classLoader.loadPluginMainClassByJarFile(name, mainClassName, file).kotlin.run { + val main = classLoader.loadPluginMainClassByJarFile( + pluginName = name, + mainClass = mainClassName, + jarFile = file + ).kotlin.run { objectInstance ?: kotlin.runCatching { createInstance() }.getOrNull() ?: (java.constructors + java.declaredConstructors) diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JvmPluginDescription.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JvmPluginDescription.kt index fb217ffb3..e084b5fa8 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JvmPluginDescription.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JvmPluginDescription.kt @@ -9,6 +9,7 @@ package net.mamoe.mirai.console.plugin.jvm +import com.vdurmont.semver4j.Semver import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import kotlinx.serialization.Transient @@ -16,6 +17,7 @@ import net.mamoe.mirai.console.plugin.FilePluginDescription import net.mamoe.mirai.console.plugin.PluginDependency import net.mamoe.mirai.console.plugin.PluginDescription import net.mamoe.mirai.console.plugin.PluginKind +import net.mamoe.mirai.console.utils.SemverAsStringSerializerLoose import java.io.File @Serializable @@ -25,7 +27,7 @@ public class JvmPluginDescription internal constructor( @SerialName("main") public val mainClassName: String, public override val author: String = "", - public override val version: String, + public override val version: @Serializable(with = SemverAsStringSerializerLoose::class) Semver, public override val info: String = "", @SerialName("depends") public override val dependencies: List<@Serializable(with = PluginDependency.SmartSerializer::class) PluginDependency> = listOf() @@ -37,7 +39,7 @@ public class JvmPluginDescription internal constructor( @Suppress("unused") public constructor( kind: PluginKind, name: String, mainClassName: String, author: String, - version: String, info: String, depends: List, + version: Semver, info: String, depends: List, file: File ) : this(kind, name, mainClassName, author, version, info, depends) { this._file = file diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/utils/SemverAsStringSerializer.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/utils/SemverAsStringSerializer.kt new file mode 100644 index 000000000..62c3c5a54 --- /dev/null +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/utils/SemverAsStringSerializer.kt @@ -0,0 +1,28 @@ +/* + * 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.utils + +import com.vdurmont.semver4j.Semver +import kotlinx.serialization.KSerializer +import kotlinx.serialization.Serializer +import kotlinx.serialization.builtins.serializer +import net.mamoe.mirai.console.setting.internal.map + +@Serializer(forClass = Semver::class) +internal object SemverAsStringSerializerLoose : KSerializer by String.serializer().map( + serializer = { it.toString() }, + deserializer = { Semver(it, Semver.SemverType.LOOSE) } +) + +@Serializer(forClass = Semver::class) +internal object SemverAsStringSerializerIvy : KSerializer by String.serializer().map( + serializer = { it.toString() }, + deserializer = { Semver(it, Semver.SemverType.IVY) } +) \ No newline at end of file