Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[console] Pre check plugin duplication & console requirement #2703

Merged
merged 10 commits into from
Jul 26, 2023
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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")
}
) {

}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
@@ -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 ]"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -88,6 +89,8 @@ internal class PluginManagerImpl(
}
}
}

resolvedPlugins.add(MiraiConsoleAsPlugin)
}

// region LOADING
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ public interface PluginDescription {
/**
* 此插件依赖的其他插件, 将会在这些插件加载之后加载此插件
*
* 特别的, 可以使用 `net.mamoe.mirai-console` 作为插件 id 限制 mirai-console 版本 (自 2.16.0 后)
*
* @see PluginDependency
*/
public val dependencies: Set<PluginDependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}