Merge remote-tracking branch 'origin/master' into command

This commit is contained in:
Karlatemp 2020-09-20 09:24:24 +08:00
commit b77a856ebe
No known key found for this signature in database
GPG Key ID: 21FBDDF664FF06F8
25 changed files with 946 additions and 390 deletions

63
.github/workflows/Publishing.yml vendored Normal file
View File

@ -0,0 +1,63 @@
# This is a basic workflow to help you get started with Actions
name: Bintray Publish
# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
on:
release:
types:
- created
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Gradle clean
run: ./gradlew clean
- name: Gradle build
run: ./gradlew build # if test's failed, don't publish
- name: Check keys
run: ./gradlew
:mirai-console:ensureBintrayAvailable
-Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }}
-Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}
- name: Gradle :mirai-console:fillBuildConstants
run: ./gradlew
:mirai-console:fillBuildConstants
-Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }}
-Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}
- name: Gradle :mirai-console:bintrayUpload
run: ./gradlew
:mirai-console:bintrayUpload
-Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }}
-Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}
- name: Gradle :mirai-console-terminal:bintrayUpload
run: ./gradlew
:mirai-console-terminal:bintrayUpload
-Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }}
-Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}
- name: Gradle :mirai-console-compiler-common:bintrayUpload
run: ./gradlew
:mirai-console-compiler-common:bintrayUpload
-Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }}
-Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}
- name: Gradle :mirai-console-intellij:bintrayUpload
run: ./gradlew
:mirai-console-intellij:bintrayUpload
-Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }}
-Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}
- name: Publish Gradle plugin
run: ./gradlew
:mirai-console-gradle:publishPlugins
-Dgradle.publish.key=${{ secrets.GRADLE_PUBLISH_KEY }} -Pgradle.publish.key=${{ secrets.GRADLE_PUBLISH_KEY }}
-Dgradle.publish.secret=${{ secrets.GRADLE_PUBLISH_SECRET }} -Pgradle.publish.secret=${{ secrets.GRADLE_PUBLISH_SECRET }}

View File

@ -1,37 +0,0 @@
# This is a basic workflow to help you get started with Actions
name: Bintray Publish
# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
on:
release:
types:
- created
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Gradle clean
run: ./gradlew clean
- name: Gradle build
run: ./gradlew build # if test's failed, don't publish
- name: Check keys
run: ./gradlew :mirai-console:ensureBintrayAvailable -Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }} -Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}
- name: Gradle :mirai-console:fillBuildConstants
run: ./gradlew :mirai-console:fillBuildConstants -Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }} -Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}
- name: Gradle :mirai-console:bintrayUpload
run: ./gradlew :mirai-console:bintrayUpload -Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }} -Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}
- name: Gradle :mirai-console-terminal:bintrayUpload
run: ./gradlew :mirai-console-terminal:bintrayUpload -Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }} -Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}

View File

@ -15,63 +15,32 @@ Mirai 是一个在全平台下运行,提供 QQ 协议支持的高效率机器
# mirai-console # mirai-console
高效率插件支持 QQ 机器人框架, 机器人核心来自 [mirai](https://github.com/mamoe/mirai) 高效率 QQ 机器人框架,机器人核心来自 [mirai](https://github.com/mamoe/mirai)
## 模块说明 ![Gradle CI](https://github.com/mamoe/mirai-console/workflows/Gradle%20CI/badge.svg?branch=master)
[![Gitter](https://badges.gitter.im/mamoe/mirai.svg)](https://gitter.im/mamoe/mirai?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
console 由后端和前端一起工作. 使用时必须选择一个前端. ## 开发
- `mirai-console`: console 的后端, 包含插件管理, 指令系统, 配置系统. - **[准备工作 - 环境和前置知识](docs/Preparations.md)**
- **[配置项目](docs/ConfiguringProjects.md)**
- **[启动 Console](docs/Run.md)**
### 后端插件开发基础
- 插件 - [Plugin 模块](docs/Plugins.md)
- 指令 - [Command 模块](docs/Commands.md)
- 存储 - [PluginData 模块](docs/PluginData.md)
- 权限 - [Permission 模块](docs/Permissions.md)
**示例插件**
- [mirai-console-example-plugin (Kotlin DSL)](https://github.com/Him188/mirai-console-example-plugin)
- [mirai-console-example-plugin (Groovy DSL)](https://github.com/Karlatemp/mirai-console-example-plugin)
前端: ### 后端插件开发进阶
- `mirai-console-terminal`: console 的 Unix 终端界面前端. - 扩展 - [Extension 模块和扩展点](docs/Extensions.md)
- `mirai-console-graphical`: console 的 JavaFX 图形化界面前端. (开发中)
**注意:`mirai-console` 1.0-RC 发布之前, 前端请使用 `mirai-console-pure` 而不是 `mirai-console-terminal`** ### 实现前端
- [FrontEnd](docs/FrontEnd.md)
**注意:`mirai-console` 后端和 terminal 前端正在进行完全的重构, 所有 API 都不具有稳定性**
### 版本
[Version]: https://api.bintray.com/packages/him188moe/mirai/mirai-console/images/download.svg?
[Bintray Download]: https://bintray.com/him188moe/mirai/mirai-console/
详见 [版本规范](docs/README.md#版本规范)
| 版本类型 | 版本号 |
|:------:|:------------:|
| 稳定 | - |
| 预览 | 1.0-M4 |
| 开发 | [![Version]][Bintray Download] |
### 使用
**查看示例插件**: [mirai-console-example-plugin](https://github.com/Him188/mirai-console-example-plugin)
正在更新中的文档:[参考文档](docs/README.md)
#### Gradle
`CORE_VERSION`: [ ![Download](https://api.bintray.com/packages/him188moe/mirai/mirai-core/images/download.svg?) ](https://bintray.com/him188moe/mirai/mirai-core/)
build.gradle.kts
```kotlin
repositories {
jcenter()
}
dependencies {
implementation("net.mamoe:mirai-core:$CORE_VERSION") // mirai-core 的 API
implementation("net.mamoe:mirai-console:$CONSOLE_VERSION") // 后端
testImplementation("net.mamoe:mirai-console-terminal:$CONSOLE_VERSION") // 前端, 用于启动测试
}
```
**注意:`mirai-console` 1.0-RC 发布之前, 前端请使用 `mirai-console-pure` 而不是 `mirai-console-terminal`**
#### Maven
同理 Gradle

View File

@ -56,50 +56,28 @@ kotlin {
} }
dependencies { dependencies {
implementation("net.mamoe:mirai-core:${Versions.core}") compileAndTestRuntime("net.mamoe:mirai-core:${Versions.core}")
compileAndTestRuntime(kotlin("stdlib", Versions.kotlinStdlib))
compileAndTestRuntime(kotlin("stdlib-jdk8", Versions.kotlinStdlib))
implementation(kotlinx("serialization-core", Versions.serialization)) compileAndTestRuntime("org.jetbrains.kotlinx:atomicfu:${Versions.atomicFU}")
implementation(kotlin("reflect")) compileAndTestRuntime(kotlinx("coroutines-core", Versions.coroutines))
compileAndTestRuntime(kotlinx("serialization-core", Versions.serialization))
compileAndTestRuntime(kotlin("reflect"))
api("net.mamoe.yamlkt:yamlkt:${Versions.yamlkt}") implementation("org.jetbrains:annotations:19.0.0")
implementation("org.jetbrains.kotlinx:atomicfu:${Versions.atomicFU}")
api("org.jetbrains:annotations:19.0.0")
api(kotlinx("coroutines-jdk8", Versions.coroutines))
api("com.vdurmont:semver4j:3.1.0") smartApi(kotlinx("coroutines-jdk8", Versions.coroutines))
smartApi("net.mamoe.yamlkt:yamlkt:${Versions.yamlkt}")
smartApi("com.vdurmont:semver4j:3.1.0")
//api(kotlinx("collections-immutable", Versions.collectionsImmutable))
testApi(kotlinx("serialization-core", Versions.serialization))
testApi("net.mamoe:mirai-core-qqandroid:${Versions.core}") testApi("net.mamoe:mirai-core-qqandroid:${Versions.core}")
testApi(kotlin("stdlib-jdk8")) testApi(kotlin("stdlib-jdk8"))
testApi(kotlin("test")) testApi(kotlin("test"))
testApi(kotlin("test-junit5")) testApi(kotlin("test-junit5"))
testImplementation("org.junit.jupiter:junit-jupiter-api:5.2.0") testApi("org.junit.jupiter:junit-jupiter-api:5.2.0")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.2.0") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.2.0")
// val autoService = "1.0-rc7"
// kapt("com.google.auto.service", "auto-service", autoService)
// compileOnly("com.google.auto.service", "auto-service-annotations", autoService)
}
ext.apply {
// 傻逼 compileAndRuntime 没 exclude 掉
// 傻逼 gradle 第二次配置 task 会覆盖掉第一次的配置
val x: com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar.() -> Unit = {
dependencyFilter.exclude {
when ("${it.moduleGroup}:${it.moduleName}") {
"net.mamoe:mirai-core" -> true
"org.jetbrains.kotlin:kotlin-stdlib" -> true
"org.jetbrains.kotlin:kotlin-stdlib-jdk8" -> true
"net.mamoe:mirai-core-qqandroid" -> true
else -> false
}
}
}
set("shadowJar", x)
} }
tasks { tasks {
@ -120,14 +98,14 @@ tasks {
Regex("""val buildDate: Instant = Instant.ofEpochSecond\(.*\)""") Regex("""val buildDate: Instant = Instant.ofEpochSecond\(.*\)""")
) { ) {
"""val buildDate: Instant = Instant.ofEpochSecond(${ """val buildDate: Instant = Instant.ofEpochSecond(${
Instant.now().getEpochSecond() Instant.now().epochSecond
})""" })"""
} }
.replace( .replace(
Regex("""val version: Semver = Semver\(".*", Semver.SemverType.LOOSE\)""") Regex("""val version: Semver = Semver\(".*", Semver.SemverType.LOOSE\)""")
) { """val version: Semver = Semver("${project.version}", Semver.SemverType.LOOSE)""" } ) { """val version: Semver = Semver("${project.version}", Semver.SemverType.LOOSE)""" }
) )
} }
} }
} }
} }

View File

@ -14,8 +14,8 @@ import java.time.Instant
internal object MiraiConsoleBuildConstants { // auto-filled on build (task :mirai-console:fillBuildConstants) internal object MiraiConsoleBuildConstants { // auto-filled on build (task :mirai-console:fillBuildConstants)
@JvmStatic @JvmStatic
val buildDate: Instant = Instant.ofEpochSecond(1599934775) val buildDate: Instant = Instant.ofEpochSecond(1600522812)
@JvmStatic @JvmStatic
val version: Semver = Semver("1.0-M4", Semver.SemverType.LOOSE) val version: Semver = Semver("1.0-RC-dev-28", Semver.SemverType.LOOSE)
} }

View File

@ -1,9 +1,12 @@
@file:Suppress("UnstableApiUsage") @file:Suppress("UnstableApiUsage")
plugins { plugins {
id("com.jfrog.bintray") version Versions.bintray apply false
id("net.mamoe.kotlin-jvm-blocking-bridge") version Versions.blockingBridge apply false
kotlin("jvm") version Versions.kotlinCompiler kotlin("jvm") version Versions.kotlinCompiler
kotlin("plugin.serialization") version Versions.kotlinCompiler kotlin("plugin.serialization") version Versions.kotlinCompiler
id("com.jfrog.bintray") version Versions.bintray apply false
id("net.mamoe.kotlin-jvm-blocking-bridge") version Versions.blockingBridge apply false
id("com.gradle.plugin-publish") version "0.12.0" apply false
//id("com.bmuschko.nexus") version "2.3.1" apply false
//id("io.codearte.nexus-staging") version "0.11.0" apply false
} }
tasks.withType(JavaCompile::class.java) { tasks.withType(JavaCompile::class.java) {

View File

@ -54,7 +54,7 @@ internal fun org.gradle.api.Project.`publishing`(configure: org.gradle.api.publi
inline fun Project.setupPublishing( inline fun Project.setupPublishing(
artifactId: String, artifactId: String,
bintrayRepo: String = "mirai", bintrayRepo: String = "mirai",
bintrayPkgName: String = "mirai-console", bintrayPkgName: String = artifactId,
vcs: String = "https://github.com/mamoe/mirai-console" vcs: String = "https://github.com/mamoe/mirai-console"
) { ) {

View File

@ -9,7 +9,7 @@
object Versions { object Versions {
const val core = "1.3.0" const val core = "1.3.0"
const val console = "1.0-RC-dev-5" const val console = "1.0-RC-dev-28"
const val consoleGraphical = "0.0.7" const val consoleGraphical = "0.0.7"
const val consoleTerminal = console const val consoleTerminal = console

View File

@ -7,8 +7,10 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE * https://github.com/mamoe/mirai/blob/master/LICENSE
*/ */
import org.gradle.api.artifacts.ExternalModuleDependency
import org.gradle.api.artifacts.dsl.DependencyHandler import org.gradle.api.artifacts.dsl.DependencyHandler
import org.gradle.kotlin.dsl.DependencyHandlerScope import org.gradle.kotlin.dsl.DependencyHandlerScope
import org.gradle.kotlin.dsl.accessors.runtime.addDependencyTo
@Suppress("unused") @Suppress("unused")
fun DependencyHandlerScope.kotlinx(id: String, version: String) = "org.jetbrains.kotlinx:kotlinx-$id:$version" fun DependencyHandlerScope.kotlinx(id: String, version: String) = "org.jetbrains.kotlinx:kotlinx-$id:$version"
@ -17,7 +19,29 @@ fun DependencyHandlerScope.kotlinx(id: String, version: String) = "org.jetbrains
fun DependencyHandlerScope.ktor(id: String, version: String = Versions.ktor) = "io.ktor:ktor-$id:$version" fun DependencyHandlerScope.ktor(id: String, version: String = Versions.ktor) = "io.ktor:ktor-$id:$version"
@Suppress("unused") @Suppress("unused")
fun DependencyHandler.compileAndRuntime(any: Any) { fun DependencyHandler.compileAndTestRuntime(any: Any) {
add("compileOnly", any) add("compileOnly", any)
add("runtimeOnly", any) add("testRuntimeOnly", any)
}
fun DependencyHandler.smartApi(
dependencyNotation: String
): ExternalModuleDependency {
return addDependencyTo(
this, "api", dependencyNotation
) {
fun exclude(group: String, module: String) {
exclude(mapOf(
"group" to group,
"module" to module
))
}
exclude("org.jetbrains.kotlin", "kotlin-stdlib-jdk8")
exclude("org.jetbrains.kotlin", "kotlin-stdlib")
exclude("org.jetbrains.kotlin", "kotlin-stdlib-common")
exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core-common")
exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core")
exclude("org.jetbrains.kotlinx", "kotlinx-serialization-common")
exclude("org.jetbrains.kotlinx", "kotlinx-serialization-core")
}
} }

49
docs/Appendix.md Normal file
View File

@ -0,0 +1,49 @@
# Mirai Console - Appendix
### Mirai Console 演进
Mirai Console 是不断前进的框架,将来必定会发生 API 弃用和重构。
维护者会严谨地推进每一项修改,并提供迁移周期(至少 2 个次版本)。
#### 版本规范
Mirai Console 的版本号遵循 [语义化版本 2.0.0](https://semver.org/lang/zh-CN/#spec-item-9) 规范。
在日常开发中, Mirai Console 会以 `-dev-1``-dev-2` 等版本后缀发布开发预览版本。这些版本仅用于兼容性测试等目的,无稳定性保证。
在大版本开发过程中Mirai Console 会以 `-M1`, `-M2` 等版本后缀发布里程碑预览版本。代表一系列功能的完成,但还不稳定。
这些版本里新增的 API 仍可能还会在下一个 Milestone 版本变化,因此请按需使用。
在大版本即将发布前Mirai Console 会以 `-RC` 版本后缀发布最终的预览版本。
`RC` 表示新版本 API 已经确定,离稳定版发布只差最后的一些内部优化或 bug 修复。
#### 版本选择
**稳定性**:稳定 (`x.y.z`) > 发布预览 (`-RC`) > 里程碑预览 (`-M`) > 开发 (`-dev`)。
| 目的 | 推荐至少更新到版本 |
|:--------------------------:|:--------------:|
| 生产环境 | `x.y.z` |
| 希望尽早体验稳定新特性的插件作者 | `-RC` |
| 无论如何都想体验新特性的插件作者 | `-M` |
| 前端实现者, 底层插件作者 | `-M` |
| 为 Mirai Console 提交 PR | `-dev` |
其中,‘底层插件’ 表示提供扩展等的插件。如权限系统,其他语言插件加载器等。
#### 更新兼容性
对于 `x.y.z` 版本号:
- 当 `z` 增加时,只会有 bug 修复,和必要的新函数添加(为了解决某一个问题),不会有破坏性变化。
- 当 `y` 增加时,可能有新 API 的引入,和旧 API 的弃用。但这些弃用会经过一个弃用周期后才被删除(隐藏)。向下兼容得到保证。
- 当 `x` 增加时,任何 API 都可能会有变化。无兼容性保证。
#### 弃用周期
一个计划被删除的 API将会在下一个次版本开始经历弃用周期。
如一个 API 在 `1.1.0` 起被弃用,它首先会是 `WARNING` (使用时会得到一个编译警告)弃用级别。
`1.2.0` 上升为 `ERROR`(使用时会得到一个编译错误);
`1.3.0` 上升为 `HIDDEN`(使用者无法看到这些 API)。
`HIDDEN` 的 API 仍然会保留在代码中并正常编译,以提供二进制兼容性,直到下一个主版本更新。

View File

@ -0,0 +1,80 @@
# Mirai Console - Configuring Projects
配置 Mirai Console 项目。
## 模块说明
console 由后端和前端一起工作. 使用时必须选择一个前端.
- `mirai-console`: Mirai Console 后端。
- `mirai-console-terminal`: 终端前端,适用于 JVM。
- [`MiraiAndroid`](https://github.com/mzdluo123/MiraiAndroid): Android 应用前端。
**注意:`mirai-console` 1.0-RC 发布之前, 前端请使用 `mirai-console-pure` 而不是 `mirai-console-terminal`**
## 选择版本
有关各类版本的区别,参考 [版本规范](Appendix.md#版本规范)
[Version]: https://api.bintray.com/packages/him188moe/mirai/mirai-console/images/download.svg?
[Bintray Download]: https://bintray.com/him188moe/mirai/mirai-console/
| 版本类型 | 版本号 |
|:------:|:------------:|
| 稳定 | - |
| 预览 | 1.0-M4 |
| 开发 | [![Version]][Bintray Download] |
## 配置项目
### 使用模板项目
Mirai 鼓励插件开发者将自己的作品开源,并为此提供了模板项目。
注意,模板项目依赖的 Mirai Console 不一定是最新的。请检查
1. 访问 [mirai-console-plugin-template](https://github.com/project-mirai/mirai-console-plugin-template)
2. 点击绿色按钮 "Use this template",创建项目
3. 克隆项目,检查并修改生成的属性
### 使用 Gradle 插件配置项目
`VERSION` 可在
若使用 `build.gradle.kts`:
```kotlin
plugins {
id("net.mamoe.mirai-console") version "VERSION"
}
```
若使用 `build.gradle`:
```groovy
plugins {
id 'net.mamoe.mirai-console' version 'VERSION'
}
```
完成。Mirai Console Gradle 插件会为你配置依赖等所有编译环境。
### 手动配置项目
添加依赖:
`build.gradle.kts`
```kotlin
repositories {
jcenter()
}
dependencies {
compileOnly("net.mamoe:mirai-core:$CORE_VERSION") // mirai-core 的 API
compileOnly("net.mamoe:mirai-console:$CONSOLE_VERSION") // 后端
testImplementation("net.mamoe:mirai-console-terminal:$CONSOLE_VERSION") // 前端, 用于启动测试
testImplementation("net.mamoe:mirai-console-terminal:$CONSOLE_VERSION") // 前端, 用于启动测试
}
```
之后还需要配置 Kotlin `jvm-default` 编译参数Kotlin 和 Java 的编译目标等。
在打包插件时必须将依赖一并打包进插件 JAR且排除 `mirai-core``mirai-console` 和它们的间接依赖,否则插件不会被加载。

2
docs/Contributing.md Normal file
View File

@ -0,0 +1,2 @@
# Mirai Console - Contributing

98
docs/Preparations.md Normal file
View File

@ -0,0 +1,98 @@
# Mirai Console - Preparations
***如果跳过本节内容,你很可能遇到无法解决的问题。***
***此文档假设你是 JVM 平台的开发者。若不是,请参考[其他语言 SDK](https://github.com/mamoe/mirai#%E5%BC%80%E5%8F%91%E8%80%85)***
### JVM 环境要求
- 桌面 JVM最低 Java 8但推荐 Java 11
- AndroidAndroid SDK 26+ Android 8.0)
### 开发插件的准备工作
#### 安装 IDE 插件
推荐使用 [IntelliJ IDEA](https://www.jetbrains.com/idea/) 或 [Android Studio](https://developer.android.com/studio)。Mirai Console 提供 IntelliJ 插件来提升开发体验。
- [Kotlin Jvm Blocking Bridge](https://github.com/mamoe/kotlin-jvm-blocking-bridge) ([JetBrains 插件仓库](https://plugins.jetbrains.com/plugin/14816-kotlin-jvm-blocking-bridge), [一键安装](https://plugins.jetbrains.com/embeddable/install/14816)):帮助 Java 用户调用 Kotlin suspend 函数
- [Mirai Console IntelliJ](../tools/intellij-plugin/) ([JetBrains 插件仓库](https://plugins.jetbrains.com/plugin/15094-mirai-console), [一键安装](https://plugins.jetbrains.com/embeddable/install/15094)):提供错误检查等功能
## 前置知识
要学习为 mirai-console 开发原生支持的插件, 需要:
- 掌握 Java 基础
- 至少粗略了解 Kotlin 基础语法30 分钟):
- [基本类型](https://www.kotlincn.net/docs/reference/basic-types.html)
- [类与继承](https://www.kotlincn.net/docs/reference/classes.html)
- [属性与字段](https://www.kotlincn.net/docs/reference/properties.html)
- [接口](https://www.kotlincn.net/docs/reference/interfaces.html)
- [扩展](https://www.kotlincn.net/docs/reference/extensions.html)
- [数据类](https://www.kotlincn.net/docs/reference/data-classes.html)
- [对象](https://www.kotlincn.net/docs/reference/object-declarations.html)
- [密封类](https://www.kotlincn.net/docs/reference/sealed-classes.html)
- **[Java 中调用 Kotlin](https://www.kotlincn.net/docs/reference/java-to-kotlin-interop.html)**
- 对于 Java 使用者,请阅读:
- [Java 用户的使用指南](#kotlin-源码阅读帮助)
- [在 Java 使用 Mirai Console 中的 Kotlin `suspend` 函数](#在-java-使用-mirai-console-中的-kotlin-suspend-函数)
- 对于 Kotlin 使用者,请熟知 [Kotlin `1.4` 版本带来的新特性](#mirai-console-使用的-kotlin-14-版本的新特性)
### Kotlin 源码阅读帮助
- Java 中的「方法」在 Kotlin 中均被称为「函数」。
- Kotlin 默认的访问权限是 `public`。如 Kotlin `class Test` 相当于 Java 的 `public class Test {}`
- Kotlin 的函数定义 `fun test(int: Int): String` 相当于 Java 的方法定义 `public String test(int int)`
### 在 Java 使用 Mirai Console 中的 Kotlin `suspend` 函数
#### 什么是 `suspend` 函数
`suspend` 函数中文是「挂起函数」,是 Kotlin 「[协程](https://www.kotlincn.net/docs/reference/coroutines/coroutines-guide.html)」的一部分。
Kotlin 协程是语言级特性,函数的修饰符 `suspend` 会在编译阶段被处理。
对于一个挂起函数:
```kotlin
suspend fun test(): String
```
它会被编译为 `public Object test(Continuation<String> $completion)`
这是因为 Kotlin 对所有挂起函数都有这样的内部变化,并在编译时实现了协程的一些特性。
Java 用户无法调用这样的方法,因为 `Continuation` 的实现很复杂。
Mamoe 为此开发了 Kotlin 编译器插件 [Kotlin Jvm Blocking Bridge](https://github.com/mamoe/kotlin-jvm-blocking-bridge),通过 `@JvmBlockingBridge` 注解,在编译期额外生成一个供 Java 使用的方法,让 Java 用户可以使用拥有源码内相同的函数签名的方法。
要获取详细信息,参考 [Kotlin Jvm Blocking Bridge 编译器插件](https://github.com/mamoe/kotlin-jvm-blocking-bridge/blob/master/README-chs.md#%E7%BC%96%E8%AF%91%E5%99%A8%E6%8F%92%E4%BB%B6)
### Mirai Console 使用的 Kotlin `1.4` 版本的新特性
在官方文档的 [语言特性与改进](https://www.kotlincn.net/docs/reference/whatsnew14.html#%E8%AF%AD%E8%A8%80%E7%89%B9%E6%80%A7%E4%B8%8E%E6%94%B9%E8%BF%9B) 基础上Mirai Console 的一些设计基于 Kotlin 1.4 的更多新特性。
#### `object` 内的扩展函数的自动引用
对于如下定义:
```kotlin
package org.example
object Obj {
fun String.foo()
}
```
在 Kotlin `1.3`,要调用 `foo`,必须使用:
```kotlin
Obj.run {
"str".foo()
}
```
因为 IDE 不会自动为 `String.foo` 添加 `import`
Kotlin `1.4` 解决了这个问题。在使用 `"str".foo` 时 Kotlin 会自动添加 `org.example.Obj.foo` 的引用。
Mirai Console 很多单例对象都设计为 `interface + companion object INSTANCE` 的接口与实现模式,需要这样的新特性。例如:
```kotlin
interface MiraiConsole {
companion object INSTANCE : MiraiConsole by MiraiConsoleImpl // MiraiConsoleImpl 是内部实现,不公开
}
```

View File

@ -1,183 +1,3 @@
# Mirai Console # Mirai Console
欢迎来到 mirai-console 开发文档! 欢迎来到 mirai-console 开发文档!
## 目录
- **[准备工作](#准备工作)**
- **[启动 Console](Run.md)**
### 后端插件开发基础
- 插件 - [Plugin 模块](Plugins.md)
- 指令 - [Command 模块](Commands.md)
- 存储 - [PluginData 模块](PluginData.md)
- 权限 - [Permission 模块](Permissions.md)
### 后端插件开发进阶
- 扩展 - [Extension 模块和扩展点](Extensions.md)
### 实现前端
- [FrontEnd](FrontEnd.md)
[`Plugin`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/Plugin.kt
[`Annotations`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/util/Annotations.kt
[`PluginData`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/PluginData.kt
[`JavaPluginScheduler`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JavaPluginScheduler.kt
[`JvmPlugin`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JvmPlugin.kt
[`PluginConfig`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/PluginConfig.kt
[`PluginLoader`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/loader/PluginLoader.kt
[`ConsoleInput`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/util/ConsoleInput.kt
[`PluginDataStorage`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/PluginDataStorage.kt
[`Command`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt
## 准备工作
***如果跳过本节内容,你很可能遇到无法解决的问题。***
### 环境要求
*不接受降低最低版本要求的建议*
- JDK 11
- AndroidAndroid SDK 26+ Android 8.0)
- Kotlin: 1.4
*Mirai Console 需要的 Kotlin 版本会与 Kotlin 最新稳定版本同步。*
### 开发插件的准备工作
- 安装并配置 JDK 11
若使用 Java或要修改 Mirai Console
- 使用 [IntelliJ IDEA](https://www.jetbrains.com/idea/) (或 `Android Studio`)。
- IDE 需装有 [Kotlin Jvm Blocking Bridge](https://github.com/mamoe/kotlin-jvm-blocking-bridge) 插件 (先启动你的 IDE再点击 [一键安装](https://plugins.jetbrains.com/embeddable/install/14816))
若使用 Kotlin无特别要求。
### 前置知识
要学习为 mirai-console 开发原生支持的插件, 需要:
- 掌握 Java 基础
- 至少粗略了解 Kotlin 基础语法30 分钟):
- [基本类型](https://www.kotlincn.net/docs/reference/basic-types.html)
- [类与继承](https://www.kotlincn.net/docs/reference/classes.html)
- [属性与字段](https://www.kotlincn.net/docs/reference/properties.html)
- [接口](https://www.kotlincn.net/docs/reference/interfaces.html)
- [扩展](https://www.kotlincn.net/docs/reference/extensions.html)
- [数据类](https://www.kotlincn.net/docs/reference/data-classes.html)
- [对象](https://www.kotlincn.net/docs/reference/object-declarations.html)
- [密封类](https://www.kotlincn.net/docs/reference/sealed-classes.html)
- **[Java 中调用 Kotlin](https://www.kotlincn.net/docs/reference/java-to-kotlin-interop.html)**
- 对于 Java 使用者,请阅读 [Java 用户的使用指南](#java-用户的使用指南)[在 Java 使用 Mirai Console 中的 Kotlin `suspend` 函数](#在-java-使用-mirai-console-中的-kotlin-suspend-函数)
- 对于 Kotlin 使用者,请熟知 [Kotlin `1.4` 版本带来的新特性](#mirai-console-使用的-kotlin-14-版本的新特性)
## 附录
### Java 用户的使用指南
- Java 中的「方法」在 Kotlin 中均被称为「函数」。
- Kotlin 默认的访问权限是 `public`。如 Kotlin `class Test` 相当于 Java 的 `public class Test {}`
- Kotlin 的函数定义 `fun test(int: Int): String` 相当于 Java 的方法定义 `public String test(int int)`
### 在 Java 使用 Mirai Console 中的 Kotlin `suspend` 函数
#### 什么是 `suspend` 函数
`suspend` 函数中文是「挂起函数」,是 Kotlin 「[协程](https://www.kotlincn.net/docs/reference/coroutines/coroutines-guide.html)」的一部分。
Kotlin 协程是语言级特性,函数的修饰符 `suspend` 会在编译阶段被处理。
对于一个挂起函数:
```kotlin
suspend fun test(): String
```
它会被编译为 `public Object test(Continuation<String> $completion)`
这是因为 Kotlin 对所有挂起函数都有这样的内部变化,并在编译时实现了协程的一些特性。
Java 用户无法调用这样的方法,因为 `Continuation` 的实现很复杂。
Mamoe 为此开发了 Kotlin 编译器插件 [Kotlin Jvm Blocking Bridge](https://github.com/mamoe/kotlin-jvm-blocking-bridge),通过 `@JvmBlockingBridge` 注解,在编译期额外生成一个供 Java 使用的方法,让 Java 用户可以使用拥有源码内相同的函数签名的方法。
要获取详细信息,参考 [Kotlin Jvm Blocking Bridge 编译器插件](https://github.com/mamoe/kotlin-jvm-blocking-bridge/blob/master/README-chs.md#%E7%BC%96%E8%AF%91%E5%99%A8%E6%8F%92%E4%BB%B6)
### Mirai Console 使用的 Kotlin `1.4` 版本的新特性
在官方文档的 [语言特性与改进](https://www.kotlincn.net/docs/reference/whatsnew14.html#%E8%AF%AD%E8%A8%80%E7%89%B9%E6%80%A7%E4%B8%8E%E6%94%B9%E8%BF%9B) 基础上Mirai Console 的一些设计基于 Kotlin 1.4 的更多新特性。
#### `object` 内的扩展函数的自动引用
对于如下定义:
```kotlin
package org.example
object Obj {
fun String.foo()
}
```
在 Kotlin `1.3`,要调用 `foo`,必须使用:
```kotlin
Obj.run {
"str".foo()
}
```
因为 IDE 不会自动为 `String.foo` 添加 `import`
Kotlin `1.4` 解决了这个问题。在使用 `"str".foo` 时 Kotlin 会自动添加 `org.example.Obj.foo` 的引用。
Mirai Console 很多单例对象都设计为 `interface + companion object INSTANCE` 的接口与实现模式,需要这样的新特性。例如:
```kotlin
interface MiraiConsole {
companion object INSTANCE : MiraiConsole by MiraiConsoleImpl // MiraiConsoleImpl 是内部实现,不公开
}
```
#### Mirai Console 演进
Mirai Console 是不断前进的框架,将来必定会发生 API 弃用和重构。
维护者会严谨地推进每一项修改,并提供迁移周期(至少 2 个次版本)。
##### 版本规范
Mirai Console 的版本号遵循 [语义化版本 2.0.0](https://semver.org/lang/zh-CN/#spec-item-9) 规范。
在日常开发中, Mirai Console 会以 `-dev-1``-dev-2` 等版本后缀发布开发预览版本。这些版本仅用于兼容性测试等目的,无稳定性保证。
在大版本开发过程中Mirai Console 会以 `-M1`, `-M2` 等版本后缀发布里程碑预览版本。代表一系列功能的完成,但还不稳定。
这些版本里新增的 API 仍可能还会在下一个 Milestone 版本变化,因此请按需使用。
在大版本即将发布前Mirai Console 会以 `-RC` 版本后缀发布最终的预览版本。
`RC` 表示新版本 API 已经确定,离稳定版发布只差最后的一些内部优化或 bug 修复。
##### 版本选择
**稳定性**:稳定 (`x.y.z`) > 发布预览 (`-RC`) > 里程碑预览 (`-M`) > 开发 (`-dev`)。
| 目的 | 推荐至少更新到版本 |
|:--------------------------:|:--------------:|
| 生产环境 | `x.y.z` |
| 希望尽早体验稳定新特性的插件作者 | `-RC` |
| 无论如何都想体验新特性的插件作者 | `-M` |
| 前端实现者, 底层插件作者 | `-M` |
| 为 Mirai Console 提交 PR | `-dev` |
其中,‘底层插件’ 表示提供扩展等的插件。如权限系统,其他语言插件加载器等。
##### 更新兼容性
对于 `x.y.z` 版本号:
- 当 `z` 增加时,只会有 bug 修复,和必要的新函数添加(为了解决某一个问题),不会有破坏性变化。
- 当 `y` 增加时,可能有新 API 的引入,和旧 API 的弃用。但这些弃用会经过一个弃用周期后才被删除(隐藏)。向下兼容得到保证。
- 当 `x` 增加时,任何 API 都可能会有变化。无兼容性保证。
##### 弃用周期
一个计划被删除的 API将会在下一个次版本开始经历弃用周期。
如一个 API 在 `1.1.0` 起被弃用,它首先会是 `WARNING` (使用时会得到一个编译警告)弃用级别。
`1.2.0` 上升为 `ERROR`(使用时会得到一个编译错误);
`1.3.0` 上升为 `HIDDEN`(使用者无法看到这些 API)。
`HIDDEN` 的 API 仍然会保留在代码中并正常编译,以提供二进制兼容性,直到下一个主版本更新。

View File

@ -2,11 +2,11 @@
Mirai Console 可以独立启动,也可以被嵌入到某个应用中。 Mirai Console 可以独立启动,也可以被嵌入到某个应用中。
## 使用第三方工具自动启动 ## 使用第三方工具自动独立启动
https://github.com/LXY1226/MiraiOK https://github.com/LXY1226/MiraiOK
## 独立启动 ## 手动配置独立启动
### 环境 ### 环境
- JRE 11+ / JDK 11+ - JRE 11+ / JDK 11+

View File

@ -36,34 +36,12 @@ dependencies {
implementation("org.jline:jline:3.15.0") implementation("org.jline:jline:3.15.0")
implementation("org.fusesource.jansi:jansi:1.18") implementation("org.fusesource.jansi:jansi:1.18")
compileAndRuntime(project(":mirai-console")) compileAndTestRuntime(project(":mirai-console"))
compileAndRuntime("net.mamoe:mirai-core:${Versions.core}") compileAndTestRuntime("net.mamoe:mirai-core:${Versions.core}")
compileAndRuntime(kotlin("stdlib", Versions.kotlinStdlib)) // embedded by core compileAndTestRuntime(kotlin("stdlib-jdk8", Versions.kotlinStdlib)) // embedded by core
runtimeOnly("net.mamoe:mirai-core-qqandroid:${Versions.core}")
testApi("net.mamoe:mirai-core-qqandroid:${Versions.core}") testApi("net.mamoe:mirai-core-qqandroid:${Versions.core}")
testApi(project(":mirai-console")) testApi(project(":mirai-console"))
// val autoService = "1.0-rc7"
// kapt("com.google.auto.service", "auto-service", autoService)
// compileOnly("com.google.auto.service", "auto-service-annotations", autoService)
// testCompileOnly("com.google.auto.service", "auto-service-annotations", autoService)
}
ext.apply {
// 傻逼 compileAndRuntime 没 exclude 掉
// 傻逼 gradle 第二次配置 task 会覆盖掉第一次的配置
val x: com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar.() -> Unit = {
dependencyFilter.include {
when ("${it.moduleGroup}:${it.moduleName}") {
"org.jline:jline" -> true
"org.fusesource.jansi:jansi" -> true
else -> false
}
}
}
this.set("shadowJar", x)
} }
version = Versions.consoleTerminal version = Versions.consoleTerminal

View File

@ -71,4 +71,4 @@ tasks {
} }
} }
// setupPublishing("mirai-console-intellij") setupPublishing("mirai-console-compiler-common")

View File

@ -1,2 +1,47 @@
# mirai-console-gradle # Mirai Console Gradle Plugin
Mirai Console Gradle 插件。
## 使用
参考 [ConfiguringProjects](../../docs/ConfiguringProjects.md#gradle)[
## 功能
- 为 `main` 源集配置 `mirai-core``mirai-console` 依赖
- 为 `test` 源集配置 `mirai-core-qqandroid`, `mirai-console-terminal` 的依赖 (用于启动测试)
- 添加 mirai 依赖仓库链接
- 配置插件 JAR 打包构建任务 `buildPlugin` (带依赖)
### `buildPlugin`
用于打包插件和依赖为可以放入 Mirai Console `plugins` 目录加载的插件 JAR。
#### 执行 `buildPlugin`
```shell script
$ gradlew buildPlugin
```
打包结果存放在 `build/mirai/` 目录下。
## 配置
若要修改 Mirai Console Gradle 插件的默认配置,在 `build.gradle.kts``build.gradle` 内,使用 `mirai`
```kotlin
mirai { // this: MiraiConsoleExtension
// 配置
}
```
DSL 详见 [MiraiConsoleExtension](src/main/kotlin/net/mamoe/mirai/console/gradle/MiraiConsoleExtension.kt)。
#### 排除依赖
如果要在打包 JAR`buildPlugin`)时排除一些依赖,请使用如下配置:
```kotlin
mirai {
excludeDependency("com.google.code.gson", "gson")
}
```

View File

@ -2,14 +2,112 @@
plugins { plugins {
kotlin("jvm") kotlin("jvm")
kotlin("kapt")
id("java-gradle-plugin")
id("com.gradle.plugin-publish")
id("java") id("java")
//signing
`maven-publish` `maven-publish`
id("com.jfrog.bintray") id("com.jfrog.bintray")
id("com.github.johnrengelman.shadow")
}
dependencies {
compileOnly(gradleApi())
compileOnly(kotlin("gradle-plugin-api").toString()) {
exclude("org.jetbrains.kotlin", "kotlin-stdlib")
}
compileOnly(kotlin("gradle-plugin").toString()) {
exclude("org.jetbrains.kotlin", "kotlin-stdlib")
}
compileOnly(kotlin("stdlib"))
api("com.github.jengelman.gradle.plugins:shadow:6.0.0")
api("org.jetbrains:annotations:19.0.0")
}
dependencies {
testApi(kotlin("test"))
testApi(kotlin("test-junit5"))
testImplementation("org.junit.jupiter:junit-jupiter-api:5.2.0")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.2.0")
} }
version = Versions.console version = Versions.console
description = "Gradle plugin for Mirai Console" description = "Gradle plugin for Mirai Console"
pluginBundle {
website = "https://github.com/mamoe/mirai-console"
vcsUrl = "https://github.com/mamoe/mirai-console"
tags = listOf("framework", "kotlin", "mirai")
}
gradlePlugin {
plugins {
create("miraiConsole") {
id = "net.mamoe.mirai-console"
displayName = "Mirai Console"
description = project.description
implementationClass = "net.mamoe.mirai.console.gradle.MiraiConsoleGradlePlugin"
}
}
}
kotlin {
sourceSets.all {
target.compilations.all {
kotlinOptions {
apiVersion = "1.3"
languageVersion = "1.3"
jvmTarget = "1.8"
freeCompilerArgs = freeCompilerArgs + "-Xjvm-default=all"
}
}
languageSettings.apply {
progressiveMode = true
useExperimentalAnnotation("kotlin.RequiresOptIn")
useExperimentalAnnotation("kotlin.ExperimentalUnsignedTypes")
useExperimentalAnnotation("kotlin.experimental.ExperimentalTypeInference")
useExperimentalAnnotation("kotlin.contracts.ExperimentalContracts")
}
}
}
tasks {
"test"(Test::class) {
useJUnitPlatform()
}
val compileKotlin by getting {}
@Suppress("UNUSED_VARIABLE")
val fillBuildConstants by registering {
group = "mirai"
doLast {
(compileKotlin as org.jetbrains.kotlin.gradle.tasks.KotlinCompile).source.filter { it.name == "VersionConstants.kt" }.single()
.let { file ->
file.writeText(
file.readText()
.replace(
Regex("""const val CONSOLE_VERSION = ".*"""")
) {
"""const val CONSOLE_VERSION = "${Versions.console}""""
}
.replace(
Regex("""const val CORE_VERSION = ".*"""")
) { """const val CORE_VERSION = "${Versions.core}"""" }
)
}
}
}
compileKotlin.dependsOn(fillBuildConstants)
}
java { java {
sourceCompatibility = JavaVersion.VERSION_1_8 sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8
@ -19,49 +117,4 @@ tasks.withType(JavaCompile::class.java) {
options.encoding = "UTF8" options.encoding = "UTF8"
} }
kotlin { setupPublishing("mirai-console-gradle")
sourceSets.all {
target.compilations.all {
kotlinOptions {
jvmTarget = "1.8"
freeCompilerArgs = freeCompilerArgs + "-Xjvm-default=all"
//useIR = true
}
}
languageSettings.apply {
progressiveMode = true
useExperimentalAnnotation("kotlin.Experimental")
useExperimentalAnnotation("kotlin.RequiresOptIn")
useExperimentalAnnotation("net.mamoe.mirai.utils.MiraiInternalAPI")
useExperimentalAnnotation("net.mamoe.mirai.utils.MiraiExperimentalAPI")
useExperimentalAnnotation("net.mamoe.mirai.console.ConsoleFrontEndImplementation")
useExperimentalAnnotation("net.mamoe.mirai.console.util.ConsoleExperimentalApi")
useExperimentalAnnotation("kotlin.ExperimentalUnsignedTypes")
useExperimentalAnnotation("kotlin.experimental.ExperimentalTypeInference")
useExperimentalAnnotation("kotlin.contracts.ExperimentalContracts")
useExperimentalAnnotation("kotlinx.serialization.ExperimentalSerializationApi")
useExperimentalAnnotation("net.mamoe.mirai.console.util.ConsoleInternalApi")
}
}
}
dependencies {
api("org.jetbrains:annotations:19.0.0")
api(kotlinx("coroutines-jdk8", Versions.coroutines))
testApi(kotlin("test"))
testApi(kotlin("test-junit5"))
testImplementation("org.junit.jupiter:junit-jupiter-api:5.2.0")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.2.0")
}
tasks {
"test"(Test::class) {
useJUnitPlatform()
}
}
// setupPublishing("mirai-console-gradle")

View File

@ -0,0 +1,132 @@
/*
* 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
*/
@file:JvmMultifileClass
@file:JvmName("MiraiConsoleGradlePluginKt")
package net.mamoe.mirai.console.gradle
internal val IGNORED_DEPENDENCIES_IN_SHADOW = arrayOf(
"org.jetbrains.kotlin:kotlin-stdlib",
"org.jetbrains.kotlin:kotlin-stdlib-common",
"org.jetbrains.kotlin:kotlin-stdlib-metadata",
"org.jetbrains.kotlin:kotlin-stdlib-jvm",
"org.jetbrains.kotlin:kotlin-stdlib-jdk7",
"org.jetbrains.kotlin:kotlin-stdlib-jdk8",
"org.jetbrains.kotlin:kotlin-reflect",
"org.jetbrains.kotlin:kotlin-reflect-common",
"org.jetbrains.kotlin:kotlin-reflect-metadata",
"org.jetbrains.kotlin:kotlin-reflect-jvm",
"org.jetbrains.kotlinx:kotlinx-serialization-core",
"org.jetbrains.kotlinx:kotlinx-serialization-core-common",
"org.jetbrains.kotlinx:kotlinx-serialization-core-metadata",
"org.jetbrains.kotlinx:kotlinx-serialization-core-jvm",
"org.jetbrains.kotlinx:kotlinx-serialization-runtime",
"org.jetbrains.kotlinx:kotlinx-serialization-runtime-common",
"org.jetbrains.kotlinx:kotlinx-serialization-runtime-metadata",
"org.jetbrains.kotlinx:kotlinx-serialization-runtime-jvm",
"org.jetbrains.kotlinx:kotlinx-serialization-protobuf",
"org.jetbrains.kotlinx:kotlinx-serialization-protobuf-common",
"org.jetbrains.kotlinx:kotlinx-serialization-protobuf-metadata",
"org.jetbrains.kotlinx:kotlinx-serialization-protobuf-jvm",
"org.jetbrains.kotlinx:kotlinx-coroutines-core",
"org.jetbrains.kotlinx:kotlinx-coroutines-core-common",
"org.jetbrains.kotlinx:kotlinx-coroutines-core-metadata",
"org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm",
"org.jetbrains.kotlinx:kotlinx-io",
"org.jetbrains.kotlinx:kotlinx-io-common",
"org.jetbrains.kotlinx:kotlinx-io-metadata",
"org.jetbrains.kotlinx:kotlinx-io-jvm",
"org.jetbrains.kotlinx:kotlinx-coroutines-io",
"org.jetbrains.kotlinx:kotlinx-coroutines-io-common",
"org.jetbrains.kotlinx:kotlinx-coroutines-io-metadata",
"org.jetbrains.kotlinx:kotlinx-coroutines-io-jvm",
"org.jetbrains.kotlinx:kotlinx-coroutines-core-jdk7",
"org.jetbrains.kotlinx:kotlinx-coroutines-core-jdk8",
"org.jetbrains.kotlinx:kotlinx-coroutines-jdk7",
"org.jetbrains.kotlinx:kotlinx-coroutines-jdk8",
"org.jetbrains.kotlinx:atomicFu",
"org.jetbrains.kotlinx:atomicFu-common",
"org.jetbrains.kotlinx:atomicFu-metadata",
"org.jetbrains.kotlinx:atomicFu-jvm",
"org.jetbrains:annotations:19.0.0",
"io.ktor:ktor-client",
"io.ktor:ktor-client-common",
"io.ktor:ktor-client-metadata",
"io.ktor:ktor-client-jvm",
"io.ktor:ktor-client-cio",
"io.ktor:ktor-client-cio-common",
"io.ktor:ktor-client-cio-metadata",
"io.ktor:ktor-client-cio-jvm",
"io.ktor:ktor-client-core",
"io.ktor:ktor-client-core-common",
"io.ktor:ktor-client-core-metadata",
"io.ktor:ktor-client-core-jvm",
"io.ktor:ktor-client-network",
"io.ktor:ktor-client-network-common",
"io.ktor:ktor-client-network-metadata",
"io.ktor:ktor-client-network-jvm",
"io.ktor:ktor-client-util",
"io.ktor:ktor-client-util-common",
"io.ktor:ktor-client-util-metadata",
"io.ktor:ktor-client-util-jvm",
"io.ktor:ktor-client-http",
"io.ktor:ktor-client-http-common",
"io.ktor:ktor-client-http-metadata",
"io.ktor:ktor-client-http-jvm",
"org.bouncyCastle:bcProv-jdk15on",
"net.mamoe:mirai-core",
"net.mamoe:mirai-core-metadata",
"net.mamoe:mirai-core-common",
"net.mamoe:mirai-core-jvm",
"net.mamoe:mirai-core-api", // for future
"net.mamoe:mirai-core-api-metadata",
"net.mamoe:mirai-core-api-common",
"net.mamoe:mirai-core-api-jvm",
"net.mamoe:mirai-core-qqAndroid",
"net.mamoe:mirai-core-qqAndroid-metadata",
"net.mamoe:mirai-core-qqAndroid-common",
"net.mamoe:mirai-core-qqAndroid-jvm",
"net.mamoe:mirai-console",
"net.mamoe:mirai-console-api", // for future
"net.mamoe:mirai-console-terminal",
"net.mamoe:mirai-console-graphical",
"net.mamoe.yamlKt:yamlKt",
"net.mamoe.yamlKt:yamlKt-common",
"net.mamoe.yamlKt:yamlKt-metadata",
"net.mamoe.yamlKt:yamlKt-jvm",
"net.mamoe:kotlin-jvm-blocking-bridge",
"net.mamoe:kotlin-jvm-blocking-bridge-common",
"net.mamoe:kotlin-jvm-blocking-bridge-metadata",
"net.mamoe:kotlin-jvm-blocking-bridge-jvm"
).map { it.toLowerCase() }.map { MiraiConsoleExtension.ExcludedDependency(it.substringBefore(':'), it.substringAfterLast(':')) }.toTypedArray()

View File

@ -0,0 +1,126 @@
/*
* 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
*/
@file:Suppress("unused", "MemberVisibilityCanBePrivate")
package net.mamoe.mirai.console.gradle
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import org.gradle.api.JavaVersion
/**
* ```
* mirai {
* // 配置
* }
* ```
*/
// must be open
open class MiraiConsoleExtension {
/**
* `true` 时不自动添加 mirai-core 的依赖
*
* 默认: `false`
*/
var noCore: Boolean = false
/**
* `true` 时不自动为 test 模块添加 mirai-core-qqandroid 的依赖.
*
* 默认: `false`
*/
var noTestCoreQQAndroid: Boolean = false
/**
* `true` 时不自动添加 mirai-console 的依赖.
*
* 默认: `false`
*/
var noConsole: Boolean = false
/**
* 自动添加的 mirai-core mirai-core-qqandroid 的版本.
*
* 默认: 与本 Gradle 插件编译时的 mirai-core 版本相同. [VersionConstants.CORE_VERSION]
*/
var coreVersion: String = VersionConstants.CORE_VERSION
/**
* 自动添加的 mirai-console 后端和前端的版本.
*
* 默认: 与本 Gradle 插件版本相同. [VersionConstants.CONSOLE_VERSION]
*/
var consoleVersion: String = VersionConstants.CONSOLE_VERSION
/**
* 自动为 test 模块添加的前端依赖名称
*
* `null` 时不自动为 test 模块添加前端依赖.
*
* 默认: [MiraiConsoleFrontEndKind.TERMINAL]
*/
var useTestConsoleFrontEnd: MiraiConsoleFrontEndKind? = MiraiConsoleFrontEndKind.TERMINAL
/**
* Java Kotlin 编译目标. 至少为 [JavaVersion.VERSION_1_8].
*
* 一般人不需要修改此项.
*
* 默认: [JavaVersion.VERSION_1_8]
*/
var jvmTarget: JavaVersion = JavaVersion.VERSION_1_8
/**
* 默认会配置 Kotlin 编译器参数 "-Xjvm-default=all". 将此项设置为 `false` 可避免配置.
*
* 一般人不需要修改此项.
*
* 默认: `false`
*/
var dontConfigureKotlinJvmDefault: Boolean = false
internal val shadowConfigurations: MutableList<ShadowJar.() -> Unit> = mutableListOf()
internal val excludedDependencies: MutableSet<ExcludedDependency> = mutableSetOf()
internal data class ExcludedDependency(
val group: String,
val name: String
)
/**
* 配置 [ShadowJar] (即打包插件)
*/
fun configureShadow(configure: ShadowJar.() -> Unit) {
shadowConfigurations.add(configure)
}
/**
* 在插件打包时忽略一个依赖
*
* @param notation 格式为 "groupId:name". "org.jetbrains.kotlin:kotlin-stdlib"
*/
fun excludeDependency(notation: String) {
requireNotNull(notation.count { it == ':' } == 1) { "Invalid dependency notation $notation." }
excludedDependencies.add(ExcludedDependency(notation.substringBefore(':'), notation.substringAfter(':')))
}
/**
* 在插件打包时忽略一个依赖
*
* @param group "org.jetbrains.kotlin"
* @param name "kotlin-stdlib"
*/
fun excludeDependency(group: String, name: String) {
excludedDependencies.add(ExcludedDependency(group, name))
}
}
enum class MiraiConsoleFrontEndKind {
TERMINAL,
}

View File

@ -0,0 +1,156 @@
/*
* 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
*/
@file:JvmMultifileClass
@file:JvmName("MiraiConsoleGradlePluginKt")
package net.mamoe.mirai.console.gradle
import com.github.jengelman.gradle.plugins.shadow.ShadowPlugin
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.plugins.JavaPluginExtension
import org.gradle.api.tasks.compile.JavaCompile
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension
import org.jetbrains.kotlin.gradle.dsl.KotlinSingleTargetExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.MAIN_COMPILATION_NAME
import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
class MiraiConsoleGradlePlugin : Plugin<Project> {
companion object {
internal const val BINTRAY_REPOSITORY_URL = "https://dl.bintray.com/him188moe/mirai"
}
private fun KotlinSourceSet.configureSourceSet(project: Project) {
languageSettings.useExperimentalAnnotation("kotlin.RequiresOptIn")
dependencies { configureDependencies(project, this@configureSourceSet) }
}
private fun Project.configureTarget(target: KotlinTarget) {
val miraiExtension = project.miraiExtension
for (compilation in target.compilations) with(compilation) {
kotlinOptions {
if (this !is KotlinJvmOptions) return@kotlinOptions
jvmTarget = miraiExtension.jvmTarget.toString()
if (!miraiExtension.dontConfigureKotlinJvmDefault) freeCompilerArgs = freeCompilerArgs + "-Xjvm-default=all"
}
}
target.compilations.flatMap { it.allKotlinSourceSets }.forEach { sourceSet ->
sourceSet.configureSourceSet(project)
}
}
@Suppress("SpellCheckingInspection")
private fun KotlinDependencyHandler.configureDependencies(project: Project, sourceSet: KotlinSourceSet) {
val miraiExtension = project.miraiExtension
if (!miraiExtension.noCore) compileOnly("net.mamoe:mirai-core:${miraiExtension.coreVersion}")
if (!miraiExtension.noConsole) compileOnly("net.mamoe:mirai-console:${miraiExtension.consoleVersion}")
if (sourceSet.name.endsWith("test", ignoreCase = true)) {
if (!miraiExtension.noCore) api("net.mamoe:mirai-core:${miraiExtension.coreVersion}")
if (!miraiExtension.noConsole) api("net.mamoe:mirai-console:${miraiExtension.consoleVersion}")
if (!miraiExtension.noTestCoreQQAndroid) api("net.mamoe:mirai-core-qqandroid:${miraiExtension.coreVersion}")
when (miraiExtension.useTestConsoleFrontEnd) {
MiraiConsoleFrontEndKind.TERMINAL -> api("net.mamoe:mirai-console-terminal:${miraiExtension.consoleVersion}")
}
}
}
private fun Project.configureCompileTarget() {
extensions.findByType(JavaPluginExtension::class.java)?.apply {
val miraiExtension = miraiExtension
sourceCompatibility = miraiExtension.jvmTarget
targetCompatibility = miraiExtension.jvmTarget
}
tasks.withType(JavaCompile::class.java) {
it.options.encoding = "UTF8"
}
}
private fun Project.registerBuildPluginTasks() {
val miraiExtension = this.miraiExtension
tasks.findByName("shadowJar")?.enabled = false
fun registerBuildPluginTask(target: KotlinTarget, isSinglePlatform: Boolean) {
tasks.create(if (isSinglePlatform) "buildPlugin" else "buildPlugin${target.name.capitalize()}", ShadowJar::class.java).apply shadow@{
group = "mirai"
val compilations = target.compilations.filter { it.name == MAIN_COMPILATION_NAME }
compilations.forEach {
dependsOn(it.compileKotlinTask)
from(it.output)
}
from(project.configurations.getByName("runtimeClasspath").copyRecursive { dependency ->
for (excludedDependency in IGNORED_DEPENDENCIES_IN_SHADOW + miraiExtension.excludedDependencies) {
if (excludedDependency.group == dependency.group
&& excludedDependency.name == dependency.name
) return@copyRecursive false
}
true
})
exclude { file ->
file.name.endsWith(".sf", ignoreCase = true)
}
destinationDirectory.value(project.layout.projectDirectory.dir(project.buildDir.name).dir("mirai"))
miraiExtension.shadowConfigurations.forEach { it.invoke(this@shadow) }
}
}
val targets = kotlinTargets
val isSingleTarget = targets.size == 1
targets.forEach { target ->
registerBuildPluginTask(target, isSingleTarget)
}
}
override fun apply(target: Project): Unit = with(target) {
target.extensions.create("mirai", MiraiConsoleExtension::class.java)
target.plugins.apply(JavaPlugin::class.java)
target.plugins.apply(ShadowPlugin::class.java)
target.repositories.maven { it.setUrl(BINTRAY_REPOSITORY_URL) }
afterEvaluate {
configureCompileTarget()
registerBuildPluginTasks()
kotlinTargets.forEach { configureTarget(it) }
}
}
}
internal val Project.miraiExtension: MiraiConsoleExtension
get() = extensions.findByType(MiraiConsoleExtension::class.java) ?: error("Cannot find MiraiConsoleExtension in project ${this.name}")
internal val Project.kotlinTargets: Collection<KotlinTarget>
get() {
val kotlinExtension = extensions.findByType(KotlinProjectExtension::class.java)
?: error("Kotlin plugin not applied. Please read https://www.kotlincn.net/docs/reference/using-gradle.html")
return when (kotlinExtension) {
is KotlinMultiplatformExtension -> kotlinExtension.targets
is KotlinSingleTargetExtension -> listOf(kotlinExtension.target)
else -> error("[MiraiConsole] Internal error: kotlinExtension is neither KotlinMultiplatformExtension nor KotlinSingleTargetExtension")
}
}

View File

@ -0,0 +1,15 @@
/*
* 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.gradle
internal object VersionConstants {
const val CONSOLE_VERSION = "1.0-RC-dev-28" // value is written here automatically during build
const val CORE_VERSION = "1.3.0" // value is written here automatically during build
}

View File

@ -33,7 +33,8 @@ intellij {
updateSinceUntilBuild = false updateSinceUntilBuild = false
setPlugins( setPlugins(
"org.jetbrains.kotlin:1.4.10-release-IJ2020.2-1@staging" "org.jetbrains.kotlin:1.4.10-release-IJ2020.2-1@staging",
"java"
) )
} }
@ -116,4 +117,4 @@ tasks {
} }
} }
// setupPublishing("mirai-console-intellij") setupPublishing("mirai-console-intellij")

View File

@ -9,6 +9,7 @@
Mamoe Technologies Mamoe Technologies
</vendor> </vendor>
<depends>com.intellij.modules.java</depends>
<depends>com.intellij.modules.platform</depends> <depends>com.intellij.modules.platform</depends>
<depends>org.jetbrains.kotlin</depends> <depends>org.jetbrains.kotlin</depends>