diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 1fa47695..42a1198e 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -20,9 +20,9 @@ jobs:
- name: Set up Java
uses: actions/setup-java@v1
with:
- java-version: 1.8
+ java-version: 11
- name: test
- run: ./gradlew clean test --stacktrace
+ run: ./gradlew test --stacktrace
- name: package plugin
run: ./plugin-script/package_plugin.sh
diff --git a/.github/workflows/co.yml b/.github/workflows/co.yml
index 335b6663..2a0566a8 100644
--- a/.github/workflows/co.yml
+++ b/.github/workflows/co.yml
@@ -21,7 +21,7 @@ jobs:
- name: Set up Java
uses: actions/setup-java@v1
with:
- java-version: 1.8
+ java-version: 11
- name: Generate coverage report
run: |
./gradlew check --stacktrace
diff --git a/.github/workflows/release-rc.yml b/.github/workflows/release-rc.yml
index b8298c66..50c18016 100644
--- a/.github/workflows/release-rc.yml
+++ b/.github/workflows/release-rc.yml
@@ -27,7 +27,7 @@ jobs:
- name: Set up Java
uses: actions/setup-java@v1
with:
- java-version: 1.8
+ java-version: 11
- name: release commit
run: ./plugin-script/release-rc.sh
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index c558efe8..a84c3d62 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -27,7 +27,7 @@ jobs:
- name: Set up Java
uses: actions/setup-java@v1
with:
- java-version: 1.8
+ java-version: 11
- name: release commit
run: ./plugin-script/release.sh
diff --git a/.gitignore b/.gitignore
index 6a611555..5072bf34 100644
--- a/.gitignore
+++ b/.gitignore
@@ -44,4 +44,6 @@ src/main/resources/META-INF/services/com.itangcent.common.spi.SetupAble
/envs
out/
-plugin-adapter/plugin-adapter-markdown/build/
\ No newline at end of file
+plugin-adapter/plugin-adapter-markdown/build/
+gradle/wrapper/caches
+gradle/wrapper/daemon
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
deleted file mode 100644
index 687a1f70..00000000
--- a/build.gradle
+++ /dev/null
@@ -1,286 +0,0 @@
-import java.nio.charset.StandardCharsets
-
-buildscript {
- repositories {
- mavenCentral()
- }
- dependencies {
- classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
- }
-}
-
-plugins {
- //https://mvnrepository.com/artifact/org.jetbrains.kotlin.jvm/org.jetbrains.kotlin.jvm.gradle.plugin
- id 'org.jetbrains.kotlin.jvm' version '1.3.71'
-}
-
-group 'com.itangcent'
-version '2.2.3.183.0'
-
-@SuppressWarnings("GroovyAssignabilityCheck")
-static def majorVersion(version) {
- return version[0..4]
-}
-
-@SuppressWarnings("GroovyAssignabilityCheck")
-static def nextVersion(version) {
- if (version.endsWith("-rc")) {
- return version[0..4]
- }
- def majorVersion = majorVersion(version)
- def next = ((majorVersion[0, 2, 4] as Integer) + 1).toString()
- return next[0] + "." + next[1] + "." + next[2]
-}
-
-task patchUpdate {
- doLast {
- def majorVersion = majorVersion(version)
- println "current version:" + majorVersion
- def nextVersion = nextVersion(version)
- def nextVersionFull = nextVersion + ".183.0"
- println "next version:" + nextVersion
-
- //patch IDEA_CHANGELOG.md
- def changelogFile = new File("IDEA_CHANGELOG.md")
- def oldChangelogFile = new File("IDEA_CHANGELOG.md.old")
- changelogFile.renameTo(new File("IDEA_CHANGELOG.md.old"))
-
- changelogFile.newOutputStream().withCloseable {
- def versionNote = "* ${nextVersion}\n\n"
- it.write(versionNote.getBytes(StandardCharsets.UTF_8))
- def commitsFile = new File("plugin-script/commits.txt")
- for (line in commitsFile.readLines()) {
- try {
- def (_, msg, id) = (line =~ /(.*?)\s*\(#(\d+)\)/)[0]
- it.write("\t* ${msg} [(#${id})](https://github.com/tangcent/easy-api/pull/${id})\n\n".getBytes(StandardCharsets.UTF_8))
- } catch (ignore) {
- }
- }
- def oldFile = oldChangelogFile.getText("UTF-8")
- if(oldFile.startsWith(versionNote)){
- it.write(oldFile.substring(versionNote.size()).getBytes(StandardCharsets.UTF_8))
- }else{
- it.write(oldFile.getBytes(StandardCharsets.UTF_8))
- }
- }
- oldChangelogFile.delete()
-
- //patch pluginChanges.html
- def pluginChangesFile = new File("idea-plugin/parts/pluginChanges.html")
- pluginChangesFile.delete()
- pluginChangesFile.createNewFile()
- pluginChangesFile.newOutputStream().withCloseable {
- it.write("v${nextVersion}.183.0(${new Date().format("yyyy-MM-dd")})\n".getBytes(StandardCharsets.UTF_8))
- it.write("
\n".getBytes(StandardCharsets.UTF_8))
- it.write("Full Changelog\n".getBytes(StandardCharsets.UTF_8))
- def enhancements = []
- def fixes = []
- def commitsFile = new File("plugin-script/commits.txt")
- for (line in commitsFile.readLines()) {
- try {
- def (_, msg, id) = (line =~ /(.*?)\s*\(#(\d+)\)/)[0]
- def li = "\t
${msg} (#${id})\n" +
- "\t"
- if (line.startsWith("fix")) {
- fixes.add(li)
- } else if(line.startsWith("feat")||line.startsWith("opti")||line.startsWith("perf")){
- enhancements.add(li)
- }
- } catch (ignore) {
- }
- }
- if (!enhancements.isEmpty()) {
- it.write("enhancement:\n".getBytes(StandardCharsets.UTF_8))
- for (enhancement in enhancements) {
- it.write("${enhancement}\n".getBytes(StandardCharsets.UTF_8))
- }
- it.write("
\n".getBytes(StandardCharsets.UTF_8))
- }
- if (!fixes.isEmpty()) {
- it.write("fix:\n".getBytes(StandardCharsets.UTF_8))
- for (fix in fixes) {
- it.write("${fix}\n".getBytes(StandardCharsets.UTF_8))
- }
- it.write("
\n".getBytes(StandardCharsets.UTF_8))
- }
- }
-
- //update build.gradle
- ant.replace(file: "build.gradle", token: version, value: nextVersionFull)
- //update gradle.properties
- ant.replace(file: "gradle.properties", token: version, value: nextVersionFull)
- //update plugin.xml
- ant.replace(file: "idea-plugin/src/main/resources/META-INF/plugin.xml", token: version, value: nextVersionFull)
-
- //set env
- def envDir = new File("envs")
- if (envDir.exists()) {
- envDir.deleteDir()
- }
- envDir.mkdir()
- new File("envs/EASY_API_PR_TITLE").newOutputStream().withCloseable {
- it.write("release v${nextVersion}".getBytes(StandardCharsets.UTF_8))
- }
-
- def prBody = ""
- def commitsFile = new File("plugin-script/commits.txt")
- for (line in commitsFile.readLines()) {
- try {
- def (_, msg, id) = (line =~ /(.*?)\s*\(#(\d+)\)/)[0]
- prBody += "* ${msg} [(#${id})](https://github.com/tangcent/easy-api/pull/${id})\n\n"
- } catch (ignore) {
- }
- }
- new File("envs/EASY_API_PR_BODY").newOutputStream().withCloseable {
- it.write(prBody.getBytes(StandardCharsets.UTF_8))
- }
- }
-}
-
-task patchUpdateRc {
- doLast {
- def majorVersion = majorVersion(version)
- println "current version:" + majorVersion
- def nextVersion = nextVersion(version)
- def nextVersionShort = nextVersion + "-rc"
- def nextVersionFull = nextVersion + ".183.0-rc"
- println "next version: ${nextVersionShort}"
-
- //patch IDEA_CHANGELOG.md
- def changelogFile = new File("IDEA_CHANGELOG.md")
- def oldChangelogFile = new File("IDEA_CHANGELOG.md.old")
- changelogFile.renameTo(new File("IDEA_CHANGELOG.md.old"))
-
- changelogFile.newOutputStream().withCloseable {
- it.write("* ${nextVersion}\n\n".getBytes(StandardCharsets.UTF_8))
- def commitsFile = new File("plugin-script/commits.txt")
- for (line in commitsFile.readLines()) {
- try {
- def (_, msg, id) = (line =~ /(.*?)\s*\(#(\d+)\)/)[0]
- it.write("\t* ${msg} [(#${id})](https://github.com/tangcent/easy-api/pull/${id})\n\n".getBytes(StandardCharsets.UTF_8))
- } catch (ignore) {
- }
- }
- it.write(oldChangelogFile.readBytes())
- }
- oldChangelogFile.delete()
-
- //patch pluginChanges.html
- def pluginChangesFile = new File("idea-plugin/parts/pluginChanges.html")
- pluginChangesFile.delete()
- pluginChangesFile.createNewFile()
- pluginChangesFile.newOutputStream().withCloseable {
- it.write("v${nextVersionFull}(${new Date().format("yyyy-MM-dd")})\n".getBytes(StandardCharsets.UTF_8))
- it.write("
\n".getBytes(StandardCharsets.UTF_8))
- it.write("Full Changelog\n".getBytes(StandardCharsets.UTF_8))
- def enhancements = []
- def fixes = []
- def commitsFile = new File("plugin-script/commits.txt")
- for (line in commitsFile.readLines()) {
- try {
- def (_, msg, id) = (line =~ /(.*?)\s*\(#(\d+)\)/)[0]
- def li = "\t ${msg} (#${id})\n" +
- "\t"
- if (line.startsWith("fix")) {
- fixes.add(li)
- } else if(line.startsWith("feat")||line.startsWith("opti")||line.startsWith("perf")){
- enhancements.add(li)
- }
- } catch (ignore) {
- }
- }
- if (!enhancements.isEmpty()) {
- it.write("enhancement:\n".getBytes(StandardCharsets.UTF_8))
- for (enhancement in enhancements) {
- it.write("${enhancement}\n".getBytes(StandardCharsets.UTF_8))
- }
- it.write("
\n".getBytes(StandardCharsets.UTF_8))
- }
- if (!fixes.isEmpty()) {
- it.write("fix:\n".getBytes(StandardCharsets.UTF_8))
- for (fix in fixes) {
- it.write("${fix}\n".getBytes(StandardCharsets.UTF_8))
- }
- it.write("
\n".getBytes(StandardCharsets.UTF_8))
- }
- }
-
- //update build.gradle
- ant.replace(file: "build.gradle", token: version, value: nextVersionFull)
- //update gradle.properties
- ant.replace(file: "gradle.properties", token: version, value: nextVersionFull)
- //update plugin.xml
- ant.replace(file: "idea-plugin/src/main/resources/META-INF/plugin.xml", token: version, value: nextVersionFull)
-
- //set env
- def envDir = new File("envs")
- if (!envDir.exists()) {
- envDir.mkdir()
- }
- new File("envs/EASY_API_PR_TITLE").newOutputStream().withCloseable {
- it.write("release v${nextVersionShort}".getBytes(StandardCharsets.UTF_8))
- }
-
- def prBody = ""
- def commitsFile = new File("plugin-script/commits.txt")
- for (line in commitsFile.readLines()) {
- try {
- def (_, msg, id) = (line =~ /(.*?)\s*\(#(\d+)\)/)[0]
- prBody += "* ${msg} [(#${id})](https://github.com/tangcent/easy-api/pull/${id})\n\n"
- } catch (ignore) {
- }
- }
- new File("envs/EASY_API_PR_BODY").newOutputStream().withCloseable {
- it.write(prBody.getBytes(StandardCharsets.UTF_8))
- }
- }
-}
-
-allprojects {
- apply plugin: 'java'
- apply plugin: 'kotlin'
- apply plugin: 'maven-publish'
- apply plugin: 'jacoco'
-
- sourceCompatibility = 1.8
- targetCompatibility = 1.8
-
- repositories {
- mavenLocal()
- mavenCentral()
- jcenter()
-
- maven {
- url("https://oss.sonatype.org/content/repositories/snapshots/")
- }
- }
-
- compileKotlin {
- kotlinOptions.jvmTarget = "1.8"
- }
-
- compileTestKotlin {
- kotlinOptions.jvmTarget = "1.8"
- }
-}
-
-task codeCoverageReport(type: JacocoReport) {
- executionData fileTree(project.rootDir.absolutePath).include("**/build/jacoco/*.exec")
-
- subprojects.each {
- sourceSets it.sourceSets.main
- }
-
- reports {
- xml.enabled true
- xml.destination file("${buildDir}/reports/jacoco/report.xml")
- html.enabled false
- csv.enabled false
- }
-}
-
-codeCoverageReport.dependsOn {
- subprojects*.test
-}
\ No newline at end of file
diff --git a/build.gradle.kts b/build.gradle.kts
new file mode 100644
index 00000000..5443ef1f
--- /dev/null
+++ b/build.gradle.kts
@@ -0,0 +1,177 @@
+import java.text.SimpleDateFormat
+import java.util.*
+
+plugins {
+ id("java")
+ id("org.jetbrains.kotlin.jvm") version "1.8.0"
+ id("application")
+ id("jacoco")
+ `java-library`
+}
+
+subprojects {
+ plugins.apply("java")
+ plugins.apply("kotlin")
+ plugins.apply("jacoco")
+
+ repositories {
+ mavenCentral()
+ maven("https://oss.sonatype.org/content/repositories/snapshots/")
+ }
+}
+
+group = "com.itangcent"
+version = properties["plugin_version"]!!
+
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ testImplementation("org.jetbrains.kotlin:kotlin-test")
+}
+
+tasks.getByName("test") {
+ useJUnitPlatform()
+}
+
+kotlin {
+ jvmToolchain(11)
+}
+
+tasks.create("codeCoverageReport", JacocoReport::class) {
+ executionData(
+ fileTree(project.rootDir.absolutePath).include("**/build/jacoco/*.exec")
+ )
+ subprojects.forEach {
+ sourceDirectories.from(it.file("src/main/kotlin"))
+ classDirectories.from(it.file("build/classes/kotlin/main"))
+ }
+ reports {
+ xml.required.set(true)
+ xml.outputLocation.set(file("${buildDir}/reports/jacoco/report.xml").apply { parentFile.mkdirs() })
+ html.required.set(false)
+ csv.required.set(false)
+ }
+
+ generate()
+}
+
+fun majorVersion(version: String): String {
+ val parts = version.split(".")
+ return "${parts[0]}.${parts[1]}.${parts[2]}"
+}
+
+fun nextVersion(version: String): String {
+ val parts = version.split(".")
+ val next = ("${parts[0]}${parts[1]}${parts[2]}".toInt() + 1).toString()
+ return "${next[0]}.${next[1]}.${next[2]}"
+}
+
+val patchUpdate by tasks.registering(Task::class) {
+ doLast {
+ val majorVersion = majorVersion(version.toString())
+ println("current version:$majorVersion")
+ val nextVersion = nextVersion(version.toString())
+ val nextVersionFull = "$nextVersion.212.0"
+ println("next version:$nextVersion")
+
+ val commitsFile = File("plugin-script/commits.txt")
+ val commits = commitsFile.readLines().mapNotNull { line ->
+ try {
+ val matchValues = Regex("^(.*?)\\s*\\(#(\\d+)\\)$").find(line)!!.groupValues
+ matchValues[1] to matchValues[2]
+ } catch (ignore: Throwable) {
+ null
+ }
+ }
+
+ //patch IDEA_CHANGELOG.md
+ val changelogFile = File("IDEA_CHANGELOG.md")
+ val oldChangelogFile = File("IDEA_CHANGELOG.md.old")
+ changelogFile.renameTo(oldChangelogFile)
+
+ changelogFile.outputStream().use {
+ val versionNote = "* ${nextVersion}\n\n"
+ it.write(versionNote.encodeToByteArray())
+ for ((msg, id) in commits) {
+ it.write(
+ "\t* $msg [(#${id})](https://github.com/tangcent/easy-api/pull/${id})\n\n".encodeToByteArray()
+ )
+ }
+ val oldFile = oldChangelogFile.readText()
+ if (oldFile.startsWith(versionNote)) {
+ it.write(oldFile.substring(versionNote.length).encodeToByteArray())
+ } else {
+ it.write(oldFile.encodeToByteArray())
+ }
+ }
+ oldChangelogFile.delete()
+
+ //patch pluginChanges.html
+ val pluginChangesFile = File("idea-plugin/parts/pluginChanges.html")
+ pluginChangesFile.delete()
+ pluginChangesFile.createNewFile()
+ pluginChangesFile.outputStream().use {
+ it.write(
+ "v${nextVersion}.212.0(${
+ SimpleDateFormat("yyyy-MM-dd").format(Date())
+ })\n".encodeToByteArray()
+ )
+ it.write("
\n".encodeToByteArray())
+ it.write(
+ "Full Changelog\n".encodeToByteArray()
+ )
+ val enhancements = ArrayList()
+ val fixes = ArrayList()
+ for ((msg, id) in commits) {
+ val li = "\t $msg (#${id})\n" +
+ "\t"
+ if (msg.startsWith("fix")) {
+ fixes.add(li)
+ } else if (msg.startsWith("feat") || msg.startsWith("opti") || msg.startsWith("perf")) {
+ enhancements.add(li)
+ }
+ }
+ if (enhancements.isNotEmpty()) {
+ it.write("enhancement:\n".encodeToByteArray())
+ for (enhancement in enhancements) {
+ it.write("${enhancement}\n".encodeToByteArray())
+ }
+ it.write("
\n".encodeToByteArray())
+ }
+ if (fixes.isNotEmpty()) {
+ it.write("fix:\n".encodeToByteArray())
+ for (fix in fixes) {
+ it.write("${fix}\n".encodeToByteArray())
+ }
+ it.write("
\n".encodeToByteArray())
+ }
+ }
+
+ //update files
+ arrayOf("build.gradle.kts", "gradle.properties", "idea-plugin/src/main/resources/META-INF/plugin.xml")
+ .map { File(it) }.forEach {
+ it.writeText(it.readText().replace(version.toString(), nextVersionFull))
+ }
+
+ //set env
+ val envDir = File("envs")
+ if (envDir.exists()) {
+ envDir.delete()
+ }
+ envDir.mkdir()
+ File("envs/EASY_YAPI_PR_TITLE").outputStream().use {
+ it.write("release v${nextVersion}".encodeToByteArray())
+ }
+
+ var prBody = ""
+ for ((msg, id) in commits) {
+ prBody += "* $msg [(#${id})](https://github.com/tangcent/easy-api/pull/${id})\n\n"
+ }
+ File("envs/EASY_YAPI_PR_BODY").outputStream().use {
+ it.write(prBody.encodeToByteArray())
+ }
+ }
+}
diff --git a/common-api/build.gradle b/common-api/build.gradle
deleted file mode 100644
index 25313690..00000000
--- a/common-api/build.gradle
+++ /dev/null
@@ -1,69 +0,0 @@
-buildscript {
- repositories {
- mavenCentral()
- }
- dependencies {
- classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
- }
-}
-
-group 'com.itangcent'
-version plugin_version
-
-sourceCompatibility = 1.8
-
-repositories {
-
- mavenCentral()
-
- maven {
- url("https://oss.sonatype.org/content/repositories/snapshots/")
- }
-}
-
-dependencies {
- implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
-
- implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
-
- implementation('com.itangcent:commons:1.4.5') {
- exclude group: 'com.google.inject'
- exclude group: 'com.google.code.gson'
- }
-
- // https://mvnrepository.com/artifact/org.apache.httpcomponents/httpmime
- compileOnly group: 'org.apache.httpcomponents', name: 'httpmime', version: '4.5.10'
-
- // https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient
- compileOnly group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.10'
-
- // https://mvnrepository.com/artifact/org.apache.httpcomponents/httpmime
- testImplementation group: 'org.apache.httpcomponents', name: 'httpmime', version: '4.5.10'
-
- // https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient
- testImplementation group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.10'
-
- // https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api
- testImplementation "org.junit.jupiter:junit-jupiter-api:${junit_version}"
- testImplementation "org.junit.jupiter:junit-jupiter-engine:${junit_version}"
- testImplementation "org.junit.jupiter:junit-jupiter-params:${junit_version}"
- testImplementation "org.jetbrains.kotlin:kotlin-test-junit5:$kotlin_version"
-
- // https://mvnrepository.com/artifact/com.google.code.gson/gson
- testImplementation group: 'com.google.code.gson', name: 'gson', version: '2.8.6'
-
- // https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient
- testImplementation group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.10'
-
- // https://search.maven.org/artifact/org.mockito.kotlin/mockito-kotlin/3.2.0/jar
- testImplementation 'org.mockito.kotlin:mockito-kotlin:3.2.0'
-
- // https://mvnrepository.com/artifact/org.mockito/mockito-inline
- testImplementation group: 'org.mockito', name: 'mockito-inline', version: '3.11.0'
-
-}
-
-
-test {
- useJUnitPlatform()
-}
\ No newline at end of file
diff --git a/common-api/build.gradle.kts b/common-api/build.gradle.kts
new file mode 100644
index 00000000..5b1e8656
--- /dev/null
+++ b/common-api/build.gradle.kts
@@ -0,0 +1,51 @@
+group = "com.itangcent"
+version = properties["plugin_version"]!!
+
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+
+ implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0")
+
+ implementation("org.jetbrains.kotlin:kotlin-reflect:1.8.0")
+
+ implementation("com.itangcent:commons:${properties["itangcent_intellij_version"]}") {
+ exclude("com.google.inject")
+ exclude("com.google.code.gson")
+ }
+
+ // https://mvnrepository.com/artifact/org.apache.httpcomponents/httpmime
+ compileOnly("org.apache.httpcomponents:httpmime:4.5.10")
+
+ // https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient
+ compileOnly("org.apache.httpcomponents:httpclient:4.5.10")
+
+ // https://mvnrepository.com/artifact/org.apache.httpcomponents/httpmime
+ testImplementation("org.apache.httpcomponents:httpmime:4.5.10")
+
+ // https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient
+ testImplementation("org.apache.httpcomponents:httpclient:4.5.10")
+
+ // https://mvnrepository.com/artifact/com.google.code.gson/gson
+ testImplementation("com.google.code.gson:gson:2.8.6")
+
+ // https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient
+ testImplementation("org.apache.httpcomponents:httpclient:4.5.10")
+
+ // https://search.maven.org/artifact/org.mockito.kotlin/mockito-kotlin/3.2.0/jar
+ testImplementation("org.mockito.kotlin:mockito-kotlin:4.1.0")
+
+ // https://mvnrepository.com/artifact/org.mockito/mockito-inline
+ testImplementation("org.mockito:mockito-inline:5.2.0")
+
+ testImplementation("org.junit.jupiter:junit-jupiter-params:${properties["junit_version"]}")
+ testImplementation("org.junit.jupiter:junit-jupiter-api:${properties["junit_version"]}")
+ testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${properties["junit_version"]}")
+ testImplementation("org.jetbrains.kotlin:kotlin-test-junit5:1.8.0")
+}
+
+tasks.getByName("test") {
+ useJUnitPlatform()
+}
\ No newline at end of file
diff --git a/common-api/src/test/kotlin/com/itangcent/common/kit/RequestUtilsTest.kt b/common-api/src/test/kotlin/com/itangcent/common/kit/RequestUtilsTest.kt
index 313feca7..504b4686 100644
--- a/common-api/src/test/kotlin/com/itangcent/common/kit/RequestUtilsTest.kt
+++ b/common-api/src/test/kotlin/com/itangcent/common/kit/RequestUtilsTest.kt
@@ -3,13 +3,12 @@ package com.itangcent.common.kit
import com.itangcent.common.utils.asArrayList
import com.itangcent.common.utils.asHashMap
import com.itangcent.http.RequestUtils
+import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.api.Assertions.assertNull
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.CsvSource
-import java.util.*
-import kotlin.test.assertEquals
-import kotlin.test.assertNull
/**
* Test case for [KitUtils]
@@ -73,7 +72,7 @@ class RequestUtilsTest {
)
fun testConcatPathToA(
pre: String?,
- after: String?
+ after: String?,
) {
assertEquals("a", RequestUtils.concatPath(pre, after))
}
diff --git a/gradle.properties b/gradle.properties
index 6992f65e..1f765921 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,11 +1,6 @@
plugin_name=EasyApi
plugin_version=2.2.3.183.0
-org.gradle.jvmargs=-Dfile.encoding=UTF-8
-systemProp.file.encoding=UTF-8
-org.gradle.daemon=true
-org.gradle.workers.max=8
-idea_version=2019.1.4
-kotlin_version=1.4.31
-junit_version=5.7.1
-descriptionFile=parts/pluginDescription.html
-changesFile=parts/pluginChanges.html
\ No newline at end of file
+kotlin.code.style=official
+kotlin_version=1.8.0
+junit_version=5.9.2
+itangcent_intellij_version=1.4.8
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index cc4fdc29..7454180f 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 8cf6eb5a..e1bef7e8 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
index 62af68b0..1b6c7873 100755
--- a/gradlew
+++ b/gradlew
@@ -1,7 +1,7 @@
-#!/usr/bin/env sh
+#!/bin/sh
#
-# Copyright 2015 the original author or authors.
+# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -17,78 +17,113 @@
#
##############################################################################
-##
-## Gradle start up script for UN*X
-##
+#
+# Gradle start up script for POSIX generated by Gradle.
+#
+# Important for running:
+#
+# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+# noncompliant, but you have some other compliant shell such as ksh or
+# bash, then to run this script, type that shell name before the whole
+# command line, like:
+#
+# ksh Gradle
+#
+# Busybox and similar reduced shells will NOT work, because this script
+# requires all of these POSIX shell features:
+# * functions;
+# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+# * compound commands having a testable exit status, especially «case»;
+# * various built-in commands including «command», «set», and «ulimit».
+#
+# Important for patching:
+#
+# (2) This script targets any POSIX shell, so it avoids extensions provided
+# by Bash, Ksh, etc; in particular arrays are avoided.
+#
+# The "traditional" practice of packing multiple parameters into a
+# space-separated string is a well documented source of bugs and security
+# problems, so this is (mostly) avoided, by progressively accumulating
+# options in "$@", and eventually passing that to Java.
+#
+# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+# see the in-line comments for details.
+#
+# There are tweaks for specific operating systems such as AIX, CygWin,
+# Darwin, MinGW, and NonStop.
+#
+# (3) This script is generated from the Groovy template
+# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# within the Gradle project.
+#
+# You can find Gradle at https://github.com/gradle/gradle/.
+#
##############################################################################
# Attempt to set APP_HOME
+
# Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
- ls=`ls -ld "$PRG"`
- link=`expr "$ls" : '.*-> \(.*\)$'`
- if expr "$link" : '/.*' > /dev/null; then
- PRG="$link"
- else
- PRG=`dirname "$PRG"`"/$link"
- fi
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
+ [ -h "$app_path" ]
+do
+ ls=$( ls -ld "$app_path" )
+ link=${ls#*' -> '}
+ case $link in #(
+ /*) app_path=$link ;; #(
+ *) app_path=$APP_HOME$link ;;
+ esac
done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >/dev/null
-APP_HOME="`pwd -P`"
-cd "$SAVED" >/dev/null
+
+APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
-APP_BASE_NAME=`basename "$0"`
+APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m" "-Dfile.encoding=UTF-8"'
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD="maximum"
+MAX_FD=maximum
warn () {
echo "$*"
-}
+} >&2
die () {
echo
echo "$*"
echo
exit 1
-}
+} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
-case "`uname`" in
- CYGWIN* )
- cygwin=true
- ;;
- Darwin* )
- darwin=true
- ;;
- MINGW* )
- msys=true
- ;;
- NONSTOP* )
- nonstop=true
- ;;
+case "$( uname )" in #(
+ CYGWIN* ) cygwin=true ;; #(
+ Darwin* ) darwin=true ;; #(
+ MSYS* | MINGW* ) msys=true ;; #(
+ NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
- JAVACMD="$JAVA_HOME/jre/sh/java"
+ JAVACMD=$JAVA_HOME/jre/sh/java
else
- JAVACMD="$JAVA_HOME/bin/java"
+ JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@@ -97,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
- JAVACMD="java"
+ JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
@@ -105,79 +140,95 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
- MAX_FD_LIMIT=`ulimit -H -n`
- if [ $? -eq 0 ] ; then
- if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
- MAX_FD="$MAX_FD_LIMIT"
- fi
- ulimit -n $MAX_FD
- if [ $? -ne 0 ] ; then
- warn "Could not set maximum file descriptor limit: $MAX_FD"
- fi
- else
- warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
- fi
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+ case $MAX_FD in #(
+ max*)
+ MAX_FD=$( ulimit -H -n ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | soft) :;; #(
+ *)
+ ulimit -n "$MAX_FD" ||
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
+ esac
fi
-# For Darwin, add options to specify how the application appears in the dock
-if $darwin; then
- GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
-fi
+# Collect all arguments for the java command, stacking in reverse order:
+# * args from the command line
+# * the main class name
+# * -classpath
+# * -D...appname settings
+# * --module-path (only if needed)
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
-if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
- APP_HOME=`cygpath --path --mixed "$APP_HOME"`
- CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
- JAVACMD=`cygpath --unix "$JAVACMD"`
-
- # We build the pattern for arguments to be converted via cygpath
- ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
- SEP=""
- for dir in $ROOTDIRSRAW ; do
- ROOTDIRS="$ROOTDIRS$SEP$dir"
- SEP="|"
- done
- OURCYGPATTERN="(^($ROOTDIRS))"
- # Add a user-defined pattern to the cygpath arguments
- if [ "$GRADLE_CYGPATTERN" != "" ] ; then
- OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
- fi
+if "$cygwin" || "$msys" ; then
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
+
# Now convert the arguments - kludge to limit ourselves to /bin/sh
- i=0
- for arg in "$@" ; do
- CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
- CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
-
- if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
- eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
- else
- eval `echo args$i`="\"$arg\""
+ for arg do
+ if
+ case $arg in #(
+ -*) false ;; # don't mess with options #(
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
+ [ -e "$t" ] ;; #(
+ *) false ;;
+ esac
+ then
+ arg=$( cygpath --path --ignore --mixed "$arg" )
fi
- i=`expr $i + 1`
+ # Roll the args list around exactly as many times as the number of
+ # args, so each arg winds up back in the position where it started, but
+ # possibly modified.
+ #
+ # NB: a `for` loop captures its iteration list before it begins, so
+ # changing the positional parameters here affects neither the number of
+ # iterations, nor the values presented in `arg`.
+ shift # remove old arg
+ set -- "$@" "$arg" # push replacement arg
done
- case $i in
- 0) set -- ;;
- 1) set -- "$args0" ;;
- 2) set -- "$args0" "$args1" ;;
- 3) set -- "$args0" "$args1" "$args2" ;;
- 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
- 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
- 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
- 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
- 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
- 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
- esac
fi
-# Escape application args
-save () {
- for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
- echo " "
-}
-APP_ARGS=`save "$@"`
+# Collect all arguments for the java command;
+# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
+# shell script including quotes and variable substitutions, so put them in
+# double quotes to make sure that they get re-expanded; and
+# * put everything else in single quotes, so that it's not re-expanded.
+
+set -- \
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \
+ -classpath "$CLASSPATH" \
+ org.gradle.wrapper.GradleWrapperMain \
+ "$@"
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+# set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
-# Collect all arguments for the java command, following the shell quoting and substitution rules
-eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+eval "set -- $(
+ printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+ xargs -n1 |
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+ tr '\n' ' '
+ )" '"$@"'
exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
index 2a0d461f..ac1b06f9 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -29,16 +29,18 @@ if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" "-Dfile.encoding=UTF-8"
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto init
+if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -52,7 +54,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-if exist "%JAVA_EXE%" goto init
+if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@@ -62,28 +64,14 @@ echo location of your Java installation.
goto fail
-:init
-@rem Get command-line arguments, handling Windows variants
-
-if not "%OS%" == "Windows_NT" goto win9xME_args
-
-:win9xME_args
-@rem Slurp the command line arguments.
-set CMD_LINE_ARGS=
-set _SKIP=2
-
-:win9xME_args_slurp
-if "x%~1" == "x" goto execute
-
-set CMD_LINE_ARGS=%*
-
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
diff --git a/idea-plugin/build.gradle b/idea-plugin/build.gradle
deleted file mode 100644
index 5c23eb2d..00000000
--- a/idea-plugin/build.gradle
+++ /dev/null
@@ -1,203 +0,0 @@
-buildscript {
-
- repositories {
- mavenCentral()
- }
-
- dependencies {
- classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
- }
-}
-
-plugins {
- //https://mvnrepository.com/artifact/org.jetbrains.intellij/org.jetbrains.intellij.gradle.plugin
- id "org.jetbrains.intellij" version "0.4.11"
-}
-
-group 'com.itangcent'
-version plugin_version
-
-apply plugin: 'org.jetbrains.intellij'
-apply plugin: 'idea'
-sourceCompatibility = 1.8
-
-intellij {
- version idea_version
- pluginName plugin_name
- updateSinceUntilBuild false
- downloadSources true
- sandboxDirectory "idea-sandbox"
- instrumentCode = true
- updateSinceUntilBuild false
- sameSinceUntilBuild false
-
- //plugins "org.jetbrains.kotlin:1.3.11-release-IJ2017.3-1"
- //plugins "org.jetbrains.kotlin:1.3.11-release-IJ2017.3-1", "org.intellij.scala:2017.3.11"
- //plugins 'org.jetbrains.kotlin:1.3.21-release-IJ2018.2-1' //dependency kotlin
-
-
-// plugins = ['java']
-}
-
-task javadocJar(type: Jar, dependsOn: javadoc) {
- classifier = 'javadoc'
- from 'build/docs/javadoc'
-}
-
-task sourcesJar(type: Jar) {
- classifier = 'sources'
- from sourceSets.main.allSource
-}
-
-patchPluginXml {
- pluginDescription(file(descriptionFile).text)
- changeNotes(file(changesFile).text)
-}
-
-artifacts {
- archives jar
- archives javadocJar
- archives sourcesJar
-}
-
-repositories {
-
- mavenCentral()
-
-}
-
-dependencies {
- implementation(project(path: ':common-api', configuration: 'default')) {
- exclude group: 'org.apache.httpcomponents', module: 'httpclient'
- }
-
- compileOnly "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
-
-// implementation fileTree(dir: 'libs', include: ['*.jar'])
-
-
- implementation('com.itangcent:intellij-idea:1.4.5') {
- exclude group: 'com.google.inject'
- exclude group: 'com.google.code.gson'
- }
-
- implementation('com.itangcent:intellij-kotlin-support:1.4.5') {
- exclude group: 'com.google.inject'
- exclude group: 'com.google.code.gson'
- }
-
- implementation('com.itangcent:intellij-groovy-support:1.4.5') {
- exclude group: 'com.google.inject'
- exclude group: 'com.google.code.gson'
- }
-
-// implementation('com.itangcent:intellij-scala-support:1.4.5') {
-// exclude group: 'com.google.inject'
-// exclude group: 'com.google.code.gson'
-// }
-
- implementation("com.google.inject:guice:4.2.2") {
- exclude group: 'org.checkerframework', module: 'checker-compat-qual'
- exclude group: 'com.google.guava', module: 'guava'
- }
-
- implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
-
- // https://mvnrepository.com/artifact/org.jsoup/jsoup
- implementation group: 'org.jsoup', name: 'jsoup', version: '1.12.1'
-
- // https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind
- implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.12.2'
-
- // https://mvnrepository.com/artifact/org.xerial/sqlite-jdbc
- implementation group: 'org.xerial', name: 'sqlite-jdbc', version: '3.34.0'
-
- // https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api
- testImplementation "org.junit.jupiter:junit-jupiter-api:${junit_version}"
- testImplementation "org.junit.jupiter:junit-jupiter-engine:${junit_version}"
- testImplementation "org.junit.jupiter:junit-jupiter-params:${junit_version}"
- testRuntime("org.junit.vintage:junit-vintage-engine:5.7.1")
- testImplementation "org.jetbrains.kotlin:kotlin-test-junit5:$kotlin_version"
-
- // https://search.maven.org/artifact/org.mockito.kotlin/mockito-kotlin/3.2.0/jar
- testImplementation 'org.mockito.kotlin:mockito-kotlin:3.2.0'
-
- // https://mvnrepository.com/artifact/org.mockito/mockito-inline
- testImplementation group: 'org.mockito', name: 'mockito-inline', version: '3.11.0'
-
- testImplementation('com.itangcent:intellij-idea-test:1.4.5') {
- exclude group: 'com.nhaarman.mockitokotlin2', module: 'mockito-kotlin'
- }
-}
-
-compileKotlin {
- kotlinOptions.jvmTarget = "1.8"
-}
-compileTestKotlin {
- kotlinOptions.jvmTarget = "1.8"
-}
-
-task findSpi {
- doLast {
- try {
- def names = [] as Set
- def duplicated = [] as Set
- //find duplicated files
- configurations.compile.forEach {
- if (it.isFile()) {
- zipTree(it)
- .filter { it.parentFile.path.endsWith("META-INF/services") }
- .forEach {
- if (!names.add(it.name)) {
- if (!duplicated.contains(it.name)) {
- duplicated.add(it.name)
- }
- }
- }
- }
- }
-
- def servicesDir = new File("./src/main/resources/META-INF/services/")
- servicesDir.delete()
- servicesDir.mkdirs()
-
- duplicated.forEach {
- try {
- def targetFile = new File(servicesDir, it)
- targetFile.createNewFile()
- targetFile.text = ""
- } catch (e) {
- println("error:" + e)
- }
- }
-
- configurations.compile.forEach {
- if (it.isFile()) {
- zipTree(it)
- .filter {
- it.parentFile.path.endsWith("META-INF/services") &&
- duplicated.contains(it.name)
- }
- .forEach {
- try {
- def targetFile = new File(servicesDir, it.name)
- if (!targetFile.exists()) {
- targetFile.createNewFile()
- }
- targetFile.append(it.text)
- targetFile.append("\n")
- } catch (e) {
- println("error to append services info to:" + it.name + e)
- }
- }
- }
- }
- } catch (e) {
- println("error to find spi:" + e)
- }
- }
-}
-
-test {
- useJUnitPlatform()
-}
\ No newline at end of file
diff --git a/idea-plugin/build.gradle.kts b/idea-plugin/build.gradle.kts
new file mode 100644
index 00000000..8bffe8fb
--- /dev/null
+++ b/idea-plugin/build.gradle.kts
@@ -0,0 +1,107 @@
+plugins {
+ id("org.jetbrains.intellij") version "1.13.2"
+}
+
+group = "com.itangcent"
+version = properties["plugin_version"]!!
+
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+
+ implementation(project(":common-api")) {
+ exclude("org.apache.httpcomponents", "httpclient")
+ }
+
+ implementation("com.itangcent:commons:${properties["itangcent_intellij_version"]}") {
+ exclude("com.google.inject")
+ exclude("com.google.code.gson")
+ }
+
+
+ implementation("com.itangcent:guice-action:${properties["itangcent_intellij_version"]}") {
+ exclude("com.google.inject")
+ exclude("com.google.code.gson")
+ }
+
+ implementation("com.itangcent:intellij-jvm:${properties["itangcent_intellij_version"]}") {
+ exclude("com.google.inject")
+ exclude("com.google.code.gson")
+ }
+
+ implementation("com.itangcent:intellij-idea:${properties["itangcent_intellij_version"]}") {
+ exclude("com.google.inject")
+ exclude("com.google.code.gson")
+ }
+
+ implementation("com.itangcent:intellij-kotlin-support:${properties["itangcent_intellij_version"]}") {
+ exclude("com.google.inject")
+ exclude("com.google.code.gson")
+ }
+
+ implementation("com.itangcent:intellij-groovy-support:${properties["itangcent_intellij_version"]}") {
+ exclude("com.google.inject")
+ exclude("com.google.code.gson")
+ }
+
+// implementation("com.itangcent:intellij-scala-support:${properties["itangcent_intellij_version"]}") {
+// exclude("com.google.inject")
+// exclude("com.google.code.gson")
+// }
+
+ implementation("com.google.inject:guice:4.2.2") {
+ exclude("org.checkerframework", "checker-compat-qual")
+ exclude("com.google.guava", "guava")
+ }
+
+ implementation("org.jetbrains.kotlin:kotlin-reflect:1.8.0")
+
+ // https://mvnrepository.com/artifact/org.jsoup/jsoup
+ implementation("org.jsoup:jsoup:1.12.1")
+
+ // https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind
+ implementation("com.fasterxml.jackson.core:jackson-databind:2.12.2")
+
+ // https://mvnrepository.com/artifact/org.xerial/sqlite-jdbc
+ implementation("org.xerial:sqlite-jdbc:3.34.0")
+
+ // https://search.maven.org/artifact/org.mockito.kotlin/mockito-kotlin/3.2.0/jar
+ testImplementation("org.mockito.kotlin:mockito-kotlin:3.2.0")
+
+ // https://mvnrepository.com/artifact/org.mockito/mockito-inline
+ testImplementation("org.mockito:mockito-inline:3.11.0")
+
+ testImplementation("com.itangcent:intellij-idea-test:${properties["itangcent_intellij_version"]}")
+
+ testImplementation("org.jetbrains.kotlin:kotlin-test")
+
+ testImplementation("org.junit.jupiter:junit-jupiter-params:${properties["junit_version"]}")
+ testImplementation("org.junit.jupiter:junit-jupiter-api:${properties["junit_version"]}")
+ testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${properties["junit_version"]}")
+ testRuntimeOnly("org.junit.vintage:junit-vintage-engine:5.7.1")
+ testImplementation("org.jetbrains.kotlin:kotlin-test-junit5:1.8.0")
+}
+
+tasks.getByName("test") {
+ useJUnitPlatform()
+}
+
+intellij {
+ version.set("2021.2.1")
+ type.set("IC")
+ pluginName.set("easy-api")
+ sandboxDir.set("idea-sandbox")
+ plugins.set(listOf("java"))
+}
+
+tasks {
+ patchPluginXml {
+ pluginDescription.set(file("parts/pluginDescription.html").readText())
+ changeNotes.set(file("parts/pluginChanges.html").readText())
+
+ sinceBuild.set("212")
+ untilBuild.set("")
+ }
+}
diff --git a/idea-plugin/src/main/kotlin/com/itangcent/idea/icons/EasyIcons.kt b/idea-plugin/src/main/kotlin/com/itangcent/idea/icons/EasyIcons.kt
index 5ca58327..18f79127 100644
--- a/idea-plugin/src/main/kotlin/com/itangcent/idea/icons/EasyIcons.kt
+++ b/idea-plugin/src/main/kotlin/com/itangcent/idea/icons/EasyIcons.kt
@@ -1,8 +1,8 @@
package com.itangcent.idea.icons
-import com.intellij.openapi.util.IconLoader
import com.intellij.util.ReflectionUtil
import com.itangcent.common.logger.Log
+import com.itangcent.common.spi.SpiUtils
import com.itangcent.common.utils.invokeMethod
import com.itangcent.common.utils.safe
import com.itangcent.idea.utils.setSizeIfNecessary
@@ -13,56 +13,66 @@ import java.net.URL
import javax.swing.AbstractButton
import javax.swing.Icon
+
/**
* @see com.intellij.icons.AllIcons
*/
object EasyIcons : Log() {
- val WebFolder = tryLoad("/nodes/webFolder.png") // 16x16
+ private val iconLoader: IconLoader by lazy {
+ SpiUtils.loadService(IconLoader::class) ?: DefaultIconLoader
+ }
+
+ val WebFolder by lazyLoad(
+ "/nodes/webFolder.png",
+ "nodes/folder.png"
+ ) // 16x16
- val Class = tryLoad("/nodes/class.png") // 16x16
+ val Class by lazyLoad("/nodes/class.png") // 16x16
- val Method = tryLoad("/nodes/method.png") // 16x16
+ val Method by lazyLoad("/nodes/method.png")// 16x16
- val CollapseAll = tryLoad(
+ val CollapseAll by lazyLoad(
"/general/collapseAll.png",
"actions/collapseall.png"
) // 11x16
- val Add = tryLoad("/general/add.png") // 16x16
+ val Add by lazyLoad("/general/add.png") // 16x16
- val Remove = tryLoad("/general/remove.png") // 16x16
+ val Remove by lazyLoad("/general/remove.png") // 16x16
- val Refresh = tryLoad("/actions/refresh.png") // 16x16
+ val Refresh by lazyLoad("/actions/refresh.png") // 16x16
- val Link = tryLoad("/ide/link.png") // 12x12
+ val Link by lazyLoad("/ide/link.png") // 12x12
- val Run = tryLoad(
+ val Run by lazyLoad(
"/general/run.png",
"/general/run@2x.png",
"/runConfigurations/testState/run.png",
"/runConfigurations/testState/run@2x.png"
) // 7x10
- val Module = tryLoad("/nodes/Module.png") // 16x16
+ val Module by lazyLoad("/nodes/Module.png") // 16x16
- val ModuleGroup = tryLoad("/nodes/moduleGroup.png") // 16x16
+ val ModuleGroup by lazyLoad("/nodes/moduleGroup.png") // 16x16
- val UpFolder = tryLoad("/nodes/upFolder.png") // 16x16
+ val UpFolder by lazyLoad("/nodes/upFolder.png") // 16x16
- val Close = tryLoad(
- "/notification/close.png",
- "/actions/close.png"
- )
- ?: tryLoadByUrl(URL("https://raw.githubusercontent.com/tangcent/easy-api/blob/master/assets/close.png"))
+ val Close by lazy {
+ tryLoad(
+ "/notification/close.png",
+ "/actions/close.png"
+ ) ?: tryLoadByUrl(URL("https://raw.githubusercontent.com/tangcent/easy-api/blob/master/assets/close.png"))
+ }
- val OK = tryLoad(
- "/general/inspectionsOK.png",
- "/process/state/GreenOK.png"
- )
- ?: tryLoadByUrl(URL("https://raw.githubusercontent.com/tangcent/easy-api/blob/master/assets/ok.png"))
+ val OK by lazy {
+ tryLoad(
+ "/general/inspectionsOK.png",
+ "/process/state/GreenOK.png"
+ ) ?: tryLoadByUrl(URL("https://raw.githubusercontent.com/tangcent/easy-api/blob/master/assets/ok.png"))
+ }
- val Export = tryLoad(
+ val Export by lazyLoad(
"/toolbarDecorator/export.svg",
"/toolbarDecorator/export.png",
"/general/ExportSettings.png",
@@ -70,7 +80,7 @@ object EasyIcons : Log() {
"/actions/export.png"
)
- val Import = tryLoad(
+ val Import by lazyLoad(
"/toolbarDecorator/import.svg",
"/toolbarDecorator/import.png",
"/general/ImportSettings.png",
@@ -78,33 +88,32 @@ object EasyIcons : Log() {
"/css/import.png"
)
+ private fun lazyLoad(vararg paths: String): Lazy = lazy { tryLoad(*paths) }
+
private fun tryLoad(vararg paths: String): Icon? {
for (path in paths) {
try {
- getIcon(path)?.takeIf {
- it.iconWidth > 2 && it.iconHeight > 2
- }?.let { return it }
+ getIcon(path)
+ ?.takeIf {
+ it.iconWidth > 2 && it.iconHeight > 2
+ }
+ ?.let { return it }
} catch (_: Exception) {
}
}
- LOG.error("non icon be found in ${paths}")
+ LOG.error("non icon be found in $paths")
return null
}
private fun getIcon(@NonNls path: String): Icon? {
- val callerClass = ReflectionUtil.getGrandCallerClass()
- if (callerClass == null) {
- debug("getGrandCallerClass failed")
- return null
- }
-
- return IconLoader.findIcon(path, callerClass)
+ val callerClass = ReflectionUtil.getGrandCallerClass() ?: this::class.java
+ return iconLoader.findIcon(path, callerClass)
}
private fun tryLoadByUrl(vararg paths: URL): Icon? {
for (path in paths) {
try {
- IconLoader.findIcon(path)?.let { return it }
+ iconLoader.findIcon(path)?.let { return it }
} catch (_: Exception) {
}
}
@@ -112,6 +121,22 @@ object EasyIcons : Log() {
}
}
+
+interface IconLoader {
+ fun findIcon(path: String, aClass: Class<*>): Icon?
+ fun findIcon(url: URL?): Icon?
+}
+
+object DefaultIconLoader : IconLoader {
+ override fun findIcon(path: String, aClass: Class<*>): Icon? {
+ return com.intellij.openapi.util.IconLoader.findIcon(path, aClass)
+ }
+
+ override fun findIcon(url: URL?): Icon? {
+ return com.intellij.openapi.util.IconLoader.findIcon(url)
+ }
+}
+
fun Icon?.iconOnly(component: Component?) {
if (this == null || component == null) {
return
diff --git a/idea-plugin/src/main/resources/META-INF/plugin.xml b/idea-plugin/src/main/resources/META-INF/plugin.xml
index 5c5b917d..9f2b8cf4 100644
--- a/idea-plugin/src/main/resources/META-INF/plugin.xml
+++ b/idea-plugin/src/main/resources/META-INF/plugin.xml
@@ -9,13 +9,13 @@
Web
-
+
-
+
diff --git a/idea-plugin/src/test/kotlin/com/itangcent/idea/plugin/api/export/core/ReservedResponseHandleTest.kt b/idea-plugin/src/test/kotlin/com/itangcent/idea/plugin/api/export/core/ReservedResponseHandleTest.kt
index 32121b66..e008bc7f 100644
--- a/idea-plugin/src/test/kotlin/com/itangcent/idea/plugin/api/export/core/ReservedResponseHandleTest.kt
+++ b/idea-plugin/src/test/kotlin/com/itangcent/idea/plugin/api/export/core/ReservedResponseHandleTest.kt
@@ -17,7 +17,6 @@ import kotlin.test.assertSame
*/
internal class ReservedResponseHandleTest {
- @Suppress("TYPE_INFERENCE_ONLY_INPUT_TYPES_WARNING")
@Test
fun testHandleResponse() {
val httpResponse = Mockito.mock(HttpResponse::class.java)
@@ -34,7 +33,7 @@ internal class ReservedResponseHandleTest {
val stringResponseHandler = StringResponseHandler()
val reservedResponseHandle = stringResponseHandler.reserved()
assertSame(reservedResponseHandle, stringResponseHandler.reserved())
- assertSame(reservedResponseHandle, reservedResponseHandle.reserved())
+ assertSame(reservedResponseHandle, reservedResponseHandle.reserved())
val reservedResult = reservedResponseHandle.handleResponse(httpResponse)
assertEquals("hello world", reservedResult.result())
assertEquals("hello world", reservedResult.result())//again
diff --git a/idea-plugin/src/test/kotlin/com/itangcent/idea/utils/DefaultModuleHelperTest.kt b/idea-plugin/src/test/kotlin/com/itangcent/idea/utils/DefaultModuleHelperTest.kt
index 46fe34f5..9825eff5 100644
--- a/idea-plugin/src/test/kotlin/com/itangcent/idea/utils/DefaultModuleHelperTest.kt
+++ b/idea-plugin/src/test/kotlin/com/itangcent/idea/utils/DefaultModuleHelperTest.kt
@@ -42,16 +42,16 @@ internal class DefaultModuleHelperTest : PluginContextLightCodeInsightFixtureTes
fun testFindModule() {
assertEquals(null, moduleHelper.findModule("any thing"))
- assertEquals(this.myModule.name, moduleHelper.findModule(testCtrlPsiFile))
- assertEquals(this.myModule.name, moduleHelper.findModule(testCtrlPsiFile as Any))
- assertEquals(this.myModule.name, moduleHelper.findModule(testCtrlPsiClass))
- assertEquals(this.myModule.name, moduleHelper.findModule(testCtrlPsiClass as Any))
- assertEquals(this.myModule.name, moduleHelper.findModule(PsiClassResource(testCtrlPsiClass)))
+ assertEquals(this.module.name, moduleHelper.findModule(testCtrlPsiFile))
+ assertEquals(this.module.name, moduleHelper.findModule(testCtrlPsiFile as Any))
+ assertEquals(this.module.name, moduleHelper.findModule(testCtrlPsiClass))
+ assertEquals(this.module.name, moduleHelper.findModule(testCtrlPsiClass as Any))
+ assertEquals(this.module.name, moduleHelper.findModule(PsiClassResource(testCtrlPsiClass)))
assertEquals("test-only", moduleHelper.findModule(testCtrlPsiClass.methods[0]))
assertEquals("test-only", moduleHelper.findModule(testCtrlPsiClass.methods[0] as Any))
assertEquals("test-only", moduleHelper.findModule(PsiMethodResource(testCtrlPsiClass.methods[0], testCtrlPsiClass)))
- assertEquals(this.myModule.name, moduleHelper.findModule(userCtrlPsiFile))
- assertEquals(this.myModule.name, moduleHelper.findModule(userCtrlPsiFile as Any))
+ assertEquals(this.module.name, moduleHelper.findModule(userCtrlPsiFile))
+ assertEquals(this.module.name, moduleHelper.findModule(userCtrlPsiFile as Any))
assertEquals("users", moduleHelper.findModule(userCtrlPsiClass))
assertEquals("users", moduleHelper.findModule(userCtrlPsiClass as Any))
assertEquals("users", moduleHelper.findModule(userCtrlPsiClass.methods[0]))
diff --git a/idea-plugin/src/test/kotlin/com/itangcent/test/IconLoaderHeadlessSupport.kt b/idea-plugin/src/test/kotlin/com/itangcent/test/IconLoaderHeadlessSupport.kt
new file mode 100644
index 00000000..0dff0868
--- /dev/null
+++ b/idea-plugin/src/test/kotlin/com/itangcent/test/IconLoaderHeadlessSupport.kt
@@ -0,0 +1,92 @@
+package com.itangcent.test
+
+import com.itangcent.common.logger.Log
+import com.itangcent.idea.icons.DefaultIconLoader
+import com.itangcent.idea.icons.IconLoader
+import java.awt.Component
+import java.awt.Graphics
+import java.awt.GraphicsEnvironment
+import java.awt.image.RenderedImage
+import java.net.URL
+import javax.imageio.ImageIO
+import javax.swing.Icon
+
+class IconLoaderHeadlessSupport : IconLoader {
+
+ companion object : Log()
+
+ private val isActivated = !GraphicsEnvironment.isHeadless()
+
+ override fun findIcon(path: String, aClass: Class<*>): Icon? {
+ if (isActivated) return DefaultIconLoader.findIcon(path, aClass)
+ val url = resolve(path, aClass.classLoader, aClass)
+ return findIcon(url)
+ }
+
+ override fun findIcon(url: URL?): Icon? {
+ if (url == null) {
+ return null
+ }
+ val image = ImageIO.read(url)
+ return HeadlessIcon(image)
+ }
+
+ private fun resolve(
+ path: String?,
+ classLoader: ClassLoader?,
+ ownerClass: Class<*>?,
+ ): URL? {
+ var resolvedPath = path
+ var url: URL? = null
+ if (resolvedPath != null) {
+ if (classLoader != null) {
+ // paths in ClassLoader getResource must not start with "/"
+ resolvedPath = if (resolvedPath[0] == '/') resolvedPath.substring(1) else resolvedPath
+ url = findUrl(resolvedPath) { classLoader.getResource(it) }
+ }
+ if (url == null && ownerClass != null) {
+ // some plugins use findIcon("icon.png",IconContainer.class)
+ url = findUrl(resolvedPath) { ownerClass.getResource(it) }
+ }
+ }
+ if (url == null) {
+ LOG.warn("Can't find icon in '$resolvedPath' near $classLoader")
+ }
+ return url
+ }
+
+ private fun findUrl(path: String, urlProvider: (String) -> URL?): URL? {
+ var path = path
+ val url = urlProvider(path)
+ if (url != null) {
+ return url
+ }
+
+ // Find either PNG or SVG icon. The icon will then be wrapped into CachedImageIcon
+ // which will load proper icon version depending on the context - UI theme, DPI.
+ // SVG version, when present, has more priority than PNG.
+ // See for details: com.intellij.util.ImageLoader.ImageDescList#create
+ if (path.endsWith(".png")) {
+ path = path.substring(0, path.length - 4) + ".svg"
+ } else if (path.endsWith(".svg")) {
+ path = path.substring(0, path.length - 4) + ".png"
+ } else {
+ LOG.debug("unexpected path: $path")
+ }
+ return urlProvider(path)
+ }
+}
+
+private class HeadlessIcon(private val image: RenderedImage) : Icon {
+ override fun paintIcon(c: Component?, g: Graphics?, x: Int, y: Int) {
+ //NOP
+ }
+
+ override fun getIconWidth(): Int {
+ return image.width
+ }
+
+ override fun getIconHeight(): Int {
+ return image.height
+ }
+}
\ No newline at end of file
diff --git a/idea-plugin/src/test/kotlin/com/itangcent/testFramework/PluginContextLightCodeInsightFixtureTestCase.kt b/idea-plugin/src/test/kotlin/com/itangcent/testFramework/PluginContextLightCodeInsightFixtureTestCase.kt
index ec735492..f0bcb361 100644
--- a/idea-plugin/src/test/kotlin/com/itangcent/testFramework/PluginContextLightCodeInsightFixtureTestCase.kt
+++ b/idea-plugin/src/test/kotlin/com/itangcent/testFramework/PluginContextLightCodeInsightFixtureTestCase.kt
@@ -11,10 +11,8 @@ import com.itangcent.intellij.extend.guice.with
import com.itangcent.mock.ConstantModuleHelper
import com.itangcent.mock.EmptyMessagesHelper
import com.itangcent.mock.SettingBinderAdaptor
-import org.junit.jupiter.api.condition.DisabledOnJre
-@DisabledOnJre
abstract class PluginContextLightCodeInsightFixtureTestCase : ContextLightCodeInsightFixtureTestCase() {
override fun bind(builder: ActionContext.ActionContextBuilder) {
diff --git a/idea-plugin/src/test/resources/META-INF/services/com.itangcent.idea.icons.IconLoader b/idea-plugin/src/test/resources/META-INF/services/com.itangcent.idea.icons.IconLoader
new file mode 100644
index 00000000..907365ed
--- /dev/null
+++ b/idea-plugin/src/test/resources/META-INF/services/com.itangcent.idea.icons.IconLoader
@@ -0,0 +1 @@
+com.itangcent.test.IconLoaderHeadlessSupport
\ No newline at end of file
diff --git a/idea-plugin/src/test/resources/model/UserInfo.java b/idea-plugin/src/test/resources/model/UserInfo.java
index ab38ab06..bd0fb432 100644
--- a/idea-plugin/src/test/resources/model/UserInfo.java
+++ b/idea-plugin/src/test/resources/model/UserInfo.java
@@ -13,16 +13,20 @@ public class UserInfo {
private Long id = 0;//user id
/**
+ * user type
+ *
* @see com.itangcent.constant.UserType
*/
- private int type;//user type
+ private int type;
/**
+ * user name
+ *
* @default tangcent
* @mock tangcent
*/
@NotBlank
- private String name;//user name
+ private String name;
/**
* user age
@@ -38,10 +42,14 @@ public class UserInfo {
*/
private Integer sex;
- //user birthDay
+ /**
+ * user birthDay
+ */
private LocalDate birthDay;
- //user regtime
+ /**
+ * user regtime
+ */
private LocalDateTime regtime;
public Long getId() {
diff --git a/settings.gradle b/settings.gradle
deleted file mode 100644
index 41988884..00000000
--- a/settings.gradle
+++ /dev/null
@@ -1,4 +0,0 @@
-rootProject.name = 'easy-api'
-include 'idea-plugin'
-include 'common-api'
-
diff --git a/settings.gradle.kts b/settings.gradle.kts
new file mode 100644
index 00000000..9bba2b93
--- /dev/null
+++ b/settings.gradle.kts
@@ -0,0 +1,3 @@
+rootProject.name = "easy-api"
+include(":common-api", ":idea-plugin")
+