diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 3a8389f93..ccedaf90c 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -30,7 +30,7 @@ jobs: - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Run automated tests - run: ./gradlew test --no-daemon + run: ./gradlew clean test --no-daemon --no-build-cache --no-configuration-cache build-windows: runs-on: windows-latest @@ -54,7 +54,7 @@ jobs: - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Run automated tests - run: ./gradlew test --no-daemon + run: ./gradlew clean test --no-daemon --no-build-cache --no-configuration-cache build-macos: runs-on: macos-latest @@ -78,7 +78,7 @@ jobs: - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Run automated tests - run: ./gradlew test --no-daemon + run: ./gradlew clean test --no-daemon --no-build-cache --no-configuration-cache static-tests: runs-on: ubuntu-latest @@ -94,8 +94,8 @@ jobs: distribution: 'temurin' cache: gradle - name: Qodana - Code Quality - uses: JetBrains/qodana-action@v2024.2 + uses: JetBrains/qodana-action@v2025.3 with: cache-default-branch-only: true use-caches: true - args: '--baseline,qodana.sarif.json' + args: '--baseline qodana.sarif.json' diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a48e524f..820736e96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0). ### Fixed +- Read access assertion when enabling Magento support or resolving Magento version from plugin settings [#2692](https://github.com/magento/magento2-phpstorm-plugin/issues/2692) - Override this file in a project theme is not working [#2549](https://github.com/magento/magento2-phpstorm-plugin/issues/2549) ## 2026.2.0 diff --git a/build.gradle.kts b/build.gradle.kts index 5c0627332..b0ad77912 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,6 +6,9 @@ import org.jetbrains.changelog.Changelog import org.jetbrains.changelog.markdownToHTML import org.jetbrains.intellij.platform.gradle.TestFrameworkType +import org.gradle.api.tasks.testing.TestDescriptor +import org.gradle.api.tasks.testing.TestResult +import org.gradle.api.tasks.testing.TestListener plugins { id("java") @@ -50,7 +53,8 @@ repositories { dependencies { testImplementation("junit:junit:4.13.2") - testCompileOnly("org.junit.jupiter:junit-jupiter-api:5.10.2") + testCompileOnly("org.junit.jupiter:junit-jupiter-api:5.13.4") + testRuntimeOnly("org.junit.vintage:junit-vintage-engine:5.13.4") intellijPlatform { create(providers.gradleProperty("platformType"), providers.gradleProperty("platformVersion")) @@ -160,6 +164,24 @@ tasks { systemProperty("ide.fleet.launch", "false") useJUnitPlatform() + addTestListener(object : TestListener { + override fun beforeSuite(suite: TestDescriptor) = Unit + + override fun beforeTest(testDescriptor: TestDescriptor) = Unit + + override fun afterTest(testDescriptor: TestDescriptor, result: TestResult) = Unit + + override fun afterSuite(suite: TestDescriptor, result: TestResult) { + if (suite.parent == null) { + logger.lifecycle( + "Test summary: ${result.testCount} run, " + + "${result.successfulTestCount} passed, " + + "${result.failedTestCount} failed, " + + "${result.skippedTestCount} skipped" + ) + } + } + }) } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index dcf30e10c..315b919a7 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -4,7 +4,7 @@ junitJupiter = "5.12.0" # plugins changelog = "2.5.0" -intelliJPlatform = "2.11.0" +intelliJPlatform = "2.16.0" kotlin = "2.3.0" kover = "0.9.5" qodana = "2025.3.1" @@ -19,4 +19,4 @@ changelog = { id = "org.jetbrains.changelog", version.ref = "changelog" } intelliJPlatform = { id = "org.jetbrains.intellij.platform", version.ref = "intelliJPlatform" } kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } kover = { id = "org.jetbrains.kotlinx.kover", version.ref = "kover" } -qodana = { id = "org.jetbrains.qodana", version.ref = "qodana" } \ No newline at end of file +qodana = { id = "org.jetbrains.qodana", version.ref = "qodana" } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index a4b76b953..61285a659 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradlew b/gradlew index b740cf133..adff685a0 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/gradlew.bat b/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/qodana.yml b/qodana.yml index a5024279a..acc01a9fb 100644 --- a/qodana.yml +++ b/qodana.yml @@ -2,8 +2,8 @@ # https://www.jetbrains.com/help/qodana/qodana-yaml.html version: 1.0 -linter: jetbrains/qodana-jvm-community:2024.2 -projectJDK: "17" +linter: jetbrains/qodana-jvm-community:2025.3 +projectJDK: "21" profile: name: qodana.recommended exclude: diff --git a/runUiTests.sh b/runUiTests.sh deleted file mode 100644 index 899ab1fca..000000000 --- a/runUiTests.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -rm -rf intellij-test-project -./gradlew clean -./gradlew runIdeForUiTests & -RUN_IDE_PID=$! - -sleep 10 - -./gradlew test -PexcludeTests="**/reference/**,**/linemarker/**,**/inspections/**,**/completion/**,**/actions/**" --no-daemon - -kill $RUN_IDE_PID - -wait $RUN_IDE_PID 2>/dev/null \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index a9de2aac4..3b26c4dbc 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -6,5 +6,5 @@ rootProject.name = "Magento 2 and Adobe Commerce" plugins { - id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" + id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0" } diff --git a/src/main/java/com/magento/idea/magento2plugin/util/magento/MagentoVersionUtil.java b/src/main/java/com/magento/idea/magento2plugin/util/magento/MagentoVersionUtil.java index f4506bb29..c8928ac52 100644 --- a/src/main/java/com/magento/idea/magento2plugin/util/magento/MagentoVersionUtil.java +++ b/src/main/java/com/magento/idea/magento2plugin/util/magento/MagentoVersionUtil.java @@ -7,6 +7,7 @@ import com.intellij.json.psi.JsonFile; import com.intellij.json.psi.JsonObject; +import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; import com.intellij.openapi.vfs.LocalFileSystem; @@ -52,33 +53,35 @@ public static Pair getVersionData( final Project project, final String magentoPath ) { - final VirtualFile file = LocalFileSystem.getInstance().findFileByPath( - getFilePath(magentoPath) - ); - final Pair versionData = new Pair<>(DEFAULT_VERSION, null); - - if (file == null) { - return versionData; - } - final PsiManager psiManager = PsiManager.getInstance(project); - final PsiFile composerFile = psiManager.findFile(file); - - if (composerFile instanceof JsonFile) { - final JsonFile composerJsonFile = (JsonFile) composerFile; - final JsonObject jsonObject = PsiTreeUtil.getChildOfType( - composerJsonFile, - JsonObject.class + return ReadAction.compute(() -> { + final VirtualFile file = LocalFileSystem.getInstance().findFileByPath( + getFilePath(magentoPath) ); + final Pair versionData = new Pair<>(DEFAULT_VERSION, null); - if (jsonObject == null) { + if (file == null) { return versionData; } - final Pair version = GetMagentoVersionUtil.getVersion(jsonObject); - - return version == null ? versionData : version; - } + final PsiManager psiManager = PsiManager.getInstance(project); + final PsiFile composerFile = psiManager.findFile(file); + + if (composerFile instanceof JsonFile) { + final JsonFile composerJsonFile = (JsonFile) composerFile; + final JsonObject jsonObject = PsiTreeUtil.getChildOfType( + composerJsonFile, + JsonObject.class + ); + + if (jsonObject == null) { + return versionData; + } + final Pair version = GetMagentoVersionUtil.getVersion(jsonObject); + + return version == null ? versionData : version; + } - return versionData; + return versionData; + }); } private static String getFilePath(final String magentoPath) { diff --git a/src/test/java/com/magento/idea/magento2plugin/util/magento/MagentoVersionUtilTest.java b/src/test/java/com/magento/idea/magento2plugin/util/magento/MagentoVersionUtilTest.java new file mode 100644 index 000000000..0057997ca --- /dev/null +++ b/src/test/java/com/magento/idea/magento2plugin/util/magento/MagentoVersionUtilTest.java @@ -0,0 +1,32 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.util.magento; + +import com.intellij.openapi.util.Pair; +import com.intellij.testFramework.EdtTestUtil; +import com.magento.idea.magento2plugin.BaseProjectTestCase; +import java.nio.file.Path; +import java.util.concurrent.atomic.AtomicReference; + +public class MagentoVersionUtilTest extends BaseProjectTestCase { + public void testGetVersionDataCanReadComposerLockOnEdtWithoutExplicitReadAction() throws Exception { + final String magentoPath = Path.of( + getTestDataPath(), + "project", + "magento2" + ).toAbsolutePath().normalize().toString(); + + final AtomicReference> versionHolder = new AtomicReference<>(); + EdtTestUtil.runInEdtAndWait(() -> versionHolder.set(MagentoVersionUtil.getVersionData( + getProject(), + magentoPath + ))); + + assertNotNull(versionHolder.get()); + assertEquals("2.4.7", versionHolder.get().getFirst()); + assertEquals("Magento Open Source", versionHolder.get().getSecond()); + } +}