Support launch dev console in idea (#2058)

* Support launch dev console in idea

* Update idea project creator templates

* document update
This commit is contained in:
微莹·纤绫 2022-06-07 00:09:58 +08:00 committed by GitHub
parent d9c1da275b
commit b2c895bc2b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 133 additions and 53 deletions

View File

@ -584,7 +584,34 @@ Central
要了解什么情况下需要强制打包,请参阅 [插件依赖打包机制](#插件依赖打包机制)。 要了解什么情况下需要强制打包,请参阅 [插件依赖打包机制](#插件依赖打包机制)。
### 发布插件到 mirai-console-loader ## 调试
[mirai-console-gradle](../../tools/gradle-plugin/README.md)
提供了在 IDEA 等 IDE 中调试插件的功能, 运行 Gradle 任务 `runConsole` 即可启动完整的 mirai-console。
> mirai-console 测试时默认在 `/debug-sandbox` 运行。
>
> 可在 `.gitignore` 中添加 `/debug-sandbox` 规则以避免测试环境被提交至 Git。
使用 IDEA 创建的项目可在 `Run Configurations` 找到 `Run Mirai Console`
![PluginDebugRunConfiguration.png](images/PluginDebugRunConfiguration.png)
可在 IDEA 右侧 `Gradle` 中找到 Gradle 任务 `runConsole`
![PluginDebugGradleTask.png](images/PluginDebugGradleTask.png)
运行后即可看见如下图所示的 mirai-console:
![PluginDebugWindowPreview](images/PluginDebugWindowPreview.webp)
> 如需进行调试, 请使用运行 (绿色三角形) 旁边的 `Debug` 按钮.
> 也可以在 Gradle 工具栏找到 `runConsole` 并右键选择 `Debug`
>
> 如果没法输入命令, 请确认 Gradle 任务视图没有被聚焦至 `:runConsole`,
> 必须选择整个 Gradle 任务视图才可执行命令。
## 发布插件到 mirai-console-loader
插件中心仍在开发中。 插件中心仍在开发中。

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

View File

@ -18,6 +18,7 @@ import org.gradle.api.JavaVersion
import org.gradle.api.XmlProvider import org.gradle.api.XmlProvider
import org.gradle.api.plugins.PluginContainer import org.gradle.api.plugins.PluginContainer
import org.gradle.api.publish.maven.MavenPublication import org.gradle.api.publish.maven.MavenPublication
import org.gradle.api.tasks.JavaExec
/** /**
* ``` * ```
@ -90,8 +91,18 @@ public open class MiraiConsoleExtension {
*/ */
public var dontConfigureKotlinJvmDefault: Boolean = false public var dontConfigureKotlinJvmDefault: Boolean = false
/**
* 配置 gradle task runConsole. 将此项设置为 `false` 时不会配置测试环境
*/
public var consoleTestRuntime: Boolean = true
internal val shadowConfigurations: MutableList<ShadowJar.() -> Unit> = mutableListOf() internal val shadowConfigurations: MutableList<ShadowJar.() -> Unit> = mutableListOf()
internal val excludedDependencies: MutableSet<ExcludedDependency> = mutableSetOf() internal val excludedDependencies: MutableSet<ExcludedDependency> = mutableSetOf()
internal val consoleTestRuntimeConf: MutableList<JavaExec.() -> Unit> = mutableListOf()
public fun setupConsoleTestRuntime(configure: JavaExec.() -> Unit) {
consoleTestRuntimeConf.add(configure)
}
internal data class ExcludedDependency( internal data class ExcludedDependency(
val group: String, val group: String,

View File

@ -16,8 +16,12 @@ import com.github.jengelman.gradle.plugins.shadow.ShadowPlugin
import com.jfrog.bintray.gradle.BintrayPlugin import com.jfrog.bintray.gradle.BintrayPlugin
import org.gradle.api.Plugin import org.gradle.api.Plugin
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.attributes.Attribute
import org.gradle.api.attributes.Usage
import org.gradle.api.plugins.JavaPlugin import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.plugins.JavaPluginExtension import org.gradle.api.plugins.JavaPluginExtension
import org.gradle.api.tasks.JavaExec
import org.gradle.api.tasks.compile.JavaCompile import org.gradle.api.tasks.compile.JavaCompile
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
@ -33,6 +37,7 @@ public class MiraiConsoleGradlePlugin : Plugin<Project> {
public companion object { public companion object {
internal const val MIRAI_SHADOW_CONF_NAME: String = "shadowLink" internal const val MIRAI_SHADOW_CONF_NAME: String = "shadowLink"
internal const val MIRAI_AS_NORMAL_DEP_CONF_NAME: String = "asNormalDep" internal const val MIRAI_AS_NORMAL_DEP_CONF_NAME: String = "asNormalDep"
internal const val MIRAI_DIRECT_RUN_CONSOLE_CONF_NAME: String = "testConsoleRuntime"
public const val FILE_SUFFIX: String = "mirai.jar" public const val FILE_SUFFIX: String = "mirai.jar"
} }
@ -112,9 +117,11 @@ public class MiraiConsoleGradlePlugin : Plugin<Project> {
} }
} }
private fun Project.registerBuildPluginTasks() { private fun Project.registerGradleTasks() {
val miraiExtension = this.miraiExtension val miraiExtension = this.miraiExtension
// Array<String>: [jar name, jar extension]
val buildPluginTasks = mutableListOf<Pair<Task, Array<String>>>()
tasks.findByName("shadowJar")?.enabled = false tasks.findByName("shadowJar")?.enabled = false
fun registerBuildPluginTask(target: KotlinTarget, isSingleTarget: Boolean) { fun registerBuildPluginTask(target: KotlinTarget, isSingleTarget: Boolean) {
@ -131,6 +138,7 @@ public class MiraiConsoleGradlePlugin : Plugin<Project> {
buildPluginV2.destinationDirectory.value( buildPluginV2.destinationDirectory.value(
project.layout.projectDirectory.dir(project.buildDir.name).dir("mirai") project.layout.projectDirectory.dir(project.buildDir.name).dir("mirai")
) )
buildPluginTasks.add(buildPluginV2 to arrayOf(project.name + "-dev", BuildMiraiPluginV2.FILE_SUFFIX))
} }
tasks.create( tasks.create(
"buildPluginLegacy".wrapNameWithPlatform(target, isSingleTarget), "buildPluginLegacy".wrapNameWithPlatform(target, isSingleTarget),
@ -172,11 +180,75 @@ public class MiraiConsoleGradlePlugin : Plugin<Project> {
targets.forEach { target -> targets.forEach { target ->
registerBuildPluginTask(target, isSingleTarget) registerBuildPluginTask(target, isSingleTarget)
} }
if (miraiExtension.consoleTestRuntime) {
dependencies.add(
MIRAI_DIRECT_RUN_CONSOLE_CONF_NAME,
"net.mamoe:mirai-core-api:${miraiExtension.coreVersion}"
)
dependencies.add(
MIRAI_DIRECT_RUN_CONSOLE_CONF_NAME,
"net.mamoe:mirai-core:${miraiExtension.coreVersion}"
)
dependencies.add(
MIRAI_DIRECT_RUN_CONSOLE_CONF_NAME,
"net.mamoe:mirai-console:${miraiExtension.consoleVersion}"
)
val frontendDep = when (miraiExtension.useTestConsoleFrontEnd) {
MiraiConsoleFrontEndKind.TERMINAL -> "net.mamoe:mirai-console-terminal:${miraiExtension.consoleVersion}"
null -> null
}
if (frontendDep != null) {
dependencies.add(MIRAI_DIRECT_RUN_CONSOLE_CONF_NAME, frontendDep)
}
tasks.register("runConsole", JavaExec::class.java) { runConsole ->
runConsole.group = "mirai"
runConsole.classpath += configurations.getByName(MIRAI_DIRECT_RUN_CONSOLE_CONF_NAME)
runConsole.mainClass.set(
when (miraiExtension.useTestConsoleFrontEnd) {
MiraiConsoleFrontEndKind.TERMINAL -> "net.mamoe.mirai.console.terminal.MiraiConsoleTerminalLoader"
null -> "ERROR_mirai_console_frontend_not_found"
}
)
// default runs on $projectDir/debug-sandbox
runConsole.workingDir = project.projectDir.resolve("debug-sandbox")
runConsole.doFirst {
// working dir can be changed by user
val plugins = runConsole.workingDir.resolve("plugins")
plugins.mkdirs()
buildPluginTasks.forEach { (buildPluginTask, jarNameMetadata) ->
val (jarName, jarSuffix) = jarNameMetadata
buildPluginTask.outputs.files.files.forEachIndexed { index, outFile ->
val name = jarName + if (index == 0) {
""
} else {
"-$index"
} + '.' + jarSuffix
outFile.copyTo(plugins.resolve(name), overwrite = true)
}
}
}
runConsole.standardInput = System.`in`
buildPluginTasks.forEach { runConsole.dependsOn(it.first) }
miraiExtension.consoleTestRuntimeConf.forEach { it.invoke(runConsole) }
}
}
} }
private fun Project.setupConfigurations() { private fun Project.setupConfigurations() {
configurations.create(MIRAI_SHADOW_CONF_NAME).isCanBeResolved = false configurations.create(MIRAI_SHADOW_CONF_NAME).isCanBeResolved = false
configurations.create(MIRAI_AS_NORMAL_DEP_CONF_NAME).isCanBeResolved = false configurations.create(MIRAI_AS_NORMAL_DEP_CONF_NAME).isCanBeResolved = false
configurations.create(MIRAI_DIRECT_RUN_CONSOLE_CONF_NAME).let { runConsoleConf ->
runConsoleConf.attributes { ac ->
fun attribute(key: String, value: String) {
ac.attribute(Attribute.of(key, String::class.java), value)
}
attribute("org.jetbrains.kotlin.platform.type", "jvm")
ac.attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage::class.java, Usage.JAVA_RUNTIME))
}
}
} }
override fun apply(target: Project): Unit = with(target) { override fun apply(target: Project): Unit = with(target) {
@ -193,7 +265,7 @@ public class MiraiConsoleGradlePlugin : Plugin<Project> {
afterEvaluate { afterEvaluate {
configureCompileTarget() configureCompileTarget()
kotlinTargets.forEach { configureTarget(it) } kotlinTargets.forEach { configureTarget(it) }
registerBuildPluginTasks() registerGradleTasks()
configurePublishing() configurePublishing()
} }
} }

View File

@ -1,25 +0,0 @@
package $PACKAGE_NAME
import net.mamoe.mirai.alsoLogin
import net.mamoe.mirai.console.MiraiConsole
import net.mamoe.mirai.console.plugin.PluginManager.INSTANCE.enable
import net.mamoe.mirai.console.plugin.PluginManager.INSTANCE.load
import net.mamoe.mirai.console.terminal.MiraiConsoleTerminalLoader
import java.io.File
import java.util.Properties
suspend fun main() {
MiraiConsoleTerminalLoader.startAsDaemon()
val pluginInstance = ${CLASS_NAME}#if (${LANGUAGE_TYPE} != "Kotlin").INSTANCE #end
pluginInstance.load() // 主动加载插件, Console 会调用 ${CLASS_NAME}.onLoad
pluginInstance.enable() // 主动启用插件, Console 会调用 ${CLASS_NAME}.onEnable
val properties = Properties().apply { File("account.properties").inputStream().use { load(it) } }
val bot = MiraiConsole.addBot(properties.getProperty("id").toLong(), properties.getProperty("password")).alsoLogin() // 登录一个测试环境的 Bot
MiraiConsole.job.join()
}

View File

@ -1,14 +0,0 @@
<!--
~ Copyright 2019-2022 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
-->
<html>
<body>
<p>This is a built-in file template used to create a new settings.gradle.kts for Mirai Console Plugin projects.</p>
</body>
</html>

View File

@ -1,11 +1,23 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="RunTerminal" type="JetRunConfigurationType" nameIsGenerated="false"> <configuration default="false" name="Run Mirai Console" type="GradleRunConfiguration" factoryName="Gradle" folderName="Mirai">
<option name="MAIN_CLASS_NAME" value="${PACKAGE_NAME}.RunTerminalKt"/> <ExternalSystemSettings>
<module name="${MODULE_NAME}.test"/> <option name="executionName" />
<shortenClasspath name="NONE"/> <option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/debug-sandbox"/> <option name="externalSystemIdString" value="GRADLE" />
<method v="2"> <option name="scriptParameters" value="" />
<option name="Make" enabled="true"/> <option name="taskDescriptions">
</method> <list />
</option>
<option name="taskNames">
<list>
<option value=":runConsole" />
</list>
</option>
<option name="vmOptions" />
</ExternalSystemSettings>
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
<DebugAllEnabled>false</DebugAllEnabled>
<method v="2" />
</configuration> </configuration>
</component> </component>

View File

@ -35,7 +35,6 @@ object FT { // file template
const val Gitignore = ".gitignore" const val Gitignore = ".gitignore"
const val RunTerminal = "RunTerminal.kt"
const val RunTerminalRun = "RunTerminal.run.xml" const val RunTerminalRun = "RunTerminal.run.xml"
const val AccountProperties = "account.properties" const val AccountProperties = "account.properties"
} }

View File

@ -30,7 +30,6 @@ class FileTemplateRegistrar : com.intellij.ide.fileTemplates.FileTemplateGroupDe
addTemplate(FileTemplateDescriptor(FT.Gitignore)) addTemplate(FileTemplateDescriptor(FT.Gitignore))
addTemplate(FileTemplateDescriptor(FT.RunTerminal))
addTemplate(FileTemplateDescriptor(FT.RunTerminalRun)) addTemplate(FileTemplateDescriptor(FT.RunTerminalRun))
} }
} }

View File

@ -43,7 +43,6 @@ sealed class GradleProjectCreator(
collect(GeneratorTemplateFile(".gitignore", getTemplate(FT.Gitignore))) collect(GeneratorTemplateFile(".gitignore", getTemplate(FT.Gitignore)))
collect(GeneratorTemplateFile("gradle.properties", getTemplate(FT.GradleProperties))) collect(GeneratorTemplateFile("gradle.properties", getTemplate(FT.GradleProperties)))
collect(GeneratorTemplateFile("src/test/kotlin/RunTerminal.kt", getTemplate(FT.RunTerminal)))
} }
} }