From b38623f9a8af4fc8985b7662f6261bc5f0b5c0b2 Mon Sep 17 00:00:00 2001 From: Stephane Bouchet Date: Wed, 30 Oct 2024 15:44:42 +0100 Subject: [PATCH] chore: support IJ 2024.2 (#894) * chore: migrate build to 2024.2 Signed-off-by: Stephane Bouchet * chore: migrate build to 2024.2 fix sonar issues Signed-off-by: Stephane Bouchet * tests: disable service tests Signed-off-by: Stephane Bouchet * tests: disable service tests Signed-off-by: Stephane Bouchet * chore: support IJ 2024.2 Signed-off-by: Stephane Bouchet * chore: support IJ 2024.2 Signed-off-by: Stephane Bouchet --------- Signed-off-by: Stephane Bouchet --- .github/workflows/IJ-latest.yml | 4 +- .../cluster_integration_ui_tests.yml | 17 +- ...ml => no_context_integration_ui_tests.yml} | 2 +- .github/workflows/validate_IJ_versions.yml | 7 +- Jenkinsfile | 64 ---- build.gradle | 234 --------------- build.gradle.kts | 284 ++++++++++++++++++ gradle.properties | 26 +- gradle/libs.versions.toml | 47 +++ idea_license_token/idea.key.gpg | Bin 2701 -> 0 bytes settings.gradle.kts | 1 + .../test/ui/dialogs/ClusterLoginDialog.java | 1 - .../cluster_project/ChangeProjectDialog.java | 1 + .../ui/tests_cluster/CreateServiceTest.java | 2 +- .../test/ui/views/GettingStartedView.java | 5 +- .../utils/odo/OdoCliComponentTest.java | 2 +- .../component/CreateComponentAction.java | 6 +- .../application/ApplicationRootNodeOdo.java | 13 +- .../application/ApplicationsRootNode.java | 16 +- .../intellij/openshift/utils/odo/OdoCli.java | 24 +- .../openshift/utils/odo/SchemaHelper.java | 126 ++++---- src/main/resources/META-INF/plugin.xml | 4 +- .../ApplicationRootNodeOdoTest.java | 10 +- .../SandboxRegistrationServerMock.java | 234 ++++++++------- 24 files changed, 605 insertions(+), 525 deletions(-) rename .github/workflows/{public_integration_ui_tests.yml => no_context_integration_ui_tests.yml} (96%) delete mode 100644 Jenkinsfile delete mode 100644 build.gradle create mode 100644 build.gradle.kts create mode 100644 gradle/libs.versions.toml delete mode 100644 idea_license_token/idea.key.gpg create mode 100644 settings.gradle.kts diff --git a/.github/workflows/IJ-latest.yml b/.github/workflows/IJ-latest.yml index 19614ee12..b57cb0e88 100644 --- a/.github/workflows/IJ-latest.yml +++ b/.github/workflows/IJ-latest.yml @@ -23,7 +23,9 @@ jobs: - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Build with Gradle - run: ./gradlew build --continue -PideaVersion=IU-LATEST-EAP-SNAPSHOT + run: | + LATEST_EAP_SNAPSHOT=$(./gradlew printProductsReleases | grep 'IC-' | head -n 1 | cut -d'-' -f2) + ./gradlew build --continue -PplatformVersion=$LATEST_EAP_SNAPSHOT - uses: actions/upload-artifact@v4 if: always() with: diff --git a/.github/workflows/cluster_integration_ui_tests.yml b/.github/workflows/cluster_integration_ui_tests.yml index 11b051b8b..e677a40ad 100644 --- a/.github/workflows/cluster_integration_ui_tests.yml +++ b/.github/workflows/cluster_integration_ui_tests.yml @@ -23,6 +23,21 @@ jobs: validate-wrappers: true - uses: helm/kind-action@0025e74a8c7512023d06dc019c617aa3cf561fde #v1.10.0 name: Start cluster + # service setup disabled along with service test + # - name: Setup cluster + # run: | + # curl -sL https://github.com/operator-framework/operator-lifecycle-manager/releases/download/v0.26.0/install.sh | bash -s v0.26.0 + # kubectl create -f https://operatorhub.io/install/service-binding-operator.yaml + # kubectl create -f https://operatorhub.io/install/stable/cloud-native-postgresql.yaml + # nb=0 + # echo -n "Waiting for operator to show up " + # while [ "$nb" != "2" ] + # do + # echo -n "." + # sleep 1 + # nb=`kubectl get pods -n operators --no-headers --ignore-not-found | grep Running | wc -l` + # done + - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Play cluster integration UI tests @@ -34,7 +49,7 @@ jobs: export DISPLAY=:99.0 Xvfb -ac :99 -screen 0 1920x1080x16 & sleep 10 - ./gradlew clusterIntegrationUITest --continue + ./gradlew integrationUITest --continue - name: Publish tests reports if: always() uses: scacap/action-surefire-report@a2911bd1a4412ec18dde2d93b1758b3e56d2a880 #v1.8.0 diff --git a/.github/workflows/public_integration_ui_tests.yml b/.github/workflows/no_context_integration_ui_tests.yml similarity index 96% rename from .github/workflows/public_integration_ui_tests.yml rename to .github/workflows/no_context_integration_ui_tests.yml index c181bcfee..35706ad2a 100644 --- a/.github/workflows/public_integration_ui_tests.yml +++ b/.github/workflows/no_context_integration_ui_tests.yml @@ -31,7 +31,7 @@ jobs: export DISPLAY=:99.0 Xvfb -ac :99 -screen 0 1920x1080x16 & sleep 10 - ./gradlew publicIntegrationUITest --continue + ./gradlew integrationUITest --continue - name: Publish tests reports if: always() uses: scacap/action-surefire-report@a2911bd1a4412ec18dde2d93b1758b3e56d2a880 #v1.8.0 diff --git a/.github/workflows/validate_IJ_versions.yml b/.github/workflows/validate_IJ_versions.yml index 773534272..f053dd4de 100644 --- a/.github/workflows/validate_IJ_versions.yml +++ b/.github/workflows/validate_IJ_versions.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - IJ: [ IU-2022.3, IU-2023.1, IU-2023.2, IU-2023.3, IU-2024.1 ] + IJ: [ 2022.3, 2023.1, 2023.2, 2023.3, 2024.1, 2024.2 ] steps: - name: Checkout Code @@ -23,12 +23,13 @@ jobs: - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Build with Gradle - run: ./gradlew build -PideaVersion=${{ matrix.IJ }} + run: ./gradlew build -PplatformVersion=${{ matrix.IJ }} - name: Verify with Gradle - run: ./gradlew runPluginVerifier -PideaVersion=${{ matrix.IJ }} + run: ./gradlew verifyPlugin -PplatformVersion=${{ matrix.IJ }} - name: Upload report uses: actions/upload-artifact@v4 if: always() with: name: ${{ matrix.IJ }}-verifier-report path: build/reports/pluginVerifier + if-no-files-found: ignore diff --git a/Jenkinsfile b/Jenkinsfile deleted file mode 100644 index a454ef298..000000000 --- a/Jenkinsfile +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env groovy - -node('rhel7'){ - def recipientList = 'jbosstools-builds@lists.jboss.org' - def javaHome = tool 'openjdk-17' - env.JAVA_HOME = "${javaHome}" - - try { - stage('Checkout repo') { - deleteDir() - git url: 'https://github.com/redhat-developer/intellij-openshift-connector', - branch: "${sha1}" - } - - def props = readProperties file: 'gradle.properties' - def isSnapshot = props['projectVersion'].contains('-SNAPSHOT') - def version = isSnapshot?props['projectVersion'].replace('-SNAPSHOT', ".${env.BUILD_NUMBER}"):props['projectVersion'] + ".${env.BUILD_NUMBER}" - - stage('Build') { - sh "./gradlew assemble -PprojectVersion=${version}" - } - - stage('Package') { - sh "./gradlew buildPlugin -PprojectVersion=${version}" - } - - if(params.UPLOAD_LOCATION) { - stage('Upload') { - def filesToPush = findFiles(glob: '**/*.zip') - sh "sftp -C ${UPLOAD_LOCATION}/snapshots/intellij-openshift-connector/ <<< \$'put -p ${filesToPush[0].path}'" - stash name:'zip', includes:filesToPush[0].path - } - } - - if(publishToMarketPlace.equals('true')){ - timeout(time:5, unit:'DAYS') { - input message:'Approve deployment?', submitter: 'jmaury,adietish,sbouchet' - } - - def channel = isSnapshot?"nightly":"stable" - - stage("Publish to Marketplace") { - unstash 'zip' - withCredentials([[$class: 'StringBinding', credentialsId: 'JetBrains marketplace token', variable: 'TOKEN']]) { - sh "./gradlew publishPlugin -PjetBrainsToken=${TOKEN} -PprojectVersion=${version} -PjetBrainsChannel=${channel}" - } - archive includes:"**.zip" - - if (!isSnapshot) { - stage("Promote the build to stable") { - def zip = findFiles(glob: '**/*.zip') - sh "sftp -C ${UPLOAD_LOCATION}/stable/intellij-openshift-connector/ <<< \$'put -p ${zip[0].path}'" - currentBuild.keepLog = true - currentBuild.description = "${version}" - } - } - } - } - } catch (any) { - currentBuild.result = 'FAILURE' - step([$class: 'Mailer', notifyEveryUnstableBuild: true, recipients: "${recipientList}", sendToIndividuals: true]) - throw any - } -} diff --git a/build.gradle b/build.gradle deleted file mode 100644 index f7b5cedd0..000000000 --- a/build.gradle +++ /dev/null @@ -1,234 +0,0 @@ -buildscript { - ext.java_version = "17" -} - -plugins { - id 'org.jetbrains.intellij' version '1.17.4' - id 'com.adarshr.test-logger' version '4.0.0' - id 'idea' - id 'java' - id 'jacoco' - id 'org.sonarqube' version '5.1.0.4882' -} - -repositories { - mavenLocal() - maven { url 'https://repository.jboss.org' } - mavenCentral() - maven { url 'https://www.jetbrains.com/intellij-repository/snapshots' } - maven { url 'https://www.jetbrains.com/intellij-repository/releases' } - maven { url 'https://cache-redirector.jetbrains.com/intellij-dependencies' } -} - -configurations { - compileOptions { - sourceCompatibility = java_version - targetCompatibility = java_version - } -} - -intellij { - version = ideaVersion //for a full list of IntelliJ IDEA releases please see https://www.jetbrains.com/intellij-repository/releases - pluginName = 'org.jboss.tools.intellij.openshift' - // use '/build/idea-sandbox/plugins/' if working from source - plugins = [ - 'java', - 'terminal', - 'yaml', - 'com.redhat.devtools.intellij.telemetry:1.2.0.59', - 'com.redhat.devtools.intellij.kubernetes:1.3.0' - ] - updateSinceUntilBuild = false -} - -//with this option enabled, build will fail about IDEA expiration builds -buildSearchableOptions.enabled = false - -runPluginVerifier { - ideVersions = [ideaVersion] -} - -publishPlugin { - token = jetBrainsToken - channels = [jetBrainsChannel] -} - -configurations { - implementation { - exclude group: 'org.slf4j', module: 'slf4j-api' - } - integrationTestImplementation.extendsFrom testImplementation - integrationTestRuntimeOnly.extendsFrom testRuntimeOnly -} - -sourceSets { - integrationTest { - java.srcDir file('src/it/java') - resources.srcDir file('src/it/resources') - compileClasspath += sourceSets.main.output + sourceSets.test.output + configurations.testRuntimeClasspath - runtimeClasspath += output + compileClasspath - } -} - -test { - // Discover and execute JUnit4-based tests - useJUnit() - systemProperties['com.redhat.devtools.intellij.telemetry.mode'] = 'disabled' - jvmArgs "-Djava.awt.headless=true" - jacoco { - includeNoLocationClasses = true - excludes = ["jdk.internal.*"] - } -} - -tasks.register('integrationTest', Test) { - systemProperties['com.redhat.devtools.intellij.telemetry.mode'] = 'disabled' - description = 'Runs the integration tests.' - group = 'verification' - testClassesDirs = sourceSets.integrationTest.output.classesDirs - classpath = sourceSets.integrationTest.runtimeClasspath - outputs.upToDateWhen { false } - testlogger { - showStandardStreams true - showPassedStandardStreams false - showSkippedStandardStreams false - showFailedStandardStreams true - showFullStackTraces true - } - jvmArgs "-Djava.awt.headless=true" - jacoco { - includeNoLocationClasses = true - excludes = ["jdk.internal.*"] - } -} -classpathIndexCleanup { - dependsOn compileIntegrationTestJava -} - -tasks.register('clusterIntegrationUITest', Test) { - dependsOn copyKey - useJUnitPlatform { - includeTags 'ui-test' - } - systemProperties['com.redhat.devtools.intellij.telemetry.mode'] = 'disabled' - systemProperties['CLUSTER_ALREADY_LOGGED_IN'] = System.getenv('CLUSTER_ALREADY_LOGGED_IN') ?: 'false' - description = 'Runs the cluster integration UI tests.' - group = 'verification' - testClassesDirs = sourceSets.integrationTest.output.classesDirs - classpath = sourceSets.integrationTest.runtimeClasspath - outputs.upToDateWhen { true } - testlogger { - showStandardStreams true - showPassedStandardStreams false - showSkippedStandardStreams false - showFailedStandardStreams true - showFullStackTraces true - } - jvmArgs "-Djava.awt.headless=false" // use of clipboard in AboutPublicTest, set to false - jacoco { - includeNoLocationClasses = true - excludes = ["jdk.internal.*"] - } - include '**/ClusterTestsSuite.class' -} - -tasks.register('publicIntegrationUITest', Test) { - dependsOn copyKey - useJUnitPlatform { - includeTags 'ui-test' - } - systemProperties['com.redhat.devtools.intellij.telemetry.mode'] = 'disabled' - description = 'Runs the public integration UI tests.' - group = 'verification' - testClassesDirs = sourceSets.integrationTest.output.classesDirs - classpath = sourceSets.integrationTest.runtimeClasspath - outputs.upToDateWhen { true } - testlogger { - showStandardStreams true - showPassedStandardStreams false - showSkippedStandardStreams false - showFailedStandardStreams true - showFullStackTraces true - } - jvmArgs "-Djava.awt.headless=false" // use of clipboard in AboutPublicTest, set to false - jacoco { - includeNoLocationClasses = true - excludes = ["jdk.internal.*"] - } - include '**/PublicTestsSuite.class' - -} - -tasks.register('copyKey', Copy) { - from "idea_license_token/idea.key" - into "build/idea-sandbox/config-uiTest" -} - -dependencies { - implementation( - 'io.fabric8:openshift-client:6.12.0', - 'org.apache.commons:commons-compress:1.26.2', - 'org.apache.commons:commons-exec:1.4.0', - 'com.redhat.devtools.intellij:intellij-common:1.9.6', - 'io.jsonwebtoken:jjwt-impl:0.12.6', - 'io.jsonwebtoken:jjwt-jackson:0.12.6', - 'org.keycloak:keycloak-installed-adapter:24.0.5', - 'com.squareup.retrofit2:converter-jackson:2.11.0', - 'com.google.code.gson:gson:2.11.0') - testImplementation( - 'org.junit.platform:junit-platform-launcher:1.10.3', - 'org.mockito:mockito-core:5.12.0', - 'org.easytesting:fest-assert:1.4', - 'com.redhat.devtools.intellij:intellij-common:1.9.6:test', - 'org.awaitility:awaitility:4.2.2', - 'org.mock-server:mockserver-client-java:5.15.0', - 'org.mock-server:mockserver-netty:5.15.0', - 'com.redhat.devtools.intellij:intellij-common-ui-test-library:0.4.3-SNAPSHOT', - 'org.junit.jupiter:junit-jupiter-engine:5.10.3', - 'org.junit.jupiter:junit-jupiter-api:5.10.3', - 'org.junit.jupiter:junit-jupiter:5.10.3', - 'org.junit.platform:junit-platform-suite:1.10.3') - constraints { - implementation('io.undertow:undertow-core:2.3.15.Final') { //keycloak - because 'https://security.snyk.io/vuln/SNYK-JAVA-IOUNDERTOW-6567186' - } - implementation('org.bouncycastle:bcprov-jdk18on:1.78.1') { //keycloak - because 'https://app.snyk.io/vuln/SNYK-JAVA-ORGBOUNCYCASTLE-6612984' - } - implementation('com.squareup.okhttp3:okhttp:4.12.0') { //retrofit - because 'https://security.snyk.io/vuln/SNYK-JAVA-COMSQUAREUPOKHTTP3-2958044' - } - } -} - -sonar { - properties { - property "sonar.projectKey", "redhat-developer_intellij-openshift-connector" - property "sonar.organization", "redhat-developer" - property "sonar.host.url", "https://sonarcloud.io" - property "sonar.junit.reportsPath", layout.buildDirectory.dir("test-results").get().asFile.absolutePath - property "sonar.gradle.skipCompile", "true" - } -} - -jacocoTestReport { - getExecutionData().setFrom(fileTree(layout.buildDirectory).include("/jacoco/*.exec")) - reports { - xml.required = true - } -} - -runIde { - systemProperties['com.redhat.devtools.intellij.telemetry.mode'] = 'debug' - //systemProperties['jboss.sandbox.api.endpoint'] = 'http://localhost:3000' -} - -tasks.register('runSandbox', JavaExec) { - group = "Execution" - description = "Run the Sandbox registration server in port 3000" - classpath = sourceSets.test.runtimeClasspath - getMainClass().set 'org.jboss.tools.intellij.openshift.ui.sandbox.SandboxRegistrationServerMock' -} - -group 'org.jboss.tools.intellij' -version projectVersion // Plugin version diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 000000000..86dcb0054 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,284 @@ +import org.jetbrains.intellij.platform.gradle.IntelliJPlatformType +import org.jetbrains.intellij.platform.gradle.TestFrameworkType + +plugins { + id("java") // Java support + alias(libs.plugins.gradleIntelliJPlugin) // Gradle IntelliJ Plugin + alias(libs.plugins.testLogger) // Nice test logs + id("jacoco") // Code coverage + alias(libs.plugins.sonarqube) // SonarQube +} + +group = "org.jboss.tools.intellij" +version = providers.gradleProperty("projectVersion").get() // Plugin version +val ideaVersion = providers.gradleProperty("platformVersion").get() +val devtoolsCommonForTests = "com.redhat.devtools.intellij:intellij-common:" + libs.devtools.common + ":test" + +// Set the JVM language level used to build the project. +java { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 +} + +repositories { + mavenLocal() + maven { url = uri("https://repository.jboss.org") } + mavenCentral() + intellijPlatform { + defaultRepositories() + } +} + +dependencies { + intellijPlatform { + create(IntelliJPlatformType.IntellijIdeaCommunity, ideaVersion) + + // Bundled Plugin Dependencies. Uses `platformBundledPlugins` property from the gradle.properties file for bundled IntelliJ Platform plugins. + bundledPlugins(providers.gradleProperty("platformBundledPlugins").map { it.split(',') }) + + // Plugin Dependencies. Uses `platformPlugins` property from the gradle.properties file for plugin from JetBrains Marketplace. + plugins(providers.gradleProperty("platformPlugins").map { it.split(',') }) + + // for local plugin -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin-faq.html#how-to-add-a-dependency-on-a-plugin-available-in-the-file-system + //plugins.set(listOf(file("/path/to/plugin/"))) + + pluginVerifier() + + instrumentationTools() + + testFramework(TestFrameworkType.Platform) + } + + components { + withModule("com.redhat.devtools.intellij:intellij-common") { + withVariant("intellijPlatformComposedJar") { + attributes { + attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.JAR)) + } + } + } + } + + implementation(libs.openshift.client) + implementation(libs.devtools.common) + implementation(libs.keycloak) + implementation(libs.jjwt.impl) + implementation(libs.jjwt.jackson) + implementation(libs.converter.jackson) + implementation(libs.annotations) // to build against platform <= 2023.2 + + // for unit tests + testImplementation(libs.junit) + testImplementation(libs.mockito) + testImplementation(libs.easytesting) + testImplementation(libs.mockserver.client) + testImplementation(libs.mockserver.netty) + + constraints { + implementation("io.undertow:undertow-core:2.3.15.Final") { // keycloak + because("https://security.snyk.io/vuln/SNYK-JAVA-IOUNDERTOW-6567186") + } + implementation("org.bouncycastle:bcprov-jdk18on:1.78.1") { // keycloak + because("https://security.snyk.io/vuln/SNYK-JAVA-ORGBOUNCYCASTLE-6612984") + } + implementation("com.squareup.okhttp3:okhttp:4.12.0") { // converter.jackson/retrofit + because("https://security.snyk.io/vuln/SNYK-JAVA-COMSQUAREUPOKHTTP3-2958044") + } + } +} + +intellijPlatform { + buildSearchableOptions = false + + pluginConfiguration { + ideaVersion { + sinceBuild = providers.gradleProperty("pluginSinceBuild") + untilBuild = provider { null } + } + } + + publishing { + token = providers.gradleProperty("jetBrainsToken") + channels = providers.gradleProperty("jetBrainsChannel").map { listOf(it) } + } + + pluginVerification { + ides { + ide(IntelliJPlatformType.IntellijIdeaCommunity, ideaVersion) + } + freeArgs = listOf( + "-mute", + "TemplateWordInPluginId,TemplateWordInPluginName" + ) + } +} + +tasks { + wrapper { + gradleVersion = providers.gradleProperty("gradleVersion").get() + } + + runIde { + systemProperty("com.redhat.devtools.intellij.telemetry.mode", "debug") + findProperty("tools.dl.path")?.let { systemProperty("tools.dl.path", it) } + //systemProperty("jboss.sandbox.api.endpoint", "http://localhost:3000") // enable when running sandbox locally, see below + } + + test { + systemProperty("com.redhat.devtools.intellij.telemetry.mode", "disabled") + jvmArgs("-Djava.awt.headless=true") + } + + withType { + configure { + isIncludeNoLocationClasses = true + excludes = listOf("jdk.internal.*") + } + } + + jacocoTestReport { + executionData.setFrom(fileTree(layout.buildDirectory).include("/jacoco/*.exec")) + classDirectories.setFrom(instrumentCode) + reports { + xml.required = true + } + } + + jacocoTestCoverageVerification { + classDirectories.setFrom(instrumentCode) + } + + sonar { + properties { + property("sonar.projectKey", "redhat-developer_intellij-openshift-connector") + property("sonar.organization", "redhat-developer") + property("sonar.host.url", "https://sonarcloud.io") + property("sonar.junit.reportsPath", layout.buildDirectory.dir("test-results").get().asFile.absolutePath) + property("sonar.gradle.skipCompile", "true") + } + } + + register("runSandbox", JavaExec::class.java) { + group = "Execution" + description = "Run the Sandbox registration server in port 3000" + classpath = sourceSets.test.get().runtimeClasspath + mainClass.set("org.jboss.tools.intellij.openshift.ui.sandbox.SandboxRegistrationServerMock") + } + +} + +sourceSets { + create("it") { + description = "integrationTest" + compileClasspath += sourceSets.main.get().compileClasspath + sourceSets.test.get().compileClasspath + runtimeClasspath += output + compileClasspath + } +} + +configurations.all { + exclude(group = "org.slf4j", module = "slf4j-api") + exclude(group = "bundledPlugin", module = "Docker") // suppress multiple SLF4J providers +} + +configurations["itRuntimeOnly"].extendsFrom(configurations.testRuntimeOnly.get()) +configurations["itImplementation"].extendsFrom(configurations.testImplementation.get()) + +val integrationTest by intellijPlatformTesting.testIde.registering { + task { + systemProperty("com.redhat.devtools.intellij.telemetry.mode", "disabled") + findProperty("tools.dl.path")?.let { systemProperty("tools.dl.path", it) } + description = "Runs the integration tests." + group = "verification" + testClassesDirs = sourceSets["it"].output.classesDirs + classpath = sourceSets["it"].runtimeClasspath + testlogger { + showStandardStreams = true + showPassedStandardStreams = false + showSkippedStandardStreams = false + showFailedStandardStreams = true + showFullStackTraces = true + } + jvmArgs("-Djava.awt.headless=true") + shouldRunAfter(tasks["test"]) + } + + plugins { + robotServerPlugin() + } + + dependencies { + testImplementation(libs.junit.platform.launcher) + testImplementation(libs.junit.platform.suite) + testImplementation(libs.junit.jupiter) + testImplementation(libs.junit.jupiter.api) + testImplementation(libs.junit.jupiter.engine) + testImplementation(devtoolsCommonForTests) + testImplementation(libs.devtools.common.ui.test) + testImplementation(libs.awaitility) + } +} + +val integrationUITest by intellijPlatformTesting.testIde.registering { + task { + systemProperty("com.redhat.devtools.intellij.telemetry.mode", "disabled") + findProperty("tools.dl.path")?.let { systemProperty("tools.dl.path", it) } + findProperty("testProjectLocation")?.let { systemProperty("testProjectLocation", it) } + systemProperties["CLUSTER_ALREADY_LOGGED_IN"] = System.getenv("CLUSTER_ALREADY_LOGGED_IN") ?: false + description = "Runs the cluster integration UI tests." + group = "verification" + testClassesDirs = sourceSets["it"].output.classesDirs + classpath = sourceSets["it"].runtimeClasspath + testlogger { + showStandardStreams = true + showPassedStandardStreams = false + showSkippedStandardStreams = false + showFailedStandardStreams = true + showFullStackTraces = true + } + jvmArgs("-Djava.awt.headless=false") // use of clipboard in AboutPublicTest, set to false + val includes = if (System.getenv("CLUSTER_ALREADY_LOGGED_IN") == null) "**/PublicTestsSuite.class" else "**/ClusterTestsSuite.class" + include(includes) + useJUnitPlatform { + includeTags("ui-test") + } + shouldRunAfter(tasks["test"]) + } + + plugins { + robotServerPlugin() + } + + dependencies { + testImplementation(libs.junit.platform.launcher) + testImplementation(libs.junit.platform.suite) + testImplementation(libs.junit.jupiter) + testImplementation(libs.junit.jupiter.api) + testImplementation(libs.junit.jupiter.engine) + testImplementation(devtoolsCommonForTests) + testImplementation(libs.devtools.common.ui.test) + testImplementation(libs.awaitility) + } +} + +// https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin-tasks.html#runIdeForUiTests +val runIdeForUiTests by intellijPlatformTesting.runIde.registering { + task { + jvmArgumentProviders += CommandLineArgumentProvider { + listOf( + "-Dide.mac.message.dialogs.as.sheets=false", + "-Djb.privacy.policy.text=", + "-Djb.consents.confirmation.enabled=false", + ) + } + } + plugins { + robotServerPlugin() + } +} + +// below is only to correctly configure IDEA project settings +idea { + module { + testSources.from(sourceSets["it"].java.srcDirs) + } +} diff --git a/gradle.properties b/gradle.properties index 0cfeb80a2..74ee889dc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,28 @@ -ideaVersion=IC-2024.1 projectVersion=1.10.2-SNAPSHOT jetBrainsToken=invalid jetBrainsChannel=stable + +# IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension +# platformType = IC (not needed as hard-coded in gradle build directly) +platformVersion=2024.2 + +# Gradle Releases -> https://github.com/gradle/gradle/releases +gradleVersion = 8.5 + +# Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html +platformBundledPlugins = com.intellij.java, org.jetbrains.plugins.yaml, org.jetbrains.plugins.terminal +platformPlugins = com.redhat.devtools.intellij.telemetry:1.2.0.59, com.redhat.devtools.intellij.kubernetes:1.3.0 + +# Supported build number ranges and IntelliJ Platform versions -> https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html +pluginSinceBuild = 223 + +# Opt-out flag for bundling Kotlin standard library -> https://jb.gg/intellij-platform-kotlin-stdlib +kotlin.stdlib.default.dependency = false + +# Enable Gradle Configuration Cache -> https://docs.gradle.org/current/userguide/configuration_cache.html +org.gradle.configuration-cache = true + +# Enable Gradle Build Cache -> https://docs.gradle.org/current/userguide/build_cache.html +org.gradle.caching = true + +org.gradle.jvmargs=-XX\:MaxHeapSize\=512m -Xmx4g -Xms1g \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 000000000..3d50f20b0 --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,47 @@ +[versions] +# libraries +junit = "4.13.2" +openshift-client = "6.12.0" +devtools-common = "1.9.7-SNAPSHOT" +keycloak = "24.0.5" +jsonwebtoken = "0.12.6" +retrofit2 = "2.11.0" +mockito = "5.12.0" +easytesting = "1.4" +mockserver = "5.15.0" +junit-platform = "1.10.3" +junit-jupiter = "5.10.3" +devtools-common-ui-test = "0.4.3-SNAPSHOT" +awaitility = "4.2.2" +annotations = "24.0.0" + +# plugins +gradleIntelliJPlugin = "2.0.1" +testlogger = "4.0.0" +sonarqube = "5.1.0.4882" + +[libraries] +junit = { group = "junit", name = "junit", version.ref = "junit" } +openshift-client = { group = "io.fabric8", name = "openshift-client", version.ref = "openshift-client" } +devtools-common = { group = "com.redhat.devtools.intellij", name = "intellij-common", version.ref = "devtools-common" } +keycloak = { group = "org.keycloak", name = "keycloak-installed-adapter", version.ref = "keycloak" } +jjwt-impl = { group = "io.jsonwebtoken", name = "jjwt-impl", version.ref = "jsonwebtoken" } +jjwt-jackson = { group = "io.jsonwebtoken", name = "jjwt-jackson", version.ref = "jsonwebtoken" } +converter-jackson = { group = "com.squareup.retrofit2", name = "converter-jackson", version.ref = "retrofit2" } +mockito = { group = "org.mockito", name = "mockito-core", version.ref = "mockito" } +easytesting = { group = "org.easytesting", name = "fest-assert", version.ref = "easytesting" } +mockserver-client = { group = "org.mock-server", name = "mockserver-client-java", version.ref = "mockserver" } +mockserver-netty = { group = "org.mock-server", name = "mockserver-netty", version.ref = "mockserver" } +junit-platform-launcher = { group = "org.junit.platform", name = "junit-platform-launcher", version.ref = "junit-platform" } +junit-platform-suite = { group = "org.junit.platform", name = "junit-platform-suite", version.ref = "junit-platform" } +junit-jupiter = { group = "org.junit.jupiter", name = "junit-jupiter", version.ref = "junit-jupiter" } +junit-jupiter-api = { group = "org.junit.jupiter", name = "junit-jupiter-api", version.ref = "junit-jupiter" } +junit-jupiter-engine = { group = "org.junit.jupiter", name = "junit-jupiter-engine", version.ref = "junit-jupiter" } +devtools-common-ui-test = { group = "com.redhat.devtools.intellij", name = "intellij-common-ui-test-library", version.ref = "devtools-common-ui-test" } +awaitility = { group = "org.awaitility", name = "awaitility", version.ref = "awaitility" } +annotations = { group = "org.jetbrains", name = "annotations", version.ref = "annotations" } + +[plugins] +gradleIntelliJPlugin = { id = "org.jetbrains.intellij.platform", version.ref = "gradleIntelliJPlugin" } +testLogger = { id = "com.adarshr.test-logger", version.ref = "testlogger" } +sonarqube = { id = "org.sonarqube", version.ref = "sonarqube" } \ No newline at end of file diff --git a/idea_license_token/idea.key.gpg b/idea_license_token/idea.key.gpg deleted file mode 100644 index 2d018e755c761a40f994d76251f2be3e6e8a4c72..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2701 zcmV;83Uc*~4Fm}T2w;sa(^_xe-}%z&0h848GI9vnJsl0&=tJlu&Q#o}>ke855m!0sX9P#S^TCX>|DQn-dWoD?((;tJir{9lA$q_+zm^WbY( z%A+w`=}(>ZX4p_zs0hX0n=J@weu~b1wOg#LE}(!-tfUhy@y3dLf>-{&i#;2E4Y218 z>CTUCVyiRTWYwl|5aKq@*dEuCqB*p#Vks*U(Xovcp?w(mElClZ;oE+BR%XILPulos ztC-$?maaWc-kHSuEMaF zQf~jE52^sGoMp=OpJHQE#)C?ijWz60Hc=czVv8hA1`tKxwO_QOnwqy3n`OgtgpS+6 zc1hQi7rU<*IPy~!8fdk~y6*-i0i+K+{mVg7>B;MUF?zyCrcM^c9c>T%p<9nagHxTB!RCP+w) z)`G99OcwKH~IA5_jwGPfK+eLs+?m1&X>u@8goB4g#%k~5bAK* z7PM1%TjdqUk_V^E7O0Glm4pQFXQ(PKVQs?s$``fln5+j!Bu$ z7(`D7L$$7)3zYQ8$MpdJP#&J!3Ub7U*#IkgQvFSVZK?r#ttzdm57~2v zkDPtcvsv6@SqdUSBWI%8y~4HN$+kwDqf>fFaF}1)IS*N3sgNXVaUA}XJ_(SS9oO>x<7>XE08fc!i0~js|44E6QFBplk zV^{gH$QN)Mf?WKdwEqKgzbj7EU3v!uxz#F5eX!*(WY?GA;DyZ1!dBeTrV(>JciQc@KOh@kiTl%m3yq|;jNv0 z|Bexb&c#c+>J{L{oTip5n0nkfH&xJkK4>lw?ce0Hr&yy>d%9F%^s`HQ#C!w-H1*wy z3~~d7S`_j+3Yd=M2XX#+8=_$98qksGy-r5$;HQ)u&QzU+d`qUvH85A-<~W%h8Lt$) z?7u(>gt)H6-!ie}PU}c}uBbtn66?N@oA>e^Q9-N2;-NF8j$?|q6X<@uRHu_Xc~)4 z#JkohE2OV9Z@UYO70>dQ5w2gbfB+%p5Y<^;~ySgrp^|+Z}O!474Q+}-> zH|Zo_S6ED6W2F$70CbX&4z!%+I32K4{th++A=WqE4>=YXlU>FD5Rj;OXzl_LVf$0< zo1#^iq%4CHrLy*WTLl-1$x<=EEYR=Jst-wPl>Cb<}P>NkDkZe`LCE zm~?&hK-(f|Wj8b!g~|97+1Fx;dSO02n0m_xT*fdWxCNhZ!*+t!Zd#JS>HZLSds>A7 zZ34Avx$ItNwMD-iJNn+XhQ&yoY|*? z(4PA#Pc-*Z!~u2!uk<_J=2hvI9zEV1!HPdr+&xoJ{5YRJgTO=A zmz72kWB_Q_E90f4G<{z@?mi~aS%&c7l$p_niw_AM#oEXTkZ$DAIWug%I6G4R%uV`ITxjSR1eZV;EJQh7*-2()(>ICAHddMLLy4z>YwsQ+h zX~618vo}LvI|Es65Ed-5XapBstCMn2@VgJQ*wejl$%|ZCbsN28m&w?Ky8h1PxeOyt z?D1kqLe9nsJ~n?a%d)0?>2E&V+6x0)zVteP`$Qutn5d&cLO<#MjIdkL?hTBjm}*EI z)IQge=@78Gn=*!x{7u21r`gsn#lg^5FiMaqAPy;GZLa(q2O?dI(UHY*sJIufH@(PIeHX!tf<^hZmRWX1CLsY^~`#<}?X zMvJP!h(XpNu(D;-wGGzpHZe8MI5|WH_VE+axf0RcXt8V3RCL`IwR$J6e)})>zH%zYkPYyhvab+ zj;dob0ox0bZrc5DkVy{G=0$g9HbDU4~Afhh=DWg!= z@77p>8AHFB|6q?Uno%-TWnKcz2uO0)S0rLDF^j~z3^{A2MYMVchq+{xDr6r`ExhPi H^NigU;pr@; diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 000000000..f243fae8b --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1 @@ +rootProject.name = "intellij-openshift-connector" diff --git a/src/it/java/org/jboss/tools/intellij/openshift/test/ui/dialogs/ClusterLoginDialog.java b/src/it/java/org/jboss/tools/intellij/openshift/test/ui/dialogs/ClusterLoginDialog.java index 5d764ca22..bed3a6a9b 100644 --- a/src/it/java/org/jboss/tools/intellij/openshift/test/ui/dialogs/ClusterLoginDialog.java +++ b/src/it/java/org/jboss/tools/intellij/openshift/test/ui/dialogs/ClusterLoginDialog.java @@ -103,5 +103,4 @@ public void clickPasteLoginCommand() { find(ComponentFixture.class, byXpath(BUTTON_PASTE_LOGIN_COMMAND)).click(); } - } \ No newline at end of file diff --git a/src/it/java/org/jboss/tools/intellij/openshift/test/ui/dialogs/cluster_project/ChangeProjectDialog.java b/src/it/java/org/jboss/tools/intellij/openshift/test/ui/dialogs/cluster_project/ChangeProjectDialog.java index 946f118f4..f5049bb14 100644 --- a/src/it/java/org/jboss/tools/intellij/openshift/test/ui/dialogs/cluster_project/ChangeProjectDialog.java +++ b/src/it/java/org/jboss/tools/intellij/openshift/test/ui/dialogs/cluster_project/ChangeProjectDialog.java @@ -57,4 +57,5 @@ private boolean isDropdownMenuOpened() { return false; } } + } \ No newline at end of file diff --git a/src/it/java/org/jboss/tools/intellij/openshift/test/ui/tests_cluster/CreateServiceTest.java b/src/it/java/org/jboss/tools/intellij/openshift/test/ui/tests_cluster/CreateServiceTest.java index 807f960bd..a43fb4534 100644 --- a/src/it/java/org/jboss/tools/intellij/openshift/test/ui/tests_cluster/CreateServiceTest.java +++ b/src/it/java/org/jboss/tools/intellij/openshift/test/ui/tests_cluster/CreateServiceTest.java @@ -29,7 +29,7 @@ public class CreateServiceTest extends AbstractClusterTest { @Test @Order(1) - @Disabled + @Disabled("unstable") public void createServiceTest() { CreateNewServiceDialog createNewServiceDialog = CreateNewServiceDialog.open(robot); assertNotNull(createNewServiceDialog); diff --git a/src/it/java/org/jboss/tools/intellij/openshift/test/ui/views/GettingStartedView.java b/src/it/java/org/jboss/tools/intellij/openshift/test/ui/views/GettingStartedView.java index f57672d29..ece0ed236 100644 --- a/src/it/java/org/jboss/tools/intellij/openshift/test/ui/views/GettingStartedView.java +++ b/src/it/java/org/jboss/tools/intellij/openshift/test/ui/views/GettingStartedView.java @@ -99,7 +99,8 @@ private boolean isViewOpened() { return true; } catch (Exception ignored) { LOGGER.info("Getting Started view: View is not opened"); - return false; + return false; + } } -} + } diff --git a/src/it/java/org/jboss/tools/intellij/openshift/utils/odo/OdoCliComponentTest.java b/src/it/java/org/jboss/tools/intellij/openshift/utils/odo/OdoCliComponentTest.java index 6147e5e6d..0f353634b 100644 --- a/src/it/java/org/jboss/tools/intellij/openshift/utils/odo/OdoCliComponentTest.java +++ b/src/it/java/org/jboss/tools/intellij/openshift/utils/odo/OdoCliComponentTest.java @@ -65,7 +65,7 @@ public static void initTestProject() throws IOException { @AfterClass public static void deleteTestProject() throws IOException { - FileUtils.deleteDirectory(new File(COMPONENT_PATH)); + FileUtils.deleteDirectory(new File(COMPONENT_PATH + PROJECT_NAME)); } @Before diff --git a/src/main/java/org/jboss/tools/intellij/openshift/actions/component/CreateComponentAction.java b/src/main/java/org/jboss/tools/intellij/openshift/actions/component/CreateComponentAction.java index 71d52a797..cffe5379a 100644 --- a/src/main/java/org/jboss/tools/intellij/openshift/actions/component/CreateComponentAction.java +++ b/src/main/java/org/jboss/tools/intellij/openshift/actions/component/CreateComponentAction.java @@ -14,8 +14,8 @@ import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.text.StringUtil; import com.redhat.devtools.intellij.common.utils.UIHelper; -import org.apache.commons.lang3.StringUtils; import org.jboss.tools.intellij.openshift.Constants; import org.jboss.tools.intellij.openshift.actions.ActionUtils; import org.jboss.tools.intellij.openshift.actions.NodeUtils; @@ -141,10 +141,10 @@ protected CreateComponentModel getModel(Project project, Odo odo, Predicate doGetOdo() { if (odoFuture == null) { - this.odoFuture = ToolFactory.getInstance() - .createOdo(project) - .thenApply(tool -> { - ApplicationRootNodeOdo odo = new ApplicationRootNodeOdo(tool.get(), tool.isDownloaded(), this, processHelper); - loadProjectModel(odo, project); - return odo; - }); + this.odoFuture = + ReadAction.compute(() -> ToolFactory.getInstance() + .createOdo(project) + .thenApply(tool -> { + ApplicationRootNodeOdo odo = new ApplicationRootNodeOdo(tool.get(), tool.isDownloaded(), this, processHelper); + loadProjectModel(odo, project); + return odo; + })); } return odoFuture; } diff --git a/src/main/java/org/jboss/tools/intellij/openshift/utils/odo/OdoCli.java b/src/main/java/org/jboss/tools/intellij/openshift/utils/odo/OdoCli.java index 7ae2064bb..ebb77cfc9 100644 --- a/src/main/java/org/jboss/tools/intellij/openshift/utils/odo/OdoCli.java +++ b/src/main/java/org/jboss/tools/intellij/openshift/utils/odo/OdoCli.java @@ -18,6 +18,7 @@ import com.intellij.execution.process.ProcessEvent; import com.intellij.execution.process.ProcessHandler; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.Strings; import com.intellij.util.messages.MessageBus; import com.redhat.devtools.intellij.common.utils.ExecHelper; @@ -36,12 +37,20 @@ import io.fabric8.openshift.client.OpenShiftClient; import io.fabric8.openshift.client.dsl.OpenShiftOperatorHubAPIGroupDSL; import io.fabric8.openshift.client.impl.OpenShiftOperatorHubAPIGroupClient; +import org.jboss.tools.intellij.openshift.KubernetesLabels; +import org.jboss.tools.intellij.openshift.utils.Cli; +import org.jboss.tools.intellij.openshift.utils.KubernetesClientExceptionUtils; +import org.jboss.tools.intellij.openshift.utils.Serialization; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.StringReader; import java.net.HttpURLConnection; -import java.nio.file.Files; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -54,15 +63,6 @@ import java.util.function.BinaryOperator; import java.util.function.Function; import java.util.function.Supplier; -import org.apache.commons.io.FileUtils; -import org.jboss.tools.intellij.openshift.KubernetesLabels; -import org.jboss.tools.intellij.openshift.utils.Cli; -import org.jboss.tools.intellij.openshift.utils.KubernetesClientExceptionUtils; -import org.jboss.tools.intellij.openshift.utils.Serialization; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import static io.fabric8.openshift.client.OpenShiftClient.BASE_API_GROUP; import static org.jboss.tools.intellij.openshift.Constants.HOME_FOLDER; @@ -469,8 +469,8 @@ public void deleteComponent(String project, String context, String component, } catch (IOException e) { LOGGER.warn(e.getLocalizedMessage(), e); } - Files.delete(new File(dir, "devfile.yaml").toPath()); - FileUtils.deleteQuietly(new File(dir, PLUGIN_FOLDER)); + FileUtil.delete(new File(dir, "devfile.yaml").toPath()); + FileUtil.delete(new File(dir, PLUGIN_FOLDER).toPath()); } else { args.add("--namespace"); args.add(project); diff --git a/src/main/java/org/jboss/tools/intellij/openshift/utils/odo/SchemaHelper.java b/src/main/java/org/jboss/tools/intellij/openshift/utils/odo/SchemaHelper.java index 91265b56e..7025c2e9c 100644 --- a/src/main/java/org/jboss/tools/intellij/openshift/utils/odo/SchemaHelper.java +++ b/src/main/java/org/jboss/tools/intellij/openshift/utils/odo/SchemaHelper.java @@ -11,80 +11,80 @@ package org.jboss.tools.intellij.openshift.utils.odo; import com.fasterxml.jackson.databind.node.ObjectNode; -import org.apache.commons.lang3.StringUtils; +import com.intellij.openapi.util.text.StringUtil; import java.util.List; import java.util.StringTokenizer; public class SchemaHelper { - private static final String POD_COUNT_DESCRIPTOR = "urn:alm:descriptor:com.tectonic.ui:podCount"; - private static final String BOOLEAN_SWITCH_DESCRIPTOR = "urn:alm:descriptor:com.tectonic.ui:booleanSwitch"; - private static final String CHECKBOX_DESCRIPTOR = "urn:alm:descriptor:com.tectonic.ui:checkbox"; - private static final String NUMBER_DESCRIPTOR = "urn:alm:descriptor:com.tectonic.ui:number"; - private static final String SELECT_DESCRIPTOR = "urn:alm:descriptor:com.tectonic.ui:select:"; + private static final String POD_COUNT_DESCRIPTOR = "urn:alm:descriptor:com.tectonic.ui:podCount"; + private static final String BOOLEAN_SWITCH_DESCRIPTOR = "urn:alm:descriptor:com.tectonic.ui:booleanSwitch"; + private static final String CHECKBOX_DESCRIPTOR = "urn:alm:descriptor:com.tectonic.ui:checkbox"; + private static final String NUMBER_DESCRIPTOR = "urn:alm:descriptor:com.tectonic.ui:number"; + private static final String SELECT_DESCRIPTOR = "urn:alm:descriptor:com.tectonic.ui:select:"; - public static ObjectNode getAnnotatedSchema(ObjectNode schema, List descriptors) { - if (!schema.has("properties")) { - schema.set("properties", schema.objectNode()); - } - if (!schema.get("properties").has("spec")) { - ObjectNode spec = schema.objectNode(); - spec.set("type", spec.textNode("object")); - ((ObjectNode)schema.get("properties")).set("spec", spec); - } - ObjectNode spec = (ObjectNode) schema.get("properties").get("spec"); - for(OperatorCRDSpecDescriptor descriptor : descriptors) { - ObjectNode node = getSchema(spec, descriptor.getPath()); - if (StringUtils.isNotBlank(descriptor.getDisplayName())) { - node.set("displayName", node.textNode(descriptor.getDisplayName())); - } - if (StringUtils.isNotBlank(descriptor.getDisplayName())) { - node.set("description", node.textNode(descriptor.getDescription())); - } - annotateType(node, descriptor); - } - return schema; + public static ObjectNode getAnnotatedSchema(ObjectNode schema, List descriptors) { + if (!schema.has("properties")) { + schema.set("properties", schema.objectNode()); + } + if (!schema.get("properties").has("spec")) { + ObjectNode spec = schema.objectNode(); + spec.set("type", spec.textNode("object")); + ((ObjectNode) schema.get("properties")).set("spec", spec); + } + ObjectNode spec = (ObjectNode) schema.get("properties").get("spec"); + for (OperatorCRDSpecDescriptor descriptor : descriptors) { + ObjectNode node = getSchema(spec, descriptor.getPath()); + if (!StringUtil.isEmptyOrSpaces(descriptor.getDisplayName())) { + node.set("displayName", node.textNode(descriptor.getDisplayName())); + } + if (!StringUtil.isEmptyOrSpaces(descriptor.getDisplayName())) { + node.set("description", node.textNode(descriptor.getDescription())); + } + annotateType(node, descriptor); } + return schema; + } - private static void annotateType(ObjectNode node, OperatorCRDSpecDescriptor crdDescriptor) { - for(String descriptor : crdDescriptor.getDescriptors()) { - if (POD_COUNT_DESCRIPTOR.equals(descriptor)) { - node.set("type", node.textNode("integer")); - } else if (BOOLEAN_SWITCH_DESCRIPTOR.equals(descriptor) || CHECKBOX_DESCRIPTOR.equals(descriptor)) { - node.set("type", node.textNode("boolean")); - } else if (NUMBER_DESCRIPTOR.equals(descriptor)) { - node.set("type", node.textNode("number")); - } else if (descriptor.startsWith(SELECT_DESCRIPTOR)) { - if (!node.has("enum")) { - node.set("enum", node.arrayNode()); - } - String select = descriptor.substring(SELECT_DESCRIPTOR.length()); - node.withArray("enum").add(select); - } + private static void annotateType(ObjectNode node, OperatorCRDSpecDescriptor crdDescriptor) { + for (String descriptor : crdDescriptor.getDescriptors()) { + if (POD_COUNT_DESCRIPTOR.equals(descriptor)) { + node.set("type", node.textNode("integer")); + } else if (BOOLEAN_SWITCH_DESCRIPTOR.equals(descriptor) || CHECKBOX_DESCRIPTOR.equals(descriptor)) { + node.set("type", node.textNode("boolean")); + } else if (NUMBER_DESCRIPTOR.equals(descriptor)) { + node.set("type", node.textNode("number")); + } else if (descriptor.startsWith(SELECT_DESCRIPTOR)) { + if (!node.has("enum")) { + node.set("enum", node.arrayNode()); } + String select = descriptor.substring(SELECT_DESCRIPTOR.length()); + node.withArray("enum").add(select); + } } + } - private static ObjectNode getSchema(ObjectNode schema, String path) { - ObjectNode parent = schema; - StringTokenizer st = new StringTokenizer(path, "."); - while (st.hasMoreTokens()) { - String p = st.nextToken(); - if (!parent.has("properties")) { - parent.set("properties", parent.objectNode()); - } - if (parent.get("properties").has(p)) { - parent = (ObjectNode) parent.get("properties").get(p); - } else { - ObjectNode node = parent.objectNode(); - ((ObjectNode)parent.get("properties")).set(p, node); - if (st.hasMoreTokens()) { - node.set("type", node.textNode("object")); - } else { - node.set("type", node.textNode("string")); - } - parent = node; - } + private static ObjectNode getSchema(ObjectNode schema, String path) { + ObjectNode parent = schema; + StringTokenizer st = new StringTokenizer(path, "."); + while (st.hasMoreTokens()) { + String p = st.nextToken(); + if (!parent.has("properties")) { + parent.set("properties", parent.objectNode()); + } + if (parent.get("properties").has(p)) { + parent = (ObjectNode) parent.get("properties").get(p); + } else { + ObjectNode node = parent.objectNode(); + ((ObjectNode) parent.get("properties")).set(p, node); + if (st.hasMoreTokens()) { + node.set("type", node.textNode("object")); + } else { + node.set("type", node.textNode("string")); } - return parent; + parent = node; + } } + return parent; + } } diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 4f487aba6..8c9dd3c28 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -254,13 +254,11 @@ ]]> - - - com.intellij.modules.lang org.jetbrains.plugins.terminal + org.jetbrains.plugins.yaml com.redhat.devtools.intellij.telemetry com.intellij.modules.java diff --git a/src/test/java/org/jboss/tools/intellij/openshift/tree/application/ApplicationRootNodeOdoTest.java b/src/test/java/org/jboss/tools/intellij/openshift/tree/application/ApplicationRootNodeOdoTest.java index 03646216f..44ca7586b 100644 --- a/src/test/java/org/jboss/tools/intellij/openshift/tree/application/ApplicationRootNodeOdoTest.java +++ b/src/test/java/org/jboss/tools/intellij/openshift/tree/application/ApplicationRootNodeOdoTest.java @@ -10,7 +10,7 @@ ******************************************************************************/ package org.jboss.tools.intellij.openshift.tree.application; -import org.apache.commons.io.FileUtils; +import com.intellij.openapi.util.io.FileUtil; import org.jboss.tools.intellij.openshift.utils.odo.Component; import org.jboss.tools.intellij.openshift.utils.odo.ComponentDescriptor; import org.jboss.tools.intellij.openshift.utils.odo.ComponentFeatures; @@ -22,6 +22,7 @@ import java.io.File; import java.io.IOException; +import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -48,8 +49,8 @@ public class ApplicationRootNodeOdoTest { new ComponentFeatures(), "path2", null); - private static final File tempDir = FileUtils.getTempDirectory(); - private static final File destinationDir = FileUtils.getUserDirectory(); + private File tempDir; + private final File destinationDir = new File(System.getProperty("user.home")); private OdoDelegate odo; private ApplicationsRootNode rootNode; private ApplicationRootNodeOdo rootNodeOdo; @@ -57,6 +58,7 @@ public class ApplicationRootNodeOdoTest { @Before public void before() throws IOException { + tempDir = FileUtil.createTempDirectory("odo-test", ""); this.odo = mock(OdoDelegate.class); this.rootNode = mock(ApplicationsRootNode.class); this.fileOperations = mockFileOperations(); @@ -96,7 +98,7 @@ public void createComponent_should_create_files_copy_and_refresh_them_if_starter // then verify(odo).createComponent(componentType, registryName, component, tempDir.getAbsolutePath(), devfile, starter); verify(fileOperations).createTempDir(any()); - verify(fileOperations).copyTo(tempDir.getAbsoluteFile(), source); + verify(fileOperations).copyTo(tempDir, Path.of(source)); verify(fileOperations).refresh(destinationDir); } diff --git a/src/test/java/org/jboss/tools/intellij/openshift/ui/sandbox/SandboxRegistrationServerMock.java b/src/test/java/org/jboss/tools/intellij/openshift/ui/sandbox/SandboxRegistrationServerMock.java index 1b13f0b18..2ae4a893d 100644 --- a/src/test/java/org/jboss/tools/intellij/openshift/ui/sandbox/SandboxRegistrationServerMock.java +++ b/src/test/java/org/jboss/tools/intellij/openshift/ui/sandbox/SandboxRegistrationServerMock.java @@ -19,131 +19,133 @@ import java.util.concurrent.TimeUnit; public class SandboxRegistrationServerMock { - private static final java.util.concurrent.ScheduledExecutorService SCHEDULED_EXECUTOR_SERVICE = Executors.newSingleThreadScheduledExecutor(); - private final HttpServer server; + private static final java.util.concurrent.ScheduledExecutorService SCHEDULED_EXECUTOR_SERVICE = Executors.newSingleThreadScheduledExecutor(); + private final HttpServer server; - private String currentSignupResponse; + private String currentSignupResponse; - private static final String initialSignupResponse = "{\n" + - " \"apiEndpoint\": \"https://api.crc.testing:6443\",\n" + - " \"cheDashboardURL\": \"\",\n" + - " \"clusterName\": \"\",\n" + - " \"company\": \"\",\n" + - " \"compliantUsername\": \"\",\n" + - " \"consoleURL\": \"\",\n" + - " \"familyName\": \"\",\n" + - " \"givenName\": \"\",\n" + - " \"status\": {\n" + - " \"ready\": false,\n" + - " \"reason\": \"PendingApproval\",\n" + - " \"verificationRequired\": true\n" + - " },\n" + - " \"username\": \"\"\n" + - " }"; + private static final String INITIAL_SIGNUP_RESPONSE = """ + { + "apiEndpoint": "https://api.crc.testing:6443", + "cheDashboardURL": "", + "clusterName": "", + "company": "", + "compliantUsername": "", + "consoleURL": "", + "familyName": "", + "givenName": "", + "status": { + "ready": false, + "reason": "PendingApproval", + "verificationRequired": true + }, + "username": "" + }"""; - private static final String afterVerificationSignupResponse = "{\n" + - " \"apiEndpoint\": \"https://api.crc.testing:6443\",\n" + - " \"cheDashboardURL\": \"\",\n" + - " \"clusterName\": \"\",\n" + - " \"company\": \"\",\n" + - " \"compliantUsername\": \"\",\n" + - " \"consoleURL\": \"\",\n" + - " \"familyName\": \"\",\n" + - " \"givenName\": \"\",\n" + - " \"status\": {\n" + - " \"ready\": false,\n" + - " \"reason\": \"PendingApproval\",\n" + - " \"verificationRequired\": false\n" + - " },\n" + - " \"username\": \"\"\n" + - " }"; + private static final String AFTER_VERIFICATION_SIGNUP_RESPONSE = """ + { + "apiEndpoint": "https://api.crc.testing:6443", + "cheDashboardURL": "", + "clusterName": "", + "company": "", + "compliantUsername": "", + "consoleURL": "", + "familyName": "", + "givenName": "", + "status": { + "ready": false, + "reason": "PendingApproval", + "verificationRequired": false + }, + "username": "" + }"""; - private static final String afterVerification1SignupResponse = "{\n" + - " \"apiEndpoint\": \"https://api.crc.testing:6443\",\n" + - " \"cheDashboardURL\": \"\",\n" + - " \"clusterName\": \"\",\n" + - " \"company\": \"\",\n" + - " \"compliantUsername\": \"\",\n" + - " \"consoleURL\": \"\",\n" + - " \"familyName\": \"\",\n" + - " \"givenName\": \"\",\n" + - " \"status\": {\n" + - " \"ready\": false,\n" + - " \"reason\": \"\",\n" + - " \"verificationRequired\": false\n" + - " },\n" + - " \"username\": \"\"\n" + - " }"; + private static final String AFTER_VERIFICATION1_SIGNUP_RESPONSE = """ + { + "apiEndpoint": "https://api.crc.testing:6443", + "cheDashboardURL": "", + "clusterName": "", + "company": "", + "compliantUsername": "", + "consoleURL": "", + "familyName": "", + "givenName": "", + "status": { + "ready": false, + "reason": "", + "verificationRequired": false + }, + "username": "" + }"""; - private static final String afterVerification2SignupResponse = "{\n" + - " \"apiEndpoint\": \"https://api.crc.testing:6443\",\n" + - " \"cheDashboardURL\": \"\",\n" + - " \"clusterName\": \"\",\n" + - " \"company\": \"\",\n" + - " \"compliantUsername\": \"\",\n" + - " \"consoleURL\": \"\",\n" + - " \"familyName\": \"\",\n" + - " \"givenName\": \"\",\n" + - " \"status\": {\n" + - " \"ready\": true,\n" + - " \"reason\": \"\",\n" + - " \"verificationRequired\": false\n" + - " },\n" + - " \"username\": \"\"\n" + - " }"; + private static final String AFTER_VERIFICATION2_SIGNUP_RESPONSE = """ + { + "apiEndpoint": "https://api.crc.testing:6443", + "cheDashboardURL": "", + "clusterName": "", + "company": "", + "compliantUsername": "", + "consoleURL": "", + "familyName": "", + "givenName": "", + "status": { + "ready": true, + "reason": "", + "verificationRequired": false + }, + "username": "" + }"""; - public SandboxRegistrationServerMock(int port) throws IOException { - server = HttpServer.create(new InetSocketAddress(InetAddress.getByName(null), port), 0); + public SandboxRegistrationServerMock(int port) throws IOException { + server = HttpServer.create(new InetSocketAddress(InetAddress.getByName(null), port), 0); - server.createContext("/api/v1/signup", exchange -> { - if (exchange.getRequestMethod().equals("GET")) { - if (currentSignupResponse == null) { - exchange.sendResponseHeaders(404, 0); - exchange.getResponseBody().close(); - } else { - exchange.sendResponseHeaders(200, currentSignupResponse.getBytes().length); - exchange.getResponseBody().write(currentSignupResponse.getBytes()); - exchange.getResponseBody().close(); - } - } else if (exchange.getRequestMethod().equals("POST")) { - currentSignupResponse = initialSignupResponse; - exchange.sendResponseHeaders(200, 0); - exchange.getResponseBody().close(); - } - }); + server.createContext("/api/v1/signup", exchange -> { + if (exchange.getRequestMethod().equals("GET")) { + if (currentSignupResponse == null) { + exchange.sendResponseHeaders(404, 0); + exchange.getResponseBody().close(); + } else { + exchange.sendResponseHeaders(200, currentSignupResponse.getBytes().length); + exchange.getResponseBody().write(currentSignupResponse.getBytes()); + exchange.getResponseBody().close(); + } + } else if (exchange.getRequestMethod().equals("POST")) { + currentSignupResponse = INITIAL_SIGNUP_RESPONSE; + exchange.sendResponseHeaders(200, 0); + exchange.getResponseBody().close(); + } + }); - server.createContext("/api/v1/signup/verification", exchange -> { - if (exchange.getRequestMethod().equals("PUT")) { - exchange.sendResponseHeaders(204, 0); - exchange.getResponseBody().close(); - } else if (exchange.getRequestMethod().equals("GET")) { - currentSignupResponse = afterVerificationSignupResponse; - SCHEDULED_EXECUTOR_SERVICE.schedule(() -> { - currentSignupResponse = afterVerification1SignupResponse; - SCHEDULED_EXECUTOR_SERVICE.schedule(() -> { - currentSignupResponse = afterVerification2SignupResponse; - }, 10, TimeUnit.SECONDS); - }, 10, TimeUnit.SECONDS); - exchange.sendResponseHeaders(200, 0); - exchange.getResponseBody().close(); - } - }); - } + server.createContext("/api/v1/signup/verification", exchange -> { + if (exchange.getRequestMethod().equals("PUT")) { + exchange.sendResponseHeaders(204, 0); + exchange.getResponseBody().close(); + } else if (exchange.getRequestMethod().equals("GET")) { + currentSignupResponse = AFTER_VERIFICATION_SIGNUP_RESPONSE; + SCHEDULED_EXECUTOR_SERVICE.schedule(() -> { + currentSignupResponse = AFTER_VERIFICATION1_SIGNUP_RESPONSE; + SCHEDULED_EXECUTOR_SERVICE.schedule(() -> { + currentSignupResponse = AFTER_VERIFICATION2_SIGNUP_RESPONSE; + }, 10, TimeUnit.SECONDS); + }, 10, TimeUnit.SECONDS); + exchange.sendResponseHeaders(200, 0); + exchange.getResponseBody().close(); + } + }); + } - public SandboxRegistrationServerMock() throws IOException { - this(3000); - } + public SandboxRegistrationServerMock() throws IOException { + this(3000); + } - public void start() { - server.start(); - } + public void start() { + server.start(); + System.out.println("listening on port 3000....."); + System.out.println("Hit CTRL+C to stop process."); + } - public void stop() { - server.stop(0); - } - - public static void main(String[] args) throws IOException { - SandboxRegistrationServerMock server = new SandboxRegistrationServerMock(); - server.start(); - } + public static void main(String[] args) throws IOException { + SandboxRegistrationServerMock server = new SandboxRegistrationServerMock(); + server.start(); + } }