From 61791972c8f8d3f1e5d4760874129bcfb60157cf Mon Sep 17 00:00:00 2001 From: Phodal Huang Date: Tue, 18 Jul 2023 09:20:02 +0800 Subject: [PATCH] feat: init plugin modules for like clinon --- .idea/gradle.xml | 1 + build.gradle.kts | 211 ++++++++++++++++++++++++++++++++++++---- gradle.properties | 6 ++ plugin/description.html | 1 + settings.gradle.kts | 2 + 5 files changed, 203 insertions(+), 18 deletions(-) create mode 100644 plugin/description.html diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 39abb8ac88..6ad16331a4 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -10,6 +10,7 @@ diff --git a/build.gradle.kts b/build.gradle.kts index ce1fd44785..ec8279f678 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,26 +1,47 @@ +import groovy.xml.XmlParser import org.gradle.api.JavaVersion.VERSION_17 import org.jetbrains.changelog.Changelog +import org.jetbrains.intellij.tasks.PatchPluginXmlTask +import org.jetbrains.intellij.tasks.PublishPluginTask +import org.jetbrains.intellij.tasks.RunIdeTask import org.jetbrains.kotlin.gradle.tasks.KotlinCompile -buildscript { - repositories { - maven { - url = uri("https://plugins.gradle.org/m2/") - } - } -} - -fun properties(key: String) = providers.gradleProperty(key) -fun environment(key: String) = providers.environmentVariable(key) - plugins { id("java") // Java support - alias(libs.plugins.kotlin) // Kotlin support - alias(libs.plugins.gradleIntelliJPlugin) // Gradle IntelliJ Plugin alias(libs.plugins.changelog) // Gradle Changelog Plugin alias(libs.plugins.qodana) // Gradle Qodana Plugin alias(libs.plugins.kover) // Gradle Kover Plugin alias(libs.plugins.serialization) + + kotlin("jvm") version "1.8.22" + id("org.jetbrains.intellij") version "1.13.1" + id("net.saliman.properties") version "1.5.2" +} + +fun properties(key: String) = providers.gradleProperty(key) +fun environment(key: String) = providers.environmentVariable(key) + +fun prop(name: String): String = + extra.properties[name] as? String + ?: error("Property `$name` is not defined in gradle.properties") + +val basePluginArchiveName = "autodev" + +val pycharmPlugins: List = listOf() +val ideaPlugins = listOf("com.intellij.java", "org.jetbrains.plugins.gradle") + +val pluginProjects: List get() = rootProject.allprojects.toList() + +val javaPlugin = "com.intellij.java" +val baseIDE = prop("baseIDE") +val platformVersion = prop("globalPlatformVersion").toInt() +val ideaVersion = prop("ideaVersion") +val pycharmVersion = prop("pycharmVersion") + +val baseVersion = when (baseIDE) { + "idea" -> ideaVersion + "pycharm" -> pycharmVersion + else -> error("Unexpected IDE name: `$baseIDE`") } group = properties("pluginGroup").get() @@ -61,7 +82,6 @@ allprojects { plugin("org.jetbrains.intellij") } - repositories { mavenCentral() maven("https://cache-redirector.jetbrains.com/repo.maven.apache.org/maven2") @@ -74,6 +94,13 @@ allprojects { } } + intellij { + version.set(baseVersion) + updateSinceUntilBuild.set(true) + instrumentCode.set(false) + sandboxDir.set("$buildDir/$baseIDE-sandbox-$platformVersion") + } + configure { sourceCompatibility = VERSION_17 targetCompatibility = VERSION_17 @@ -89,13 +116,142 @@ allprojects { freeCompilerArgs = listOf("-Xjvm-default=all") } } + + withType { + sinceBuild.set(prop("pluginSinceBuild")) + untilBuild.set(prop("pluginUntilBuild")) + } + + // All these tasks don't make sense for non-root subprojects + // Root project (i.e. `:plugin`) enables them itself if needed + runIde { enabled = false } + prepareSandbox { enabled = false } + buildSearchableOptions { enabled = false } + } +} + +project(":plugin") { + intellij { + pluginName.set("autodev") + val pluginList: MutableList = mutableListOf() + if (baseIDE == "idea") { + pluginList += listOf( + javaPlugin, + ) + } + plugins.set(pluginList) + } + + dependencies { + implementation(project(":")) + implementation(project(":idea")) + implementation(project(":pycharm")) + } + + // Collects all jars produced by compilation of project modules and merges them into singe one. + // We need to put all plugin manifest files into single jar to make new plugin model work + val mergePluginJarTask = task("mergePluginJars") { + duplicatesStrategy = DuplicatesStrategy.FAIL + archiveBaseName.set(basePluginArchiveName) + + exclude("META-INF/MANIFEST.MF") + exclude("**/classpath.index") + + val pluginLibDir by lazy { + val sandboxTask = tasks.prepareSandbox.get() + sandboxTask.destinationDir.resolve("${sandboxTask.pluginName.get()}/lib") + } + + val pluginJars by lazy { + pluginLibDir.listFiles().orEmpty().filter { + it.isPluginJar() + } + } + + destinationDirectory.set(project.layout.dir(provider { pluginLibDir })) + + doFirst { + for (file in pluginJars) { + from(zipTree(file)) + } + } + + doLast { + delete(pluginJars) + } + } + + // Add plugin sources to the plugin ZIP. + // gradle-intellij-plugin will use it as a plugin sources if the plugin is used as a dependency + val createSourceJar = task("createSourceJar") { + for (prj in pluginProjects) { + from(prj.kotlin.sourceSets.main.get().kotlin) { + include("**/*.java") + include("**/*.kt") + } + } + + destinationDirectory.set(layout.buildDirectory.dir("libs")) + archiveBaseName.set(basePluginArchiveName) + archiveClassifier.set("src") + } + + tasks { + buildPlugin { + dependsOn(createSourceJar) + from(createSourceJar) { into("lib/src") } + // Set proper name for final plugin zip. + // Otherwise, base name is the same as gradle module name + archiveBaseName.set(basePluginArchiveName) + } + + runIde { enabled = true } + + prepareSandbox { + finalizedBy(mergePluginJarTask) + enabled = true + } + + buildSearchableOptions { + // Force `mergePluginJarTask` be executed before `buildSearchableOptions` + // Otherwise, `buildSearchableOptions` task can't load the plugin and searchable options are not built. + // Should be dropped when jar merging is implemented in `gradle-intellij-plugin` itself + dependsOn(mergePluginJarTask) +// enabled = prop("enableBuildSearchableOptions").toBoolean() + } + + withType { + // Default args for IDEA installation + jvmArgs("-Xmx768m", "-XX:+UseG1GC", "-XX:SoftRefLRUPolicyMSPerMB=50") + // Disable plugin auto reloading. See `com.intellij.ide.plugins.DynamicPluginVfsListener` + jvmArgs("-Didea.auto.reload.plugins=false") + // Don't show "Tip of the Day" at startup + jvmArgs("-Dide.show.tips.on.startup.default.value=false") + // uncomment if `unexpected exception ProcessCanceledException` prevents you from debugging a running IDE + // jvmArgs("-Didea.ProcessCanceledException=disabled") + + // Uncomment to enable FUS testing mode + // jvmArgs("-Dfus.internal.test.mode=true") + + // Uncomment to enable localization testing mode + // jvmArgs("-Didea.l10n=true") + } + + withType { + pluginDescription.set(provider { file("description.html").readText() }) + } + + withType { + token.set("publishToken") +// channels.set(listOf(channel)) + } } } project(":pycharm") { intellij { - version.set("PC-2022.2.4") - plugins.set(listOf("python-ce")) + version.set(pycharmVersion) + plugins.set(pycharmPlugins) } dependencies { implementation(project(":")) @@ -104,8 +260,8 @@ project(":pycharm") { project(":idea") { intellij { - version.set("IC-2022.2") - plugins.set(listOf("com.intellij.java", "org.jetbrains.plugins.gradle")) + version.set(ideaVersion) + plugins.set(ideaPlugins) } dependencies { implementation(project(":")) @@ -137,6 +293,25 @@ qodana { showReport = environment("QODANA_SHOW_REPORT").map { it.toBoolean() }.getOrElse(false) } +fun File.isPluginJar(): Boolean { + if (!isFile) return false + if (extension != "jar") return false + return zipTree(this).files.any { it.isManifestFile() } +} + +fun File.isManifestFile(): Boolean { + if (extension != "xml") return false + val rootNode = try { + val parser = XmlParser() + parser.parse(this) + } catch (e: Exception) { + logger.error("Failed to parse $path", e) + return false + } + return rootNode.name() == "idea-plugin" +} + + // Configure Gradle Kover Plugin - read more: https://github.com/Kotlin/kotlinx-kover#configuration kover.xmlReport { onCheck = true diff --git a/gradle.properties b/gradle.properties index bc5eafaa41..46651cb8f2 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,6 +6,11 @@ pluginRepositoryUrl = https://github.com/unit-mesh/auto-dev # SemVer format -> https://semver.org pluginVersion = 0.6.1 +# Supported IDEs: idea, pycharm +baseIDE=idea +pycharmVersion=PC-2022.2.4 +ideaVersion=IC-2022.2 + # Supported build number ranges and IntelliJ Platform versions -> https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html pluginSinceBuild = 221.* pluginUntilBuild = 232.* @@ -13,6 +18,7 @@ pluginUntilBuild = 232.* # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType = IC platformVersion = 2022.2 +globalPlatformVersion = 2031 # Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html platformPlugins = com.intellij.java, org.jetbrains.plugins.gradle, Git4Idea diff --git a/plugin/description.html b/plugin/description.html new file mode 100644 index 0000000000..44d284bb5d --- /dev/null +++ b/plugin/description.html @@ -0,0 +1 @@ +Unit Mesh AutoDev AI assistant plugin \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index e6ee315695..508107be83 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,5 +1,7 @@ rootProject.name = "AutoDev" +include("plugin") + include( "pycharm", "idea"