123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955 |
- import groovy.util.Node
- import groovy.xml.XmlParser
- import org.gradle.api.JavaVersion.VERSION_17
- import org.jetbrains.changelog.Changelog
- import org.jetbrains.intellij.platform.gradle.IntelliJPlatformType
- import org.jetbrains.intellij.platform.gradle.IntelliJPlatformType.IntellijIdeaUltimate
- import org.jetbrains.intellij.platform.gradle.TestFrameworkType
- import org.jetbrains.intellij.platform.gradle.extensions.IntelliJPlatformDependenciesExtension
- import org.jetbrains.intellij.platform.gradle.extensions.IntelliJPlatformTestingExtension
- import org.jetbrains.intellij.platform.gradle.tasks.RunIdeTask
- import org.jetbrains.intellij.platform.gradle.utils.extensionProvider
- import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
- import java.util.*
- // The same as `--stacktrace` param
- gradle.startParameter.showStacktrace = ShowStacktrace.ALWAYS
- @Suppress("DSL_SCOPE_VIOLATION")
- plugins {
- id("java") // Java support
- 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)
- alias(libs.plugins.gradleIntelliJPlugin)
- id("org.jetbrains.grammarkit") version "2022.3.2.2"
- kotlin("jvm") version "1.8.22"
- id("net.saliman.properties") version "1.5.2"
- }
- fun properties(key: String) = providers.gradleProperty(key)
- fun environment(key: String) = providers.environmentVariable(key)
- val basePluginArchiveName = "autodev-jetbrains"
- val javaScriptPlugins = listOf("JavaScript")
- val pycharmPlugins = listOf(prop("pythonPlugin"))
- val javaPlugins = listOf("com.intellij.java", "org.jetbrains.kotlin")
- val clionVersion = prop("clionVersion")
- // https://plugins.jetbrains.com/docs/intellij/plugin-compatibility.html#modules-specific-to-functionality
- val clionPlugins = listOf(
- "com.intellij.cidr.base",
- "com.intellij.cidr.lang",
- "com.intellij.clion",
- prop("rustPlugin"),
- "org.toml.lang"
- )
- var cppPlugins: List<String> = listOf(
- "com.intellij.cidr.lang",
- "com.intellij.clion",
- "com.intellij.cidr.base",
- "org.jetbrains.plugins.clion.test.google",
- "org.jetbrains.plugins.clion.test.catch"
- )
- val rustPlugins = listOf(
- prop("rustPlugin"),
- "org.toml.lang"
- )
- val riderVersion = prop("riderVersion")
- val riderPlugins: List<String> = listOf(
- "rider-plugins-appender",
- "org.intellij.intelliLang",
- )
- val scalaPlugin = prop("scalaPlugin")
- val pluginProjects: List<Project> get() = rootProject.allprojects.toList()
- val ideaPlugins =
- listOf(
- "com.intellij.java",
- "org.jetbrains.plugins.gradle",
- "org.jetbrains.idea.maven",
- "org.jetbrains.kotlin",
- "JavaScript"
- )
- var baseIDE = prop("baseIDE")
- val platformVersion = prop("platformVersion").toInt()
- val ideaVersion = prop("ideaVersion")
- val golandVersion = prop("golandVersion")
- val pycharmVersion = prop("pycharmVersion")
- val webstormVersion = prop("webstormVersion")
- var lang = extra.properties["lang"] ?: "java"
- val baseVersion = when (baseIDE) {
- "idea" -> ideaVersion
- "pycharm" -> pycharmVersion
- "goland" -> golandVersion
- "clion" -> clionVersion
- "rider" -> riderVersion
- "javascript" -> webstormVersion
- else -> error("Unexpected IDE name: `$baseIDE`")
- }
- changelog {
- version.set(properties("pluginVersion"))
- groups.empty()
- path.set(rootProject.file("CHANGELOG.md").toString())
- repositoryUrl.set(properties("pluginRepositoryUrl"))
- }
- repositories {
- mavenCentral()
- intellijPlatform {
- defaultRepositories()
- jetbrainsRuntime()
- }
- }
- configure(
- subprojects
- - project(":exts")
- ) {
- apply {
- plugin("idea")
- plugin("kotlin")
- plugin("org.jetbrains.kotlinx.kover")
- plugin("org.jetbrains.intellij.platform.module")
- }
- repositories {
- mavenCentral()
- intellijPlatform {
- defaultRepositories()
- jetbrainsRuntime()
- }
- }
- intellijPlatform {
- instrumentCode = false
- buildSearchableOptions = false
- }
- idea {
- module {
- generatedSourceDirs.add(file("src/gen"))
- isDownloadJavadoc = true
- isDownloadSources = true
- }
- }
- configure<JavaPluginExtension> {
- sourceCompatibility = VERSION_17
- targetCompatibility = VERSION_17
- }
- tasks {
- withType<KotlinCompile> {
- kotlinOptions {
- jvmTarget = VERSION_17.toString()
- languageVersion = "1.8"
- // see https://plugins.jetbrains.com/docs/intellij/using-kotlin.html#kotlin-standard-library
- apiVersion = "1.7"
- freeCompilerArgs = listOf("-Xjvm-default=all")
- }
- }
- prepareSandbox { enabled = false }
- }
- val testOutput = configurations.create("testOutput")
- if (this.name != "ext-terminal") {
- sourceSets {
- main {
- java.srcDirs("src/gen")
- if (platformVersion == 241) {
- resources.srcDirs("src/233/main/resources")
- }
- resources.srcDirs("src/$platformVersion/main/resources")
- }
- test {
- resources.srcDirs("src/$platformVersion/test/resources")
- }
- }
- kotlin {
- sourceSets {
- main {
- // share 233 code to 241
- if (platformVersion == 241) {
- kotlin.srcDirs("src/233/main/kotlin")
- }
- kotlin.srcDirs("src/$platformVersion/main/kotlin")
- }
- test {
- kotlin.srcDirs("src/$platformVersion/test/kotlin")
- }
- }
- }
- }
- dependencies {
- compileOnly(kotlin("stdlib-jdk8"))
- implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1")
- implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3")
- testOutput(sourceSets.test.get().output.classesDirs)
- intellijPlatform {
- testFramework(TestFrameworkType.Bundled)
- }
- }
- }
- project(":") {
- apply {
- plugin("org.jetbrains.changelog")
- plugin("org.jetbrains.intellij.platform")
- }
- repositories {
- intellijPlatform {
- defaultRepositories()
- jetbrainsRuntime()
- }
- }
- intellijPlatform {
- projectName = basePluginArchiveName
- pluginConfiguration {
- id = "cc.unitmesh.devti"
- name = "AutoDev"
- version = prop("pluginVersion")
- ideaVersion {
- sinceBuild = prop("pluginSinceBuild")
- untilBuild = prop("pluginUntilBuild")
- }
- vendor {
- name = "Phodal Huang"
- }
- }
- pluginVerification {
- freeArgs = listOf("-mute", "TemplateWordInPluginId,ForbiddenPluginIdPrefix")
- ides {
- ide(IntellijIdeaUltimate, "2024.2")
- select {
- types = listOf(IntellijIdeaUltimate)
- sinceBuild = "242"
- untilBuild = "242"
- }
- }
- }
- instrumentCode = false
- buildSearchableOptions = false
- }
- dependencies {
- intellijPlatform {
- pluginVerifier()
- intellijIde(prop("ideaVersion"))
- if (hasProp("jbrVersion")) {
- jetbrainsRuntime(prop("jbrVersion"))
- } else {
- jetbrainsRuntime()
- }
- val pluginList: MutableList<String> = mutableListOf("Git4Idea")
- when (lang) {
- "idea" -> {
- pluginList += javaPlugins
- }
- "scala" -> {
- pluginList += javaPlugins + scalaPlugin
- }
- "python" -> {
- pluginList += pycharmPlugins
- }
- "go" -> {
- pluginList += listOf("org.jetbrains.plugins.go")
- }
- "cpp" -> {
- pluginList += clionPlugins
- }
- "rust" -> {
- pluginList += rustPlugins
- }
- }
- intellijPlugins(pluginList)
- pluginModule(implementation(project(":core")))
- pluginModule(implementation(project(":java")))
- pluginModule(implementation(project(":kotlin")))
- pluginModule(implementation(project(":pycharm")))
- pluginModule(implementation(project(":javascript")))
- pluginModule(implementation(project(":goland")))
- pluginModule(implementation(project(":rust")))
- pluginModule(implementation(project(":cpp")))
- pluginModule(implementation(project(":scala")))
- pluginModule(implementation(project(":local-bundle")))
- pluginModule(implementation(project(":exts:ext-database")))
- pluginModule(implementation(project(":exts:ext-android")))
- pluginModule(implementation(project(":exts:ext-harmonyos")))
- pluginModule(implementation(project(":exts:ext-git")))
- pluginModule(implementation(project(":exts:ext-http-client")))
- pluginModule(implementation(project(":exts:ext-terminal")))
- pluginModule(implementation(project(":exts:devins-lang")))
- testFramework(TestFrameworkType.Bundled)
- }
- implementation(project(":core"))
- implementation(project(":java"))
- implementation(project(":kotlin"))
- implementation(project(":pycharm"))
- implementation(project(":javascript"))
- implementation(project(":goland"))
- implementation(project(":rust"))
- implementation(project(":cpp"))
- implementation(project(":scala"))
- implementation(project(":local-bundle"))
- implementation(project(":exts:ext-database"))
- implementation(project(":exts:ext-android"))
- implementation(project(":exts:ext-harmonyos"))
- implementation(project(":exts:ext-git"))
- implementation(project(":exts:ext-http-client"))
- implementation(project(":exts:ext-terminal"))
- implementation(project(":exts:devins-lang"))
- kover(project(":cpp"))
- kover(project(":core"))
- kover(project(":goland"))
- kover(project(":java"))
- kover(project(":javascript"))
- kover(project(":kotlin"))
- kover(project(":pycharm"))
- kover(project(":rust"))
- kover(project(":scala"))
- kover(project(":exts:ext-database"))
- kover(project(":exts:ext-android"))
- kover(project(":exts:devins-lang"))
- }
- tasks {
- val projectName = project.extensionProvider.flatMap { it.projectName }
- composedJar {
- archiveBaseName.convention(projectName)
- }
- withType<RunIdeTask> {
- // 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")
- }
- patchPluginXml {
- pluginDescription.set(provider { file("src/description.html").readText() })
- changelog {
- version.set(properties("pluginVersion"))
- groups.empty()
- path.set(rootProject.file("CHANGELOG.md").toString())
- repositoryUrl.set(properties("pluginRepositoryUrl"))
- }
- val changelog = project.changelog
- // Get the latest available change notes from the changelog file
- changeNotes.set(properties("pluginVersion").map { pluginVersion ->
- with(changelog) {
- renderItem(
- (getOrNull(pluginVersion) ?: getUnreleased())
- .withHeader(false)
- .withEmptySections(false),
- Changelog.OutputType.HTML,
- )
- }
- })
- }
- buildPlugin {
- archiveBaseName.set(basePluginArchiveName)
- archiveVersion.set(prop("pluginVersion") + "-" + prop("platformVersion"))
- }
- publishPlugin {
- dependsOn("patchChangelog")
- token.set(environment("PUBLISH_TOKEN"))
- channels.set(properties("pluginVersion").map {
- listOf(it.split('-').getOrElse(1) { "default" }.split('.').first())
- })
- }
- intellijPlatformTesting {
- // Generates event scheme for JetBrains Academy plugin FUS events to `build/eventScheme.json`
- runIde.register("buildEventsScheme") {
- task {
- args(
- "buildEventsScheme",
- "--outputFile=${buildDir()}/eventScheme.json",
- "--pluginId=com.jetbrains.edu"
- )
- // Force headless mode to be able to run command on CI
- systemProperty("java.awt.headless", "true")
- // BACKCOMPAT: 2024.1. Update value to 242 and this comment
- // `IDEA_BUILD_NUMBER` variable is used by `buildEventsScheme` task to write `buildNumber` to output json.
- // It will be used by TeamCity automation to set minimal IDE version for new events
- environment("IDEA_BUILD_NUMBER", "241")
- }
- }
- runIde.register("runInSplitMode") {
- splitMode = true
- // Specify custom sandbox directory to have a stable path to log file
- sandboxDirectory =
- intellijPlatform.sandboxContainer.dir("split-mode-sandbox-${prop("platformVersion")}")
- plugins {
- plugins(ideaPlugins)
- }
- }
- customRunIdeTask(IntellijIdeaUltimate, prop("ideaVersion"), baseTaskName = "Idea")
- }
- }
- }
- project(":core") {
- apply {
- plugin("org.jetbrains.kotlin.plugin.serialization")
- }
- dependencies {
- intellijPlatform {
- intellijIde(prop("ideaVersion"))
- intellijPlugins(ideaPlugins)
- testFramework(TestFrameworkType.Bundled)
- }
- implementation("com.theokanning.openai-gpt3-java:service:0.18.2")
- implementation("com.squareup.okhttp3:okhttp:4.4.1")
- implementation("com.squareup.okhttp3:okhttp-sse:4.4.1")
- implementation("com.squareup.retrofit2:converter-jackson:2.9.0")
- implementation("com.squareup.retrofit2:converter-gson:2.9.0")
- implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.14.2")
- implementation("com.fasterxml.jackson.core:jackson-databind:2.14.2")
- implementation("org.commonmark:commonmark:0.21.0")
- implementation("org.commonmark:commonmark-ext-gfm-tables:0.21.0")
- implementation("org.yaml:snakeyaml:2.2")
- implementation("com.nfeld.jsonpathkt:jsonpathkt:2.0.1")
- implementation("org.jetbrains:markdown:0.6.1")
- // chocolate factory
- // follow: https://onnxruntime.ai/docs/get-started/with-java.html
- // implementation("com.microsoft.onnxruntime:onnxruntime:1.18.0")
- // implementation("ai.djl.huggingface:tokenizers:0.29.0")
- implementation("cc.unitmesh:cocoa-core:1.0.0")
- implementation("cc.unitmesh:document:1.0.0")
- // kanban
- implementation("org.kohsuke:github-api:1.314")
- implementation("org.gitlab4j:gitlab4j-api:5.3.0")
- // template engine
- implementation("org.apache.velocity:velocity-engine-core:2.3")
- // http request/response
- implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.14.2")
- // token count
- implementation("com.knuddels:jtokkit:1.0.0")
- implementation("org.apache.commons:commons-text:1.12.0")
- implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3")
- // junit
- testImplementation("io.kotest:kotest-assertions-core:5.7.2")
- testImplementation("junit:junit:4.13.2")
- testRuntimeOnly("org.junit.vintage:junit-vintage-engine:5.9.3")
- }
- task("resolveDependencies") {
- doLast {
- rootProject.allprojects
- .map { it.configurations }
- .flatMap { it.filter { c -> c.isCanBeResolved } }
- .forEach { it.resolve() }
- }
- }
- }
- project(":pycharm") {
- dependencies {
- intellijPlatform {
- intellijIde(prop("ideaVersion"))
- intellijPlugins(ideaPlugins + pycharmPlugins)
- }
- implementation(project(":core"))
- }
- }
- project(":java") {
- dependencies {
- intellijPlatform {
- intellijIde(prop("ideaVersion"))
- intellijPlugins(ideaPlugins)
- }
- implementation(project(":core"))
- }
- }
- project(":javascript") {
- dependencies {
- intellijPlatform {
- intellijIde(prop("ideaVersion"))
- intellijPlugins(ideaPlugins)
- intellijPlugins(javaScriptPlugins)
- }
- implementation(project(":core"))
- }
- }
- project(":kotlin") {
- dependencies {
- intellijPlatform {
- intellijIde(prop("ideaVersion"))
- intellijPlugins(ideaPlugins)
- }
- implementation(project(":core"))
- implementation(project(":java"))
- }
- }
- project(":scala") {
- dependencies {
- intellijPlatform {
- intellijIde(prop("ideaVersion"))
- intellijPlugins(ideaPlugins + scalaPlugin)
- }
- implementation(project(":core"))
- implementation(project(":java"))
- }
- }
- project(":rust") {
- dependencies {
- intellijPlatform {
- intellijIde(prop("ideaVersion"))
- intellijPlugins(ideaPlugins + rustPlugins)
- }
- implementation(project(":core"))
- }
- }
- project(":cpp") {
- if (platformVersion == 233 || platformVersion == 241) {
- cppPlugins += "com.intellij.nativeDebug"
- }
- dependencies {
- intellijPlatform {
- intellijIde(clionVersion)
- intellijPlugins(cppPlugins)
- }
- implementation(project(":core"))
- }
- }
- //project(":csharp") {
- // dependencies {
- // intellijPlatform {
- // intellijIde(riderVersion)
- // intellijPlugins(riderPlugins)
- // }
- //
- // implementation(project(":core"))
- // }
- //}
- project(":goland") {
- dependencies {
- intellijPlatform {
- intellijIde(prop("ideaVersion"))
- intellijPlugins(prop("goPlugin").split(',').map(String::trim).filter(String::isNotEmpty))
- }
- implementation(project(":core"))
- }
- }
- project(":exts:ext-database") {
- dependencies {
- intellijPlatform {
- intellijIde(prop("ideaVersion"))
- intellijPlugins(ideaPlugins + "com.intellij.database")
- }
- implementation(project(":core"))
- }
- }
- project(":exts:ext-android") {
- dependencies {
- intellijPlatform {
- intellijIde(prop("ideaVersion"))
- intellijPlugins((ideaPlugins + prop("androidPlugin").ifBlank { "" }).filter(String::isNotEmpty))
- }
- implementation(project(":core"))
- }
- }
- project(":exts:ext-harmonyos") {
- dependencies {
- intellijPlatform {
- intellijIde(prop("ideaVersion"))
- intellijPlugins((ideaPlugins + prop("androidPlugin").ifBlank { "" }).filter(String::isNotEmpty))
- }
- implementation(project(":core"))
- }
- }
- project(":exts:ext-git") {
- dependencies {
- intellijPlatform {
- intellijIde(prop("ideaVersion"))
- intellijPlugins(ideaPlugins + "Git4Idea")
- }
- implementation(project(":core"))
- implementation("cc.unitmesh:git-commit-message:0.4.6")
- }
- }
- project(":exts:ext-http-client") {
- dependencies {
- intellijPlatform {
- intellijIde(prop("ideaVersion"))
- intellijPlugins(ideaPlugins + "com.jetbrains.restClient")
- }
- implementation(project(":core"))
- }
- }
- project(":local-bundle") {
- dependencies {
- intellijPlatform {
- intellijIde(prop("ideaVersion"))
- }
- implementation(project(":core"))
- }
- }
- project(":exts:ext-terminal") {
- dependencies {
- intellijPlatform {
- intellijIde(prop("ideaVersion"))
- intellijPlugins(ideaPlugins + "org.jetbrains.plugins.terminal")
- }
- implementation(project(":core"))
- }
- sourceSets {
- main {
- resources.srcDirs("src/$platformVersion/main/resources")
- }
- test {
- resources.srcDirs("src/$platformVersion/test/resources")
- }
- }
- kotlin {
- sourceSets {
- main {
- kotlin.srcDirs("src/$platformVersion/main/kotlin")
- }
- test {
- kotlin.srcDirs("src/$platformVersion/test/kotlin")
- }
- }
- }
- }
- project(":exts:devins-lang") {
- apply {
- plugin("org.jetbrains.grammarkit")
- }
- dependencies {
- intellijPlatform {
- intellijIde(prop("ideaVersion"))
- intellijPlugins(ideaPlugins + "org.intellij.plugins.markdown" + "com.jetbrains.sh" + "Git4Idea")
- }
- implementation(project(":core"))
- implementation(project(":exts:ext-git"))
- }
- tasks {
- generateLexer {
- sourceFile.set(file("src/grammar/DevInLexer.flex"))
- targetOutputDir.set(file("src/gen/cc/unitmesh/devti/language/lexer"))
- purgeOldFiles.set(true)
- }
- generateParser {
- sourceFile.set(file("src/grammar/DevInParser.bnf"))
- targetRootOutputDir.set(file("src/gen"))
- pathToParser.set("cc/unitmesh/devti/language/parser/DevInParser.java")
- pathToPsiRoot.set("cc/unitmesh/devti/language/psi")
- purgeOldFiles.set(true)
- }
- withType<KotlinCompile> {
- dependsOn(generateLexer, generateParser)
- }
- }
- }
- 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"
- }
- data class TypeWithVersion(val type: IntelliJPlatformType, val version: String)
- fun String.toTypeWithVersion(): TypeWithVersion {
- val (code, version) = split("-", limit = 2)
- return TypeWithVersion(IntelliJPlatformType.fromCode(code), version)
- }
- /**
- * Creates `run$[baseTaskName]` Gradle task to run IDE of given [type]
- * via `runIde` task with plugins according to [ideToPlugins] map
- */
- fun IntelliJPlatformTestingExtension.customRunIdeTask(
- type: IntelliJPlatformType,
- versionWithCode: String? = null,
- baseTaskName: String = type.name,
- ) {
- runIde.register("run$baseTaskName") {
- useInstaller = false
- if (versionWithCode != null) {
- val version = versionWithCode.toTypeWithVersion().version
- this.type = type
- this.version = version
- } else {
- val pathProperty = baseTaskName.replaceFirstChar { it.lowercaseChar() } + "Path"
- // Avoid throwing exception during property calculation.
- // Some IDE tooling (for example, Package Search plugin) may try to calculate properties during `Sync` phase for all tasks.
- // In our case, some `run*` task may not have `pathProperty` in your `gradle.properties`,
- // and as a result, the `Sync` tool window will show you the error thrown by `prop` function.
- //
- // The following solution just moves throwing the corresponding error to task execution,
- // i.e., only when a task is actually invoked
- if (hasProp(pathProperty)) {
- localPath.convention(layout.dir(provider { file(prop(pathProperty)) }))
- } else {
- task {
- doFirst {
- throw GradleException("Property `$pathProperty` is not defined in gradle.properties")
- }
- }
- }
- }
- // Specify custom sandbox directory to have a stable path to log file
- sandboxDirectory =
- intellijPlatform.sandboxContainer.dir("${baseTaskName.lowercase()}-sandbox-${prop("platformVersion")}")
- plugins {
- plugins(ideaPlugins)
- }
- }
- }
- fun IntelliJPlatformDependenciesExtension.intellijIde(versionWithCode: String) {
- val (type, version) = versionWithCode.toTypeWithVersion()
- create(type, version, useInstaller = false)
- }
- fun IntelliJPlatformDependenciesExtension.intellijPlugins(vararg notations: String) {
- for (notation in notations) {
- if (notation.contains(":")) {
- plugin(notation)
- } else {
- bundledPlugin(notation)
- }
- }
- }
- fun IntelliJPlatformDependenciesExtension.intellijPlugins(notations: List<String>) {
- intellijPlugins(*notations.toTypedArray())
- }
- fun hasProp(name: String): Boolean = extra.has(name)
- fun prop(name: String): String =
- extra.properties[name] as? String ?: error("Property `$name` is not defined in gradle.properties")
- fun withProp(name: String, action: (String) -> Unit) {
- if (hasProp(name)) {
- action(prop(name))
- }
- }
- fun withProp(filePath: String, name: String, action: (String) -> Unit) {
- if (!file(filePath).exists()) {
- println("$filePath doesn't exist")
- return
- }
- val properties = loadProperties(filePath)
- val value = properties.getProperty(name) ?: return
- action(value)
- }
- fun buildDir(): String {
- return project.layout.buildDirectory.get().asFile.absolutePath
- }
- fun <T : ModuleDependency> T.excludeKotlinDeps() {
- exclude(module = "kotlin-runtime")
- exclude(module = "kotlin-reflect")
- exclude(module = "kotlin-stdlib")
- exclude(module = "kotlin-stdlib-common")
- exclude(module = "kotlin-stdlib-jdk8")
- }
- fun loadProperties(path: String): Properties {
- val properties = Properties()
- file(path).bufferedReader().use { properties.load(it) }
- return properties
- }
- fun parseManifest(file: File): Node {
- val node = XmlParser().parse(file)
- check(node.name() == "idea-plugin") {
- "Manifest file `$file` doesn't contain top-level `idea-plugin` attribute"
- }
- return node
- }
- fun manifestFile(project: Project): File? {
- var filePath: String? = null
- val mainOutput = project.sourceSets.main.get().output
- val resourcesDir = mainOutput.resourcesDir ?: error("Failed to find resources dir for ${project.name}")
- if (filePath != null) {
- return resourcesDir.resolve(filePath).takeIf { it.exists() }
- ?: error("Failed to find manifest file for ${project.name} module")
- }
- val rootManifestFile =
- manifestFile(project(":intellij-plugin")) ?: error("Failed to find manifest file for :intellij-plugin module")
- val rootManifest = parseManifest(rootManifestFile)
- val children = ((rootManifest["content"] as? List<*>)?.single() as? Node)?.children()
- ?: error("Failed to find module declarations in root manifest")
- return children.filterIsInstance<Node>()
- .flatMap { node ->
- if (node.name() != "module") return@flatMap emptyList()
- val name = node.attribute("name") as? String ?: return@flatMap emptyList()
- listOfNotNull(resourcesDir.resolve("$name.xml").takeIf { it.exists() })
- }.firstOrNull() ?: error("Failed to find manifest file for ${project.name} module")
- }
- fun findModulePackage(project: Project): String? {
- val moduleManifest = manifestFile(project) ?: return null
- val node = parseManifest(moduleManifest)
- return node.attribute("package") as? String ?: error("Failed to find package for ${project.name}")
- }
- fun verifyClasses(project: Project) {
- val pkg = findModulePackage(project) ?: return
- val expectedDir = pkg.replace('.', '/')
- var hasErrors = false
- for (classesDir in project.sourceSets.main.get().output.classesDirs) {
- val basePath = classesDir.toPath()
- for (file in classesDir.walk()) {
- if (file.isFile && file.extension == "class") {
- val relativePath = basePath.relativize(file.toPath())
- if (!relativePath.startsWith(expectedDir)) {
- logger.error(
- "Wrong package of `${
- relativePath.joinToString(".").removeSuffix(".class")
- }` class. Expected `$pkg`"
- )
- hasErrors = true
- }
- }
- }
- }
- if (hasErrors) {
- throw GradleException("Classes with wrong package were found. See https://docs.google.com/document/d/1pOy-qNlGOJe6wftHVYHkH8sZOoAfav1fdGDPJgkQWJo")
- }
- }
- fun DependencyHandler.implementationWithoutKotlin(dependencyNotation: Provider<*>) {
- implementation(dependencyNotation) {
- excludeKotlinDeps()
- }
- }
- fun DependencyHandler.testImplementationWithoutKotlin(dependencyNotation: Provider<*>) {
- testImplementation(dependencyNotation) {
- excludeKotlinDeps()
- }
- }
|