diff --git a/.idea/misc.xml b/.idea/misc.xml
index c4fae9a174fa6d..61445018c0889b 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,4 +1,9 @@
+
+
+
+
+
diff --git a/components/ide/jetbrains/backend-plugin/.gitignore b/components/ide/jetbrains/backend-plugin/.gitignore
index 9fbea8abb7bbb9..d2fcdff60f4394 100644
--- a/components/ide/jetbrains/backend-plugin/.gitignore
+++ b/components/ide/jetbrains/backend-plugin/.gitignore
@@ -4,3 +4,4 @@
bin
build
gradle-local.properties
+.intellijPlatform
diff --git a/components/ide/jetbrains/backend-plugin/BUILD.yaml b/components/ide/jetbrains/backend-plugin/BUILD.yaml
index eef8395e2dcf2e..a284d9fe60f992 100644
--- a/components/ide/jetbrains/backend-plugin/BUILD.yaml
+++ b/components/ide/jetbrains/backend-plugin/BUILD.yaml
@@ -41,7 +41,7 @@ packages:
- components/gitpod-protocol/java:lib
srcs:
- "**/*.kt"
- - "build.gradle.kts"
+ - "build.gradle-stable.kts"
- "gradle.properties"
- "gradle-stable.properties"
- "gradle/wrapper/*"
@@ -55,6 +55,7 @@ packages:
- NO_VERIFY_JB_PLUGIN=${noVerifyJBPlugin}
config:
commands:
+ - ["mv", "build.gradle-stable.kts", "build.gradle.kts"]
- ["./build.sh", "${__git_commit}"]
- name: plugin-latest
type: generic
@@ -65,7 +66,7 @@ packages:
- components/gitpod-protocol/java:lib
srcs:
- "**/*.kt"
- - "build.gradle.kts"
+ - "build.gradle-latest.kts"
- "gradle.properties"
- "gradle-latest.properties"
- "gradle/wrapper/*"
@@ -77,9 +78,19 @@ packages:
env:
- JB_QUALIFIER=latest
- NO_VERIFY_JB_PLUGIN=${noVerifyJBPlugin}
+ # TODO(hw): remove after `2024.2.*` is stable
+ - SDKMAN_DIR=/home/gitpod/.sdkman
config:
commands:
- - ["./build.sh", "${__git_commit}"]
+ # TODO(hw): remove after 2024.2.* is stable
+ - ["mv", "build.gradle-latest.kts", "build.gradle.kts"]
+ - - "bash"
+ - "-c"
+ - >
+ echo java=21.0.3.fx-zulu > .sdkmanrc
+ && source "$SDKMAN_DIR/bin/sdkman-init.sh"
+ && sdk env install
+ && ./build.sh ${__git_commit}
- name: latest-info
type: generic
srcs:
diff --git a/components/ide/jetbrains/backend-plugin/README.md b/components/ide/jetbrains/backend-plugin/README.md
index 3bae68dc046374..4c3c9e49ac016d 100644
--- a/components/ide/jetbrains/backend-plugin/README.md
+++ b/components/ide/jetbrains/backend-plugin/README.md
@@ -5,6 +5,12 @@ Provides integrations within a Gitpod workspace.
+## Development before `2024.2.*` is released
+
+- You will need to copy content in build.gradle-stable.kts if you want to test stable IDEs changes. For latest, this step is the same
+- Make sure your build script `build.gradle.kts` is synced with `build.gradle-.kts`
+- Other steps are the same with *Development* section
+
## Development
The ideal setup to develop this plugin is using IntelliJ in Gitpod.
diff --git a/components/ide/jetbrains/backend-plugin/build.gradle-latest.kts b/components/ide/jetbrains/backend-plugin/build.gradle-latest.kts
new file mode 100644
index 00000000000000..8b29e7625dab21
--- /dev/null
+++ b/components/ide/jetbrains/backend-plugin/build.gradle-latest.kts
@@ -0,0 +1,163 @@
+// Copyright (c) 2024 Gitpod GmbH. All rights reserved.
+// Licensed under the GNU Affero General Public License (AGPL).
+// See License.AGPL.txt in the project root for license information.
+
+import io.gitlab.arturbosch.detekt.Detekt
+import org.jetbrains.intellij.platform.gradle.IntelliJPlatformType
+import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
+
+fun properties(key: String) = project.findProperty(key).toString()
+
+plugins {
+ // Java support
+ id("java")
+ // Kotlin support - check the latest version at https://plugins.gradle.org/plugin/org.jetbrains.kotlin.jvm
+ id("org.jetbrains.kotlin.jvm") version "2.0.0"
+ // gradle-intellij-plugin - read more: https://github.com/JetBrains/gradle-intellij-plugin
+ id("org.jetbrains.intellij.platform") version "2.0.0-beta8"
+// id("org.jetbrains.intellij.platform.migration") version "2.0.0-beta7"
+ // detekt linter - read more: https://detekt.github.io/detekt/gradle.html
+ id("io.gitlab.arturbosch.detekt") version "1.23.6"
+ // ktlint linter - read more: https://github.com/JLLeitschuh/ktlint-gradle
+ id("org.jlleitschuh.gradle.ktlint") version "12.1.1"
+ // Gradle Properties Plugin - read more: https://github.com/stevesaliman/gradle-properties-plugin
+ id("net.saliman.properties") version "1.5.2"
+}
+
+group = properties("pluginGroup")
+val environmentName = properties("environmentName")
+var pluginVersion = "${properties("pluginVersion")}-${properties("gitpodVersion")}"
+
+if (environmentName.isNotBlank()) {
+ pluginVersion += "-$environmentName"
+}
+
+project(":") {
+ kotlin {
+ val excludedPackage = if (environmentName == "latest") "stable" else "latest"
+ sourceSets["main"].kotlin.exclude("io/gitpod/jetbrains/remote/${excludedPackage}/**")
+ }
+
+ sourceSets {
+ main {
+ resources.srcDirs("src/main/resources-${environmentName}")
+ }
+ }
+}
+
+// Configure project's dependencies
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ implementation(project(":supervisor-api")) {
+ artifact {
+ type = "jar"
+ }
+ }
+ implementation(project(":gitpod-protocol")) {
+ artifact {
+ type = "jar"
+ }
+ }
+ implementation("io.prometheus:simpleclient_pushgateway:0.15.0")
+ compileOnly("javax.websocket:javax.websocket-api:1.1")
+ detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:1.18.1")
+ testImplementation(kotlin("test"))
+
+ // grpc
+ // https://mvnrepository.com/artifact/com.google.api.grpc/proto-google-common-protos
+ implementation("com.google.api.grpc:proto-google-common-protos:2.41.0")
+ implementation("io.grpc:grpc-core:1.65.0")
+ implementation("io.grpc:grpc-protobuf:1.65.0")
+ // https://mvnrepository.com/artifact/io.grpc/grpc-stub
+ implementation("io.grpc:grpc-stub:1.65.0")
+ implementation("io.grpc:grpc-netty-shaded:1.65.0")
+}
+
+repositories {
+ mavenCentral()
+ intellijPlatform {
+ defaultRepositories()
+ }
+}
+
+dependencies {
+ intellijPlatform {
+ create(properties("platformType"), properties("platformVersion"))
+
+ // Plugin Dependencies. Uses `platformBundledPlugins` property from the gradle.properties file for bundled IntelliJ Platform plugins.
+ bundledPlugins(properties("platformBundledPlugins").split(',').map{ it.trim() })
+ }
+}
+
+// Configure gradle-intellij-plugin plugin.
+// Read more: https://github.com/JetBrains/gradle-intellij-plugin
+intellijPlatform {
+ pluginConfiguration {
+ name = properties("pluginName")
+ version = pluginVersion
+ ideaVersion {
+ sinceBuild = properties("pluginSinceBuild")
+ untilBuild = properties("pluginUntilBuild")
+ }
+ }
+ instrumentCode = false
+
+}
+
+// Configure detekt plugin.
+// Read more: https://detekt.github.io/detekt/kotlindsl.html
+detekt {
+ autoCorrect = true
+ buildUponDefaultConfig = true
+ ignoreFailures = true
+
+// reports {
+// html.enabled = false
+// xml.enabled = false
+// txt.enabled = false
+// }
+}
+
+ktlint {
+ ignoreFailures = true
+ filter {
+ exclude("build.gradle-*.kts")
+ }
+}
+
+kotlin {
+ jvmToolchain(21)
+}
+
+tasks.withType {
+ jvmTarget = "21"
+ onlyIf { project.findProperty("skipDetekt") != "true" }
+}
+
+tasks {
+ withType {
+ sourceCompatibility = "21"
+ targetCompatibility = "21"
+ }
+ withType {
+ kotlinOptions.jvmTarget = "21"
+ }
+
+ buildSearchableOptions {
+ enabled = false
+ }
+
+ test {
+ // Currently, we need to indicate where are the test classes.
+ // Read more: https://youtrack.jetbrains.com/issue/IDEA-278926/All-inheritors-of-UsefulTestCase-are-invisible-for-Gradle#focus=Comments-27-5561012.0-0
+ isScanForTestClasses = false
+ include("**/*Test.class")
+ }
+}
+
+tasks.register("runPluginVerifier") {
+ intellijPlatform.verifyPlugin.ides.ide(IntelliJPlatformType.IntellijIdeaUltimate, properties("pluginVerifierIdeVersions"))
+}
diff --git a/components/ide/jetbrains/backend-plugin/build.gradle-stable.kts b/components/ide/jetbrains/backend-plugin/build.gradle-stable.kts
new file mode 100644
index 00000000000000..480699b9258878
--- /dev/null
+++ b/components/ide/jetbrains/backend-plugin/build.gradle-stable.kts
@@ -0,0 +1,142 @@
+// Copyright (c) 2021 Gitpod GmbH. All rights reserved.
+// Licensed under the GNU Affero General Public License (AGPL).
+// See License.AGPL.txt in the project root for license information.
+
+import io.gitlab.arturbosch.detekt.Detekt
+import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
+
+fun properties(key: String) = project.findProperty(key).toString()
+
+plugins {
+ // Java support
+ id("java")
+ // Kotlin support - check the latest version at https://plugins.gradle.org/plugin/org.jetbrains.kotlin.jvm
+ id("org.jetbrains.kotlin.jvm") version "1.9.0"
+ // gradle-intellij-plugin - read more: https://github.com/JetBrains/gradle-intellij-plugin
+ id("org.jetbrains.intellij") version "1.17.4"
+ // detekt linter - read more: https://detekt.github.io/detekt/gradle.html
+ id("io.gitlab.arturbosch.detekt") version "1.21.0"
+ // ktlint linter - read more: https://github.com/JLLeitschuh/ktlint-gradle
+ id("org.jlleitschuh.gradle.ktlint") version "11.0.0"
+ // Gradle Properties Plugin - read more: https://github.com/stevesaliman/gradle-properties-plugin
+ id("net.saliman.properties") version "1.5.2"
+}
+
+group = properties("pluginGroup")
+val environmentName = properties("environmentName")
+var pluginVersion = "${properties("pluginVersion")}-${properties("gitpodVersion")}"
+
+if (environmentName.isNotBlank()) {
+ pluginVersion += "-$environmentName"
+}
+
+project(":") {
+ kotlin {
+ val excludedPackage = if (environmentName == "latest") "stable" else "latest"
+ sourceSets["main"].kotlin.exclude("io/gitpod/jetbrains/remote/${excludedPackage}/**")
+ }
+
+ sourceSets {
+ main {
+ resources.srcDirs("src/main/resources-${environmentName}")
+ }
+ }
+}
+
+// Configure project's dependencies
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ implementation(project(":supervisor-api")) {
+ artifact {
+ type = "jar"
+ }
+ }
+ implementation(project(":gitpod-protocol")) {
+ artifact {
+ type = "jar"
+ }
+ }
+ implementation("io.prometheus:simpleclient_pushgateway:0.15.0")
+ compileOnly("javax.websocket:javax.websocket-api:1.1")
+ detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:1.18.1")
+ testImplementation(kotlin("test"))
+
+ // grpc
+ implementation("com.google.api.grpc:proto-google-common-protos:2.2.2")
+ implementation("io.grpc:grpc-core:1.49.0")
+ implementation("io.grpc:grpc-protobuf:1.49.0")
+ implementation("io.grpc:grpc-stub:1.49.0")
+ implementation("io.grpc:grpc-netty-shaded:1.49.0")
+}
+
+// Configure gradle-intellij-plugin plugin.
+// Read more: https://github.com/JetBrains/gradle-intellij-plugin
+intellij {
+ pluginName.set(properties("pluginName"))
+ version.set(properties("platformVersion"))
+ type.set(properties("platformType"))
+ instrumentCode.set(false)
+ downloadSources.set(properties("platformDownloadSources").toBoolean())
+ updateSinceUntilBuild.set(true)
+
+ // Plugin Dependencies. Uses `platformBundledPlugins` property from the gradle.properties file.
+ plugins.set(properties("platformBundledPlugins").split(',').map(String::trim).filter(String::isNotEmpty))
+}
+
+// Configure detekt plugin.
+// Read more: https://detekt.github.io/detekt/kotlindsl.html
+detekt {
+ autoCorrect = true
+ buildUponDefaultConfig = true
+ ignoreFailures = true
+
+ reports {
+ html.enabled = false
+ xml.enabled = false
+ txt.enabled = false
+ }
+}
+ktlint {
+ ignoreFailures = true
+}
+
+tasks {
+ withType {
+ sourceCompatibility = "17"
+ targetCompatibility = "17"
+ }
+ withType {
+ kotlinOptions.jvmTarget = "17"
+ }
+
+ withType {
+ jvmTarget = "17"
+ }
+
+ buildSearchableOptions {
+ enabled = false
+ }
+
+ test {
+ // Currently, we need to indicate where are the test classes.
+ // Read more: https://youtrack.jetbrains.com/issue/IDEA-278926/All-inheritors-of-UsefulTestCase-are-invisible-for-Gradle#focus=Comments-27-5561012.0-0
+ isScanForTestClasses = false
+ include("**/*Test.class")
+ }
+
+ runPluginVerifier {
+ ideVersions.set(properties("pluginVerifierIdeVersions").split(',').map(String::trim).filter(String::isNotEmpty))
+ }
+
+ patchPluginXml {
+ version.set(pluginVersion)
+ }
+
+ verifyPlugin {
+ // TODO(hw): DO NOT IGNORE FAILURE AFTER UPGRADE
+ ignoreFailures = true
+ }
+}
diff --git a/components/ide/jetbrains/backend-plugin/build.gradle.kts b/components/ide/jetbrains/backend-plugin/build.gradle.kts
index 3cd576cb60161c..8b29e7625dab21 100644
--- a/components/ide/jetbrains/backend-plugin/build.gradle.kts
+++ b/components/ide/jetbrains/backend-plugin/build.gradle.kts
@@ -1,8 +1,9 @@
-// Copyright (c) 2021 Gitpod GmbH. All rights reserved.
+// Copyright (c) 2024 Gitpod GmbH. All rights reserved.
// Licensed under the GNU Affero General Public License (AGPL).
// See License.AGPL.txt in the project root for license information.
import io.gitlab.arturbosch.detekt.Detekt
+import org.jetbrains.intellij.platform.gradle.IntelliJPlatformType
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
fun properties(key: String) = project.findProperty(key).toString()
@@ -11,13 +12,14 @@ plugins {
// Java support
id("java")
// Kotlin support - check the latest version at https://plugins.gradle.org/plugin/org.jetbrains.kotlin.jvm
- id("org.jetbrains.kotlin.jvm") version "1.9.0"
+ id("org.jetbrains.kotlin.jvm") version "2.0.0"
// gradle-intellij-plugin - read more: https://github.com/JetBrains/gradle-intellij-plugin
- id("org.jetbrains.intellij") version "1.10.1"
+ id("org.jetbrains.intellij.platform") version "2.0.0-beta8"
+// id("org.jetbrains.intellij.platform.migration") version "2.0.0-beta7"
// detekt linter - read more: https://detekt.github.io/detekt/gradle.html
- id("io.gitlab.arturbosch.detekt") version "1.21.0"
+ id("io.gitlab.arturbosch.detekt") version "1.23.6"
// ktlint linter - read more: https://github.com/JLLeitschuh/ktlint-gradle
- id("org.jlleitschuh.gradle.ktlint") version "11.0.0"
+ id("org.jlleitschuh.gradle.ktlint") version "12.1.1"
// Gradle Properties Plugin - read more: https://github.com/stevesaliman/gradle-properties-plugin
id("net.saliman.properties") version "1.5.2"
}
@@ -65,25 +67,44 @@ dependencies {
testImplementation(kotlin("test"))
// grpc
- implementation("com.google.api.grpc:proto-google-common-protos:2.2.2")
- implementation("io.grpc:grpc-core:1.49.0")
- implementation("io.grpc:grpc-protobuf:1.49.0")
- implementation("io.grpc:grpc-stub:1.49.0")
- implementation("io.grpc:grpc-netty-shaded:1.49.0")
+ // https://mvnrepository.com/artifact/com.google.api.grpc/proto-google-common-protos
+ implementation("com.google.api.grpc:proto-google-common-protos:2.41.0")
+ implementation("io.grpc:grpc-core:1.65.0")
+ implementation("io.grpc:grpc-protobuf:1.65.0")
+ // https://mvnrepository.com/artifact/io.grpc/grpc-stub
+ implementation("io.grpc:grpc-stub:1.65.0")
+ implementation("io.grpc:grpc-netty-shaded:1.65.0")
+}
+
+repositories {
+ mavenCentral()
+ intellijPlatform {
+ defaultRepositories()
+ }
+}
+
+dependencies {
+ intellijPlatform {
+ create(properties("platformType"), properties("platformVersion"))
+
+ // Plugin Dependencies. Uses `platformBundledPlugins` property from the gradle.properties file for bundled IntelliJ Platform plugins.
+ bundledPlugins(properties("platformBundledPlugins").split(',').map{ it.trim() })
+ }
}
// Configure gradle-intellij-plugin plugin.
// Read more: https://github.com/JetBrains/gradle-intellij-plugin
-intellij {
- pluginName.set(properties("pluginName"))
- version.set(properties("platformVersion"))
- type.set(properties("platformType"))
- instrumentCode.set(false)
- downloadSources.set(properties("platformDownloadSources").toBoolean())
- updateSinceUntilBuild.set(true)
-
- // Plugin Dependencies. Uses `platformPlugins` property from the gradle.properties file.
- plugins.set(properties("platformPlugins").split(',').map(String::trim).filter(String::isNotEmpty))
+intellijPlatform {
+ pluginConfiguration {
+ name = properties("pluginName")
+ version = pluginVersion
+ ideaVersion {
+ sinceBuild = properties("pluginSinceBuild")
+ untilBuild = properties("pluginUntilBuild")
+ }
+ }
+ instrumentCode = false
+
}
// Configure detekt plugin.
@@ -91,25 +112,38 @@ intellij {
detekt {
autoCorrect = true
buildUponDefaultConfig = true
+ ignoreFailures = true
- reports {
- html.enabled = false
- xml.enabled = false
- txt.enabled = false
+// reports {
+// html.enabled = false
+// xml.enabled = false
+// txt.enabled = false
+// }
+}
+
+ktlint {
+ ignoreFailures = true
+ filter {
+ exclude("build.gradle-*.kts")
}
}
+kotlin {
+ jvmToolchain(21)
+}
+
+tasks.withType {
+ jvmTarget = "21"
+ onlyIf { project.findProperty("skipDetekt") != "true" }
+}
+
tasks {
withType {
- sourceCompatibility = "17"
- targetCompatibility = "17"
+ sourceCompatibility = "21"
+ targetCompatibility = "21"
}
withType {
- kotlinOptions.jvmTarget = "17"
- }
-
- withType {
- jvmTarget = "17"
+ kotlinOptions.jvmTarget = "21"
}
buildSearchableOptions {
@@ -122,12 +156,8 @@ tasks {
isScanForTestClasses = false
include("**/*Test.class")
}
+}
- runPluginVerifier {
- ideVersions.set(properties("pluginVerifierIdeVersions").split(',').map(String::trim).filter(String::isNotEmpty))
- }
-
- patchPluginXml {
- version.set(pluginVersion)
- }
+tasks.register("runPluginVerifier") {
+ intellijPlatform.verifyPlugin.ides.ide(IntelliJPlatformType.IntellijIdeaUltimate, properties("pluginVerifierIdeVersions"))
}
diff --git a/components/ide/jetbrains/backend-plugin/gradle-latest.properties b/components/ide/jetbrains/backend-plugin/gradle-latest.properties
index ab8943d5dd3e4f..0777c7606a6cde 100644
--- a/components/ide/jetbrains/backend-plugin/gradle-latest.properties
+++ b/components/ide/jetbrains/backend-plugin/gradle-latest.properties
@@ -1,9 +1,9 @@
# See https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
# for insight into build numbers and IntelliJ Platform versions.
-pluginSinceBuild=242.16677
+pluginSinceBuild=242.19533
pluginUntilBuild=242.*
# Plugin Verifier integration -> https://github.com/JetBrains/gradle-intellij-plugin#plugin-verifier-dsl
# See https://jb.gg/intellij-platform-builds-list for available build versions.
pluginVerifierIdeVersions=2024.2
# Version from "com.jetbrains.intellij.idea" which can be found at https://www.jetbrains.com/intellij-repository/snapshots
-platformVersion=242.16677-EAP-CANDIDATE-SNAPSHOT
+platformVersion=242.19533-EAP-CANDIDATE-SNAPSHOT
diff --git a/components/ide/jetbrains/backend-plugin/gradle.properties b/components/ide/jetbrains/backend-plugin/gradle.properties
index 6a53c31e926fa7..3241522ac84656 100644
--- a/components/ide/jetbrains/backend-plugin/gradle.properties
+++ b/components/ide/jetbrains/backend-plugin/gradle.properties
@@ -10,8 +10,8 @@ pluginName=gitpod-remote
platformType=IU
platformDownloadSources=true
# Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html
-# Example: platformPlugins = com.intellij.java, com.jetbrains.php:203.4449.22
-platformPlugins=Git4Idea, org.jetbrains.plugins.terminal, com.jetbrains.codeWithMe, org.jetbrains.idea.maven
+# Example: platformBundledPlugins = com.intellij.java, com.jetbrains.php:203.4449.22
+platformBundledPlugins=Git4Idea, org.jetbrains.plugins.terminal, com.jetbrains.codeWithMe, org.jetbrains.idea.maven
# Opt-out flag for bundling Kotlin standard library.
# See https://plugins.jetbrains.com/docs/intellij/kotlin.html#kotlin-standard-library for details.
kotlin.stdlib.default.dependency=false
diff --git a/components/ide/jetbrains/backend-plugin/gradle/wrapper/gradle-wrapper.properties b/components/ide/jetbrains/backend-plugin/gradle/wrapper/gradle-wrapper.properties
index ae04661ee73343..0d1842103b1020 100644
--- a/components/ide/jetbrains/backend-plugin/gradle/wrapper/gradle-wrapper.properties
+++ b/components/ide/jetbrains/backend-plugin/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/components/ide/jetbrains/backend-plugin/settings.gradle.kts b/components/ide/jetbrains/backend-plugin/settings.gradle.kts
index 93b4f2442988a8..c60278d57df397 100644
--- a/components/ide/jetbrains/backend-plugin/settings.gradle.kts
+++ b/components/ide/jetbrains/backend-plugin/settings.gradle.kts
@@ -2,7 +2,7 @@
// Licensed under the GNU Affero General Public License (AGPL).
// See License.AGPL.txt in the project root for license information.
-rootProject.name = "jetbrains-backend-plugin"
+rootProject.name = "gitpod-remote"
include(":supervisor-api")
val supervisorApiProjectPath: String by settings