mirror of
https://github.com/mamoe/mirai.git
synced 2025-03-12 14:00:12 +08:00
[console] Pre check plugin duplication & console requirement (#2703)
* feat: check in load plugin * feat: console requirement * feat: dependsOn mirai * feat: dependsOn docs * fix: docs * use: net.mamoe.mirai-console * revert * [console] Wrap mirai-console as a plugin * [console] Fix plugin dependencies checking skipped already loaded plugins * [console/tests] Check plugin can depends on mirai-console --------- Co-authored-by: Karlatemp <kar@kasukusakura.com>
This commit is contained in:
parent
5ace423f2a
commit
7daf2d56bc
@ -0,0 +1,10 @@
|
||||
#
|
||||
# Copyright 2019-2023 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/dev/LICENSE
|
||||
#
|
||||
|
||||
net.mamoe.console.itest.plugincandependsonmiraiconsole.PluginCanDependsOnMiraiConsole
|
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2019-2023 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/dev/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.console.itest.plugincandependsonmiraiconsole
|
||||
|
||||
import net.mamoe.mirai.console.plugin.jvm.JvmPluginDescription
|
||||
import net.mamoe.mirai.console.plugin.jvm.KotlinPlugin
|
||||
|
||||
internal object PluginCanDependsOnMiraiConsole : KotlinPlugin(
|
||||
JvmPluginDescription("net.mamoe.tester.plugin-can-depends-mirai-console", "1.0.0") {
|
||||
dependsOn("net.mamoe.mirai-console")
|
||||
}
|
||||
) {
|
||||
|
||||
}
|
@ -39,6 +39,7 @@ import net.mamoe.mirai.console.internal.extension.GlobalComponentStorage
|
||||
import net.mamoe.mirai.console.internal.permission.BuiltInPermissionService
|
||||
import net.mamoe.mirai.console.internal.permission.getPermittedPermissionsAndSource
|
||||
import net.mamoe.mirai.console.internal.plugin.JvmPluginInternal
|
||||
import net.mamoe.mirai.console.internal.plugin.MiraiConsoleAsPlugin
|
||||
import net.mamoe.mirai.console.internal.pluginManagerImpl
|
||||
import net.mamoe.mirai.console.internal.util.runIgnoreException
|
||||
import net.mamoe.mirai.console.permission.Permission
|
||||
@ -633,10 +634,15 @@ public object BuiltInCommands {
|
||||
reset().append("\n\n")
|
||||
|
||||
append("Plugins: ")
|
||||
if (MiraiConsole.pluginManagerImpl.resolvedPlugins.isEmpty()) {
|
||||
|
||||
val resolvedPlugins = MiraiConsole.pluginManagerImpl.resolvedPlugins.asSequence()
|
||||
.filter { it !is MiraiConsoleAsPlugin } // skip mirai-console in status
|
||||
.toList()
|
||||
|
||||
if (resolvedPlugins.isEmpty()) {
|
||||
gray().append("<none>")
|
||||
} else {
|
||||
MiraiConsole.pluginManagerImpl.resolvedPlugins.joinTo(this) { plugin ->
|
||||
resolvedPlugins.joinTo(this) { plugin ->
|
||||
if (plugin.isEnabled) {
|
||||
green().append(plugin.name).reset().append(" v").gold()
|
||||
} else {
|
||||
|
@ -287,7 +287,7 @@ internal class BuiltInJvmPluginLoaderImpl(
|
||||
return filePlugins.toSet().map { it.second }
|
||||
}
|
||||
|
||||
private val loadedPlugins = ConcurrentHashMap<JvmPlugin, Unit>()
|
||||
private val loadedPlugins = ConcurrentHashMap<String, JvmPlugin>()
|
||||
|
||||
private fun Path.moveNameFolder(plugin: JvmPlugin) {
|
||||
val nameFolder = this.resolve(plugin.description.name).toFile()
|
||||
@ -324,8 +324,8 @@ internal class BuiltInJvmPluginLoaderImpl(
|
||||
override fun load(plugin: JvmPlugin) {
|
||||
ensureActive()
|
||||
|
||||
if (loadedPlugins.put(plugin, Unit) != null) {
|
||||
error("Plugin '${plugin.name}' is already loaded and cannot be reloaded.")
|
||||
if (loadedPlugins.put(plugin.id, plugin) != null) {
|
||||
error("Plugin '${plugin.id}' is already loaded and cannot be reloaded.")
|
||||
}
|
||||
logger.verbose { "Loading plugin ${plugin.description.smartToString()}" }
|
||||
runCatching {
|
||||
|
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2019-2023 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/dev/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.console.internal.plugin
|
||||
|
||||
import net.mamoe.mirai.console.command.ConsoleCommandOwner
|
||||
import net.mamoe.mirai.console.internal.MiraiConsoleBuildConstants
|
||||
import net.mamoe.mirai.console.permission.Permission
|
||||
import net.mamoe.mirai.console.permission.PermissionId
|
||||
import net.mamoe.mirai.console.plugin.Plugin
|
||||
import net.mamoe.mirai.console.plugin.PluginManager.INSTANCE.description
|
||||
import net.mamoe.mirai.console.plugin.description.PluginDependency
|
||||
import net.mamoe.mirai.console.plugin.description.PluginDescription
|
||||
import net.mamoe.mirai.console.plugin.loader.PluginLoader
|
||||
import net.mamoe.mirai.console.util.SemVersion
|
||||
|
||||
internal object MiraiConsoleAsPlugin : Plugin {
|
||||
// MiraiConsole always enabled
|
||||
override val isEnabled: Boolean get() = true
|
||||
|
||||
override val loader: PluginLoader<*, *> get() = TheLoader
|
||||
|
||||
override val parentPermission: Permission
|
||||
get() = ConsoleCommandOwner.parentPermission
|
||||
|
||||
override fun permissionId(name: String): PermissionId {
|
||||
return ConsoleCommandOwner.permissionId(name)
|
||||
}
|
||||
|
||||
internal object TheLoader : PluginLoader<Plugin, PluginDescription> {
|
||||
override fun listPlugins(): List<Plugin> = listOf(MiraiConsoleAsPlugin)
|
||||
|
||||
override fun disable(plugin: Plugin) {
|
||||
// noop
|
||||
}
|
||||
|
||||
override fun enable(plugin: Plugin) {
|
||||
// noop
|
||||
}
|
||||
|
||||
override fun load(plugin: Plugin) {
|
||||
// noop
|
||||
}
|
||||
|
||||
override fun getPluginDescription(plugin: Plugin): PluginDescription {
|
||||
if (plugin !== MiraiConsoleAsPlugin) {
|
||||
error("loader not match with " + plugin.description.id)
|
||||
}
|
||||
return TheDescription
|
||||
}
|
||||
}
|
||||
|
||||
internal object TheDescription : PluginDescription {
|
||||
override val id: String get() = "net.mamoe.mirai-console"
|
||||
override val name: String get() = "Console"
|
||||
override val author: String get() = "Mamoe Technologies"
|
||||
override val version: SemVersion get() = MiraiConsoleBuildConstants.version
|
||||
override val info: String get() = ""
|
||||
override val dependencies: Set<PluginDependency> get() = setOf()
|
||||
|
||||
|
||||
override fun toString(): String {
|
||||
return "PluginDescription[ mirai-console ]"
|
||||
}
|
||||
}
|
||||
}
|
@ -20,6 +20,7 @@ import net.mamoe.mirai.console.internal.extension.GlobalComponentStorage
|
||||
import net.mamoe.mirai.console.plugin.NotYetLoadedPlugin
|
||||
import net.mamoe.mirai.console.plugin.Plugin
|
||||
import net.mamoe.mirai.console.plugin.PluginManager
|
||||
import net.mamoe.mirai.console.plugin.PluginManager.INSTANCE.description
|
||||
import net.mamoe.mirai.console.plugin.PluginManager.INSTANCE.safeLoader
|
||||
import net.mamoe.mirai.console.plugin.description.PluginDependency
|
||||
import net.mamoe.mirai.console.plugin.description.PluginDescription
|
||||
@ -88,6 +89,8 @@ internal class PluginManagerImpl(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resolvedPlugins.add(MiraiConsoleAsPlugin)
|
||||
}
|
||||
|
||||
// region LOADING
|
||||
@ -207,6 +210,8 @@ internal class PluginManagerImpl(
|
||||
|
||||
@Throws(PluginResolutionException::class)
|
||||
private fun <D : PluginDescription> List<D>.sortByDependencies(): List<D> {
|
||||
val alreadyLoadedPlugins = resolvedPlugins.asSequence().map { it.description }.toList() // snapshot
|
||||
|
||||
val originPluginDescriptions = this@sortByDependencies
|
||||
val pending2BeResolved = originPluginDescriptions.toMutableList()
|
||||
val resolved = ArrayList<D>(pending2BeResolved.size)
|
||||
@ -252,6 +257,8 @@ internal class PluginManagerImpl(
|
||||
pending2BeResolved.forEach { pluginDesc ->
|
||||
val missed = pluginDesc.dependencies.filter { dependency ->
|
||||
val resolvedDep = originPluginDescriptions.findDependency(dependency)
|
||||
?: alreadyLoadedPlugins.findDependency(dependency)
|
||||
|
||||
if (resolvedDep != null) {
|
||||
resolvedDep.checkSatisfies(dependency, pluginDesc)
|
||||
false
|
||||
|
@ -104,6 +104,8 @@ public interface PluginDescription {
|
||||
/**
|
||||
* 此插件依赖的其他插件, 将会在这些插件加载之后加载此插件
|
||||
*
|
||||
* 特别的, 可以使用 `net.mamoe.mirai-console` 作为插件 id 限制 mirai-console 版本 (自 2.16.0 后)
|
||||
*
|
||||
* @see PluginDependency
|
||||
*/
|
||||
public val dependencies: Set<PluginDependency>
|
||||
|
@ -18,11 +18,11 @@ class FrameworkInstanceTest : AbstractConsoleInstanceTest() {
|
||||
|
||||
@Test
|
||||
fun testConsole1() {
|
||||
assertEquals(0, PluginManager.plugins.size)
|
||||
assertEquals(1, PluginManager.plugins.size)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testConsole2() {
|
||||
assertEquals(0, PluginManager.plugins.size)
|
||||
assertEquals(1, PluginManager.plugins.size)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user