From f0a0fe013afad32622341ddea4790bf044546a8a Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Mon, 12 Aug 2024 17:01:42 +0800 Subject: [PATCH 1/3] =?UTF-8?q?fix(api):=20=E4=BF=AE=E5=A4=8D=20CreateAsse?= =?UTF-8?q?tApi=20=E4=BD=BF=E7=94=A8=E7=9A=84=E9=94=99=E8=AF=AF=E8=AF=B7?= =?UTF-8?q?=E6=B1=82=E5=A4=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/love/forte/simbot/kook/api/asset/CreateAssetApi.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simbot-component-kook-api/src/commonMain/kotlin/love/forte/simbot/kook/api/asset/CreateAssetApi.kt b/simbot-component-kook-api/src/commonMain/kotlin/love/forte/simbot/kook/api/asset/CreateAssetApi.kt index 26221e7a..3b382011 100644 --- a/simbot-component-kook-api/src/commonMain/kotlin/love/forte/simbot/kook/api/asset/CreateAssetApi.kt +++ b/simbot-component-kook-api/src/commonMain/kotlin/love/forte/simbot/kook/api/asset/CreateAssetApi.kt @@ -51,7 +51,7 @@ public class CreateAssetApi private constructor( private const val DEFAULT_FILENAME = "unknown-file" private const val ASSET_API_FORM_PROPERTY_NAME = "file" private val HEADERS = Headers.build { - append(HttpHeaders.ContentType, "form-data") + append(HttpHeaders.ContentType, ContentType.MultiPart.FormData) } /** From bd15b6ae0eee685c1b8608f7d44c71122552fc25 Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Mon, 12 Aug 2024 17:32:13 +0800 Subject: [PATCH 2/3] =?UTF-8?q?optimize(internal):=20=E7=AE=80=E5=8D=95?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=86=85=E9=83=A8=E7=9A=84KSP?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apireader/ApiReaderProcessor.kt | 56 +++--- .../apireader/EventReaderProcessor.kt | 52 +++--- .../build.gradle.kts | 166 ------------------ 3 files changed, 60 insertions(+), 214 deletions(-) delete mode 100644 simbot-component-kook-stdlib-test/build.gradle.kts diff --git a/internal-processors/api-reader/src/main/kotlin/kook/internal/processors/apireader/ApiReaderProcessor.kt b/internal-processors/api-reader/src/main/kotlin/kook/internal/processors/apireader/ApiReaderProcessor.kt index 8977ada5..244eeee7 100644 --- a/internal-processors/api-reader/src/main/kotlin/kook/internal/processors/apireader/ApiReaderProcessor.kt +++ b/internal-processors/api-reader/src/main/kotlin/kook/internal/processors/apireader/ApiReaderProcessor.kt @@ -20,8 +20,7 @@ package kook.internal.processors.apireader -import com.google.devtools.ksp.KspExperimental -import com.google.devtools.ksp.getKotlinClassByName +import com.google.devtools.ksp.getClassDeclarationByName import com.google.devtools.ksp.isAbstract import com.google.devtools.ksp.processing.Resolver import com.google.devtools.ksp.processing.SymbolProcessor @@ -42,29 +41,11 @@ abstract class ReaderProcessor(private val environment: SymbolProcessorEnvironme abstract val optionName: String abstract val targetClassName: String - @OptIn(KspExperimental::class) - override fun process(resolver: Resolver): List { - val targetFilePath: String? = environment.options[optionName] - - val targetFile = File(targetFilePath ?: run { - val msg = "target output file option ['$optionName'] is null!" - environment.logger.warn(msg) - return emptyList() - }) - - environment.logger.info("target output file: ${targetFile.absolutePath}") - val targetClass = resolver.getKotlinClassByName(targetClassName) - environment.logger.info("apiClass: $targetClassName") - targetClass ?: return emptyList() - - val targetClasses = resolver.getAllFiles().flatMap { it.declarations } - .filterIsInstance() - .filter { - targetClass.asStarProjectedType().isAssignableFrom(it.asStarProjectedType()) - } - .filter { !it.isAbstract() } - .toList() + private var targetFile: File? = null + private val targetClasses = mutableListOf() + override fun finish() { + val targetFile = targetFile ?: return if (!targetFile.exists()) { targetFile.parentFile.mkdirs() } else { @@ -80,7 +61,32 @@ abstract class ReaderProcessor(private val environment: SymbolProcessorEnvironme ).use { writer -> writer.writeDeflistTo(targetClasses) } + } + override fun process(resolver: Resolver): List { + val targetFilePath: String? = environment.options[optionName] + + val targetFile = File(targetFilePath ?: run { + val msg = "target output file option ['$optionName'] is null!" + environment.logger.warn(msg) + return emptyList() + }) + + this.targetFile = targetFile + + environment.logger.info("target output file: ${targetFile.absolutePath}") + val targetClass = resolver.getClassDeclarationByName(targetClassName) + environment.logger.info("apiClass: $targetClassName found $targetClass", targetClass) + targetClass ?: return emptyList() + + // find all + resolver.getAllFiles().flatMap { it.declarations } + .filterIsInstance() + .filter { + targetClass.asStarProjectedType().isAssignableFrom(it.asStarProjectedType()) + } + .filter { !it.isAbstract() } + .toCollection(targetClasses) return emptyList() } @@ -91,7 +97,7 @@ abstract class ReaderProcessor(private val environment: SymbolProcessorEnvironme * * @author ForteScarlet */ -class ApiReaderProcessor(private val environment: SymbolProcessorEnvironment) : ReaderProcessor(environment) { +class ApiReaderProcessor(environment: SymbolProcessorEnvironment) : ReaderProcessor(environment) { override val optionName: String = API_READ_TARGET_FILE_OPTION_KEY override val targetClassName: String = KOOK_API_CLASS_NAME } diff --git a/internal-processors/api-reader/src/main/kotlin/kook/internal/processors/apireader/EventReaderProcessor.kt b/internal-processors/api-reader/src/main/kotlin/kook/internal/processors/apireader/EventReaderProcessor.kt index 92b50f05..631be054 100644 --- a/internal-processors/api-reader/src/main/kotlin/kook/internal/processors/apireader/EventReaderProcessor.kt +++ b/internal-processors/api-reader/src/main/kotlin/kook/internal/processors/apireader/EventReaderProcessor.kt @@ -20,8 +20,7 @@ package kook.internal.processors.apireader -import com.google.devtools.ksp.KspExperimental -import com.google.devtools.ksp.getKotlinClassByName +import com.google.devtools.ksp.getClassDeclarationByName import com.google.devtools.ksp.getVisibility import com.google.devtools.ksp.processing.Resolver import com.google.devtools.ksp.processing.SymbolProcessor @@ -50,7 +49,29 @@ class EventReaderProcessor(private val environment: SymbolProcessorEnvironment) private val targetClassName = environment.options[EVENT_READ_TARGET_CLASS_OPTION_KEY] ?: KOOK_EVENT_CLASS_NAME - @OptIn(KspExperimental::class) + private var targetFile: File? = null + private val targetClasses = mutableListOf() + + override fun finish() { + val targetFile = targetFile ?: return + + if (!targetFile.exists()) { + targetFile.parentFile.mkdirs() + } else { + targetFile.delete() + } + + targetFile.toPath().bufferedWriter( + options = arrayOf( + StandardOpenOption.WRITE, + StandardOpenOption.TRUNCATE_EXISTING, + StandardOpenOption.CREATE + ) + ).use { writer -> + writer.writeDeflistTo(targetClasses) + } + } + override fun process(resolver: Resolver): List { val targetFilePath: String? = environment.options[EVENT_READ_TARGET_FILE_OPTION_KEY] @@ -59,37 +80,22 @@ class EventReaderProcessor(private val environment: SymbolProcessorEnvironment) environment.logger.warn(msg) return emptyList() }) + this.targetFile = targetFile environment.logger.info("Target class name: $targetClassName") environment.logger.info("Target output file: ${targetFile.absolutePath}") - val targetClass = resolver.getKotlinClassByName(targetClassName) - environment.logger.info("apiClass: $targetClass") + val targetClass = resolver.getClassDeclarationByName(targetClassName) + environment.logger.info("apiClass: $targetClass found at $targetClass", targetClass) targetClass ?: return emptyList() - val targetClasses = resolver.getAllFiles().flatMap { it.declarations } + resolver.getAllFiles().flatMap { it.declarations } .filterIsInstance() .filter { targetClass.asStarProjectedType().isAssignableFrom(it.asStarProjectedType()) } // .filter { !it.isAbstract() } .filter { it.getVisibility() in EXPECT_VISIBILITY } - .toList() - - if (!targetFile.exists()) { - targetFile.parentFile.mkdirs() - } else { - targetFile.delete() - } - - targetFile.toPath().bufferedWriter( - options = arrayOf( - StandardOpenOption.WRITE, - StandardOpenOption.TRUNCATE_EXISTING, - StandardOpenOption.CREATE - ) - ).use { writer -> - writer.writeDeflistTo(targetClasses) - } + .toCollection(targetClasses) return emptyList() } diff --git a/simbot-component-kook-stdlib-test/build.gradle.kts b/simbot-component-kook-stdlib-test/build.gradle.kts deleted file mode 100644 index 36a4777c..00000000 --- a/simbot-component-kook-stdlib-test/build.gradle.kts +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (c) 2023. ForteScarlet. - * - * This file is part of simbot-component-kook. - * - * simbot-component-kook is free software: you can redistribute it and/or modify it under the terms of - * the GNU Lesser General Public License as published by the Free Software Foundation, - * either version 3 of the License, or (at your option) any later version. - * - * simbot-component-kook is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License along with simbot-component-kook, - * If not, see . - */ - -import love.forte.gradle.common.kotlin.multiplatform.NativeTargets - -plugins { - kotlin("multiplatform") - kotlin("plugin.serialization") -} - - -repositories { - mavenCentral() -} - -kotlin { - jvm { - withJava() - compilations.all { - kotlinOptions { - jvmTarget = "1.8" - javaParameters = true - freeCompilerArgs = freeCompilerArgs + listOf("-Xjvm-default=all") - } - } - testRuns["test"].executionTask.configure { - useJUnitPlatform() - } - } - - js(IR) { - nodejs { - } - binaries.executable() - } - - - val mainPresets = mutableSetOf() - val testPresets = mutableSetOf() - - // see https://kotlinlang.org/docs/native-target-suppors - - val targets = NativeTargets.Official.all.intersect(NativeTargets.KtorClient.all) - - targets { - presets.filterIsInstance>() - .filter { it.name in targets } - .forEach { presets -> - val target = fromPreset(presets, presets.name) - val mainSourceSet = target.compilations["main"].kotlinSourceSets.first() - val testSourceSet = target.compilations["test"].kotlinSourceSets.first() - - val tn = target.name - when { - // just for test - // main中只使用HttpClient但用不到引擎,没必要指定 - - // win - tn.startsWith("mingw") -> { - mainSourceSet.dependencies { - implementation(libs.ktor.client.winhttp) - } - } - // linux: CIO..? - tn.startsWith("linux") -> { - mainSourceSet.dependencies { - implementation(libs.ktor.client.cio) - } - } - - // darwin based - tn.startsWith("macos") - || tn.startsWith("ios") - || tn.startsWith("watchos") - || tn.startsWith("tvos") -> { - mainSourceSet.dependencies { - implementation(libs.ktor.client.darwin) - } - } - } - - mainPresets.add(mainSourceSet) - testPresets.add(testSourceSet) - } - } - - sourceSets { - val commonMain by getting { - dependencies { - api(project(":simbot-component-kook-stdlib-multi")) - } - } - - val commonTest by getting { - dependencies { - implementation(kotlin("test")) - implementation(libs.kotlinx.coroutines.test) - } - } - - val jvmMain by getting { - dependencies { - runtimeOnly(libs.ktor.client.cio) - compileOnly(simbotUtilAnnotations) // use @Api4J annotation - } - } - - - getByName("jvmTest") { - dependencies { - implementation(libs.ktor.client.cio) - implementation(simbotApi) - implementation(simbotLogger) - implementation(simbotLoggerSlf4j) - } - } - - getByName("jsMain") { - dependencies { - implementation(libs.ktor.client.js) - implementation("love.forte.plugin.suspend-transform:suspend-transform-annotation:0.4.0") - } - } - - val nativeMain by creating { - dependsOn(commonMain) - } - - val nativeTest by creating { - dependsOn(commonTest) - } - - configure(mainPresets) { dependsOn(nativeMain) } - configure(testPresets) { dependsOn(nativeTest) } - - } - -} - - - -// suppress all? -//tasks.withType().configureEach { -// dokkaSourceSets.configureEach { -// suppress.set(true) -// perPackageOption { -// suppress.set(true) -// } -// } -//} - - From a9d7613ca43ee5be8fd1db90f0b894040cf56a2d Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Mon, 12 Aug 2024 17:37:14 +0800 Subject: [PATCH 3/3] release: v4.0.0-beta6 --- .changelog/v4.0.0-beta6.md | 7 +++++++ .github/workflows/publish-release.yml | 27 ++------------------------- CHANGELOG.md | 7 +++++++ buildSrc/src/main/kotlin/P.kt | 4 ++-- 4 files changed, 18 insertions(+), 27 deletions(-) create mode 100644 .changelog/v4.0.0-beta6.md diff --git a/.changelog/v4.0.0-beta6.md b/.changelog/v4.0.0-beta6.md new file mode 100644 index 00000000..a18f9fde --- /dev/null +++ b/.changelog/v4.0.0-beta6.md @@ -0,0 +1,7 @@ +> 对应核心版本: [**v4.5.0**](https://github.com/simple-robot/simpler-robot/releases/tag/v4.5.0) + +> [!warning] +> 目前版本尚处于 **`beta`** 阶段,代表仍然可能存在部分已知问题或未知问题, +> 以及尚未完善的内容和落后于官方更新的内容。 + +我们欢迎并期望着您的 [反馈](https://github.com/simple-robot/simbot-component-kook/issues) 或 [协助](https://github.com/simple-robot/simbot-component-kook/pulls),感谢您的贡献与支持! diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 87095493..3816db40 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -88,10 +88,11 @@ jobs: # Create gitHub release - name: Create Github Release - uses: softprops/action-gh-release@v0.1.15 + uses: softprops/action-gh-release@v2 with: token: ${{ secrets.PUSH_TOKEN }} body_path: .changelog/${{ github.ref_name }}.md + body: '' generate_release_notes: true prerelease: ${{ contains(github.ref_name, 'preview') || contains(github.ref_name, 'alpha') || contains(github.ref_name, 'dev') }} @@ -137,27 +138,3 @@ jobs: # deploy to sub dir destination_dir: components/kook -# deploy-website: -# name: Deploy Website -# runs-on: ubuntu-latest -# needs: run-test-and-publish -# steps: -# - uses: actions/checkout@v4 -# - uses: actions/setup-node@v3 -# with: -# node-version: 16.x -# cache: npm -# cache-dependency-path: ./website/package-lock.json -# -# - run: | -# npm ci -# npm run build -# working-directory: ./website -# -# # https://github.com/marketplace/actions/github-pages-action -# - name: Push to doc repository -# uses: peaceiris/actions-gh-pages@v3 -# with: -# personal_token: ${{ secrets.PUSH_TOKEN }} -# publish_branch: gh-pages -# publish_dir: ./website/build diff --git a/CHANGELOG.md b/CHANGELOG.md index c659d811..bf0a0c23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# v4.0.0-beta6 + +> Release & Pull Notes: [v4.0.0-beta6](https://github.com/simple-robot/simpler-robot/releases/tag/v4.0.0-beta6) + +- optimize(internal): 简单优化内部的KSP ([`bd15b6a`](https://github.com/simple-robot/simpler-robot/commit/bd15b6a)) +- fix(api): 修复 CreateAssetApi 使用的错误请求头 ([`f0a0fe0`](https://github.com/simple-robot/simpler-robot/commit/f0a0fe0)) + # v4.0.0-beta5 > Release & Pull Notes: [v4.0.0-beta5](https://github.com/simple-robot/simpler-robot/releases/tag/v4.0.0-beta5) diff --git a/buildSrc/src/main/kotlin/P.kt b/buildSrc/src/main/kotlin/P.kt index 3eda9e1e..23882083 100644 --- a/buildSrc/src/main/kotlin/P.kt +++ b/buildSrc/src/main/kotlin/P.kt @@ -49,8 +49,8 @@ object P : ProjectDetail() { override val homepage: String get() = HOMEPAGE - const val VERSION = "4.0.0-beta5" - const val NEXT_VERSION = "4.0.0-beta6" + const val VERSION = "4.0.0-beta6" + const val NEXT_VERSION = "4.0.0-beta7" override val snapshotVersion = "$NEXT_VERSION-SNAPSHOT" override val version = if (isSnapshot()) snapshotVersion else VERSION