diff --git a/plugins/gradle/BUILD.bazel b/plugins/gradle/BUILD.bazel
index 31dd19a677ef..91252431fa01 100644
--- a/plugins/gradle/BUILD.bazel
+++ b/plugins/gradle/BUILD.bazel
@@ -168,6 +168,8 @@ jvm_library(
"//platform/smRunner:smRunner_test_lib",
"@lib//:gson",
"@lib//:guava",
+ "//platform/eel",
+ "//platform/eel-provider",
],
exports = ["//platform/external-system-api/testFramework"],
runtime_deps = [
diff --git a/plugins/gradle/intellij.gradle.tests.iml b/plugins/gradle/intellij.gradle.tests.iml
index d5cd1cacf157..b8b7ca563f1f 100644
--- a/plugins/gradle/intellij.gradle.tests.iml
+++ b/plugins/gradle/intellij.gradle.tests.iml
@@ -63,5 +63,7 @@
+
+
\ No newline at end of file
diff --git a/plugins/gradle/java/testSources/importing/GradleFindUsagesTest.java b/plugins/gradle/java/testSources/importing/GradleFindUsagesTest.java
index eb39a56d72e1..287b04195c37 100644
--- a/plugins/gradle/java/testSources/importing/GradleFindUsagesTest.java
+++ b/plugins/gradle/java/testSources/importing/GradleFindUsagesTest.java
@@ -6,7 +6,10 @@ import com.intellij.openapi.module.Module;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Segment;
import com.intellij.openapi.util.Trinity;
-import com.intellij.psi.*;
+import com.intellij.psi.JavaPsiFacade;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiMethod;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.PsiSearchHelper;
@@ -14,10 +17,8 @@ import com.intellij.psi.search.SearchScope;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.usageView.UsageInfo;
import com.intellij.util.containers.ContainerUtil;
-import org.gradle.wrapper.PathAssembler;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.jetbrains.plugins.gradle.service.execution.GradleUserHomeUtil;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration;
@@ -26,7 +27,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMe
import org.junit.Test;
import org.junit.runners.Parameterized;
-import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
@@ -50,16 +50,6 @@ public class GradleFindUsagesTest extends GradleImportingTestCase {
return Arrays.asList(new Object[][]{{BASE_GRADLE_VERSION}});
}
- @Override
- protected void collectAllowedRoots(List roots, PathAssembler.LocalDistribution distribution) {
- super.collectAllowedRoots(roots, distribution);
- File gradleUserHomeDir = GradleUserHomeUtil.gradleUserHomeDir();
- File generatedGradleJarsDir = new File(gradleUserHomeDir, "caches/" + getGradleVersion() + "/generated-gradle-jars");
- roots.add(generatedGradleJarsDir.getPath());
- File gradleDistLibDir = new File(distribution.getDistributionDir(), "gradle-" + getGradleVersion() + "/lib");
- roots.add(gradleDistLibDir.getPath());
- }
-
@Test
public void testBuildSrcClassesUsages() throws Exception {
createProjectSubFile("settings.gradle", "rootProject.name = 'multiproject'\n" +
diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleImportingTestCase.kt b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleImportingTestCase.kt
index 77be4a4129dd..96a9a702a196 100644
--- a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleImportingTestCase.kt
+++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleImportingTestCase.kt
@@ -31,12 +31,11 @@ import com.intellij.openapi.ui.TestDialogManager
import com.intellij.openapi.util.Couple
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.util.Ref
-import com.intellij.openapi.util.SystemInfo
import com.intellij.openapi.util.io.FileUtil
-import com.intellij.openapi.util.io.NioFiles
import com.intellij.openapi.util.text.Strings
import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.openapi.vfs.VirtualFile
+import com.intellij.platform.eel.provider.getEelDescriptor
import com.intellij.platform.testFramework.io.ExternalResourcesChecker.reportUnavailability
import com.intellij.testFramework.ExtensionTestUtil.maskExtensions
import com.intellij.testFramework.IdeaTestUtil
@@ -45,9 +44,9 @@ import com.intellij.util.SmartList
import com.intellij.util.ThrowableRunnable
import com.intellij.util.currentJavaVersion
import com.intellij.util.io.copyRecursively
-import org.gradle.StartParameter
+import com.intellij.util.io.createParentDirectories
+import com.intellij.util.io.delete
import org.gradle.util.GradleVersion
-import org.gradle.wrapper.PathAssembler
import org.jetbrains.annotations.NonNls
import org.jetbrains.plugins.gradle.frameworkSupport.GradleDsl
import org.jetbrains.plugins.gradle.frameworkSupport.settingsScript.GradleSettingScriptBuilder
@@ -65,21 +64,16 @@ import org.jetbrains.plugins.gradle.tooling.GradleJvmResolver.Companion.resolveG
import org.jetbrains.plugins.gradle.tooling.JavaVersionRestriction
import org.jetbrains.plugins.gradle.tooling.TargetJavaVersionWatcher
import org.jetbrains.plugins.gradle.tooling.VersionMatcherRule
-import org.jetbrains.plugins.gradle.util.GradleConstants
-import org.jetbrains.plugins.gradle.util.GradleUtil
+import org.jetbrains.plugins.gradle.util.*
import org.junit.Assume
import org.junit.Rule
import org.junit.rules.TestName
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import java.io.File
import java.io.IOException
-import java.io.UncheckedIOException
-import java.nio.file.Files
import java.nio.file.Path
import java.util.function.Consumer
-import java.util.zip.ZipException
-import java.util.zip.ZipFile
+import kotlin.io.path.exists
@RunWith(Parameterized::class)
abstract class GradleImportingTestCase : JavaExternalSystemImportingTestCase() {
@@ -95,7 +89,7 @@ abstract class GradleImportingTestCase : JavaExternalSystemImportingTestCase() {
@JvmField
var myGradleVersion: String? = null
- var gradleVersion: String
+ open var gradleVersion: String
get() = myGradleVersion!!
set(value) {
myGradleVersion = value
@@ -107,7 +101,6 @@ abstract class GradleImportingTestCase : JavaExternalSystemImportingTestCase() {
protected val currentGradleBaseVersion: GradleVersion
get() = GradleVersion.version(gradleVersion).baseVersion
- private var myProjectSettings: GradleProjectSettings? = null
var gradleJdkHome: String? = null
private set
@@ -116,13 +109,26 @@ abstract class GradleImportingTestCase : JavaExternalSystemImportingTestCase() {
private val deprecationError = Ref.create?>()
private val deprecationTextBuilder = StringBuilder()
- private var myDistribution: PathAssembler.LocalDistribution? = null
+ private var myProjectSettings: GradleProjectSettings? = null
+ private var myGradleDistributionRoot: Path? = null
private var deprecationTextLineCount = 0
private var originalGradleUserHome: Path? = null
protected open val isWarningsAllowed: Boolean
get() = false
+ protected val gradleUserHome: Path
+ get() {
+ val serviceDirectory = GradleSettings.getInstance(myProject).serviceDirectoryPath
+ return if (serviceDirectory != null) Path.of(serviceDirectory) else gradleUserHomeDir(Path.of(projectPath).getEelDescriptor())
+ }
+
+ override fun getTestsTempDir(): String = "tmp"
+ override fun getExternalSystemConfigFileName(): String = "build.gradle"
+ override fun getCurrentExternalProjectSettings(): GradleProjectSettings = myProjectSettings!!
+ override fun getExternalSystemId(): ProjectSystemId = GradleConstants.SYSTEM_ID
+ protected override fun runInDispatchThread(): Boolean = false
+
@Throws(Exception::class)
override fun setUp() {
Assume.assumeThat(gradleVersion, versionMatcherRule.matcher)
@@ -141,138 +147,18 @@ abstract class GradleImportingTestCase : JavaExternalSystemImportingTestCase() {
setRegistryPropertyForTest("unknown.sdk.auto", "false")
unknownSdkFixMode = TestUnknownSdkResolver.TestUnknownSdkFixMode.REAL_LOCAL_FIX
- cleanScriptsCacheIfNeeded()
-
installGradleJvmConfigurator()
installExecutionDeprecationChecker()
originalGradleUserHome = this.gradleUserHome
}
- protected open fun installGradleJvmConfigurator() {
- ExternalSystemApiUtil.subscribe(myProject, GradleConstants.SYSTEM_ID, object : ExternalSystemSettingsListener {
- override fun onProjectsLinked(settings: MutableCollection) {
- for (projectSettings in settings) {
- projectSettings.gradleJvm = GRADLE_JDK_NAME
- }
- }
- }, myTestDisposable)
- }
-
- protected open fun configureJdkTable() {
- cleanJdkTable()
- populateJdkTable(mutableListOf(createJdkFromJavaHome()))
- }
-
- protected fun cleanJdkTable() {
- removedSdks.clear()
- for (sdk in ProjectJdkTable.getInstance().getAllJdks()) {
- ProjectJdkTable.getInstance().removeJdk(sdk)
- if (GRADLE_JDK_NAME == sdk.getName()) continue
- removedSdks.add(sdk)
- }
- }
-
- protected fun populateJdkTable(jdks: List) {
- for (jdk in jdks) {
- ProjectJdkTable.getInstance().addJdk(jdk)
- }
- }
-
- protected open fun configureGradleVmOptions(options: MutableSet) {
- if (isGradleAtLeast("7.0") && !this.isWarningsAllowed) {
- options.add("-Dorg.gradle.warning.mode=fail")
- }
- }
-
- private val gradleVmOptions: MutableSet
- get() {
- val options: MutableSet = HashSet()
- configureGradleVmOptions(options)
- return options
- }
-
- private fun setUpGradleVmOptions() {
- val settings = GradleSystemSettings.getInstance()
- val defaultVmOptions = settings.gradleVmOptions ?: ""
-
- val requiredVmOptions = this.gradleVmOptions
- val effectiveVmOptions = String.format("%s %s", defaultVmOptions, Strings.join(requiredVmOptions, " ")).trim { it <= ' ' }
-
- settings.gradleVmOptions = effectiveVmOptions
- }
-
- private fun createJdkFromJavaHome(): Sdk {
- val jdkHomeDir = LocalFileSystem.getInstance().refreshAndFindFileByNioFile(Path.of(gradleJdkHome!!))
- val javaSdk = JavaSdk.getInstance()
- val javaSdkType: SdkType = javaSdk ?: SimpleJavaSdkType.getInstance()
- val jdk = SdkConfigurationUtil.setupSdk(arrayOfNulls(0), jdkHomeDir!!, javaSdkType, true, null, GRADLE_JDK_NAME)
- assertNotNull("Cannot create JDK for " + this.gradleJdkHome, jdk)
- return jdk!!
- }
-
@Throws(Exception::class)
override fun setUpInWriteAction() {
super.setUpInWriteAction()
this.gradleJdkHome = requireRealJdkHome()
- myDistribution = configureWrapper()
+ myGradleDistributionRoot = configureWrapper()
}
- protected val gradleUserHome: Path
- get() {
- val serviceDirectory = GradleSettings.getInstance(myProject).serviceDirectoryPath
- return if (serviceDirectory != null) Path.of(serviceDirectory) else gradleUserHomeDir().toPath()
- }
-
- /**
- * This is a workaround for the following issue on windows:
- * "C:\Users\builduser\.gradle\caches\jars-1\cache.properties (The system cannot find the file specified)"
- */
- private fun cleanScriptsCacheIfNeeded() {
- if (SystemInfo.isWindows && isGradleOlderThan("3.5")) {
- val gradleUserHome = this.gradleUserHome
- val cacheFile = gradleUserHome.resolve("caches/jars-1/cache.properties")
- if (Files.notExists(cacheFile)) {
- try {
- Files.createFile(NioFiles.createParentDirectories(cacheFile))
- }
- catch (e: IOException) {
- throw UncheckedIOException(e)
- }
- }
- val scriptsCacheFolder = gradleUserHome.resolve("caches").resolve(gradleVersion).resolve("scripts")
- try {
- NioFiles.deleteRecursively(scriptsCacheFolder)
- LOG.debug("Gradle scripts cache folder has been successfully removed at $scriptsCacheFolder")
- }
- catch (_: IOException) {
- LOG.debug("Gradle scripts cache folder has not been removed at $scriptsCacheFolder")
- }
- val scriptsRemappedCacheFolder = gradleUserHome.resolve("caches").resolve(gradleVersion).resolve("scripts-remapped")
- try {
- NioFiles.deleteRecursively(scriptsRemappedCacheFolder)
- LOG.debug("Gradle scripts-remapped cache folder has been successfully removed at $scriptsRemappedCacheFolder")
- }
- catch (_: IOException) {
- LOG.debug("Gradle scripts-remapped cache folder has not been removed at $scriptsRemappedCacheFolder")
- }
- }
- }
-
- protected override fun runInDispatchThread(): Boolean = false
-
- private fun requireRealJdkHome(): String {
- if (myWSLDistribution != null) {
- return requireWslJdkHome(myWSLDistribution!!)
- }
- return requireJdkHome()
- }
-
- open fun requireJdkHome(): String {
- return requireJdkHome(this.currentGradleVersion, myTargetJavaVersionWatcher.restriction)
- }
-
- protected open fun collectAllowedRoots(roots: MutableList, distribution: PathAssembler.LocalDistribution) = Unit
-
@Throws(Exception::class)
override fun tearDown() {
if (this.gradleJdkHome == null) {
@@ -312,27 +198,16 @@ abstract class GradleImportingTestCase : JavaExternalSystemImportingTestCase() {
roots.add(this.gradleJdkHome!!)
roots.addAll(collectRootsInside(this.gradleJdkHome!!))
roots.add(PathManager.getConfigPath())
- val gradleHomeEnv = getVariable("GRADLE_USER_HOME")
- if (gradleHomeEnv != null) roots.add(gradleHomeEnv)
+ roots.add(myGradleDistributionRoot.toString())
+ roots.add(gradleUserHome.toString())
val javaHome = getVariable("JAVA_HOME")
if (javaHome != null) roots.add(javaHome)
-
- collectAllowedRoots(roots, myDistribution!!)
}
- override fun getTestsTempDir(): String = "tmp"
-
- override fun getExternalSystemConfigFileName(): String = "build.gradle"
-
- protected fun importProjectUsingSingeModulePerGradleProject() {
- currentExternalProjectSettings.isResolveModulePerSourceSet = false
- importProject()
- }
-
- @Throws(IOException::class)
- protected fun importProjectUsingSingeModulePerGradleProject(config: @NonNls String) {
- currentExternalProjectSettings.isResolveModulePerSourceSet = false
- importProject(config)
+ override fun createImportSpec(): ImportSpec {
+ val importSpecBuilder = ImportSpecBuilder(super.createImportSpec())
+ importSpecBuilder.withArguments("--stacktrace")
+ return importSpecBuilder.build()
}
@Throws(IOException::class)
@@ -345,11 +220,205 @@ abstract class GradleImportingTestCase : JavaExternalSystemImportingTestCase() {
handleDeprecationError(deprecationError.get())
}
+ override fun handleImportFailure(errorMessage: String, errorDetails: String?) {
+ val combinedMessage = errorMessage + "\n" + errorDetails
+ if (combinedMessage.contains("org.gradle.wrapper.Download.download") && combinedMessage.contains("java.net.SocketException")) {
+ reportUnavailability("Gradle distribution service", null)
+ }
+ super.handleImportFailure(errorMessage, errorDetails)
+ }
+
+ @Throws(IOException::class)
+ open fun importProject(config: @NonNls String) {
+ importProject(config, null)
+ }
+
+ open fun requireJdkHome(): String {
+ return requireJdkHome(this.currentGradleVersion, myTargetJavaVersionWatcher.restriction)
+ }
+
+ protected open fun configureGradleVmOptions(options: MutableSet) {
+ if (isGradleAtLeast("7.0") && !this.isWarningsAllowed) {
+ options.add("-Dorg.gradle.warning.mode=fail")
+ }
+ }
+
+ protected open fun installGradleJvmConfigurator() {
+ ExternalSystemApiUtil.subscribe(myProject, GradleConstants.SYSTEM_ID, object : ExternalSystemSettingsListener {
+ override fun onProjectsLinked(settings: MutableCollection) {
+ for (projectSettings in settings) {
+ projectSettings.gradleJvm = GRADLE_JDK_NAME
+ }
+ }
+ }, myTestDisposable)
+ }
+
+ protected open fun configureJdkTable() {
+ cleanJdkTable()
+ populateJdkTable(mutableListOf(createJdkFromJavaHome()))
+ }
+
protected open fun handleDeprecationError(errorInfo: Couple?) {
if (errorInfo == null) return
handleImportFailure(errorInfo.first!!, errorInfo.second)
}
+ protected open fun injectRepo(config: @NonNls String): String {
+ val mavenRepositoryPatch =
+ """
+ allprojects {
+ repositories {
+ maven {
+ url = 'https://repo.labs.intellij.net/repo1'
+ }
+ }
+ }
+
+ """.trimIndent()
+ if (config.contains(MAVEN_REPOSITORY_PATCH_PLACE)) {
+ return config.replace(MAVEN_REPOSITORY_PATCH_PLACE, mavenRepositoryPatch)
+ }
+ else {
+ return mavenRepositoryPatch + config
+ }
+ }
+
+ fun script(configure: Consumer): String {
+ val builder = createBuildScriptBuilder()
+ configure.accept(builder)
+ return builder.generate()
+ }
+
+ fun settingsScript(configure: Consumer>): String {
+ val builder = create(this.currentGradleVersion, GradleDsl.GROOVY)
+ configure.accept(builder)
+ return builder.generate()
+ }
+
+ protected fun cleanJdkTable() {
+ removedSdks.clear()
+ for (sdk in ProjectJdkTable.getInstance().getAllJdks()) {
+ ProjectJdkTable.getInstance().removeJdk(sdk)
+ if (GRADLE_JDK_NAME == sdk.getName()) continue
+ removedSdks.add(sdk)
+ }
+ }
+
+ protected fun populateJdkTable(jdks: List) {
+ for (jdk in jdks) {
+ ProjectJdkTable.getInstance().addJdk(jdk)
+ }
+ }
+
+ protected fun importProjectUsingSingeModulePerGradleProject() {
+ currentExternalProjectSettings.isResolveModulePerSourceSet = false
+ importProject()
+ }
+
+ @Throws(IOException::class)
+ protected fun importProjectUsingSingeModulePerGradleProject(config: @NonNls String) {
+ currentExternalProjectSettings.isResolveModulePerSourceSet = false
+ importProject(config)
+ }
+
+ protected fun createBuildScriptBuilder(): TestGradleBuildScriptBuilder = TestGradleBuildScriptBuilder(this.currentGradleVersion)
+ .addPrefix(MAVEN_REPOSITORY_PATCH_PLACE, "")
+
+ protected fun createEmptyGradleRunConfiguration(name: String): GradleRunConfiguration {
+ val runManager = RunManagerEx.getInstanceEx(myProject)
+ val settings = runManager.createConfiguration(name, GradleExternalTaskConfigurationType::class.java)
+ return settings.getConfiguration() as GradleRunConfiguration
+ }
+
+ @Throws(IOException::class)
+ protected fun createSettingsFile(content: @NonNls String): VirtualFile = createProjectSubFile("settings.gradle", content)
+
+ /**
+ * Produces settings content and creates necessary directories.
+ * @param projects list of sub-project to create
+ * @return a block of `include 'project-name'` lines for settings.gradle
+ */
+ protected fun including(vararg projects: String): String = including(myProjectRoot, *projects)
+
+ protected fun including(root: VirtualFile?, vararg projects: String): String {
+ assertNotNull(root)
+ return TestGradleSettingsScriptHelper(root!!.toNioPath(), projects as Array).build()
+ }
+
+ protected fun assertMergedModuleCompileLibDepScope(moduleName: String, depName: String) {
+ assertModuleLibDepScope(moduleName, depName, DependencyScope.COMPILE)
+ }
+
+ protected fun assertMergedModuleCompileModuleDepScope(moduleName: String, depName: String) {
+ assertModuleModuleDepScope(moduleName, depName, DependencyScope.COMPILE)
+ }
+
+ protected fun isGradleOlderThan(ver: String): Boolean {
+ return GradleVersionUtil.isGradleOlderThan(this.currentGradleBaseVersion, ver)
+ }
+
+ protected fun isGradleAtLeast(ver: String): Boolean {
+ return GradleVersionUtil.isGradleAtLeast(this.currentGradleBaseVersion, ver)
+ }
+
+ protected fun convertToLibraryName(fsRoot: VirtualFile): String = "Gradle: ${fsRoot.getName()}"
+
+ protected fun enableGradleDebugWithSuspend() {
+ val settings = GradleSystemSettings.getInstance()
+ val currentOptions = settings.gradleVmOptions ?: ""
+ settings.gradleVmOptions = "$currentOptions -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005"
+ }
+
+ @Throws(IOException::class)
+ protected fun overrideGradleUserHome(relativeUserHomePath: String) {
+ val gradleUserHome = myTestDir.resolve(relativeUserHomePath)
+ if (myGradleDistributionRoot!!.exists()) {
+ val targetGradleDistribution = getGradleDistributionRoot(gradleUserHome, currentGradleVersion)
+ targetGradleDistribution.createParentDirectories()
+ myGradleDistributionRoot!!.copyRecursively(targetGradleDistribution)
+ }
+ GradleSettings.getInstance(myProject).setServiceDirectoryPath(gradleUserHome.toString())
+ }
+
+ protected fun resetGradleUserHomeIfNeeded() {
+ if (originalGradleUserHome != this.gradleUserHome) {
+ val normalizedOldGradleUserHome = originalGradleUserHome!!.normalize().toString()
+ val canonicalOldGradleUserHome = FileUtil.toCanonicalPath(normalizedOldGradleUserHome)
+ GradleSettings.getInstance(myProject).setServiceDirectoryPath(canonicalOldGradleUserHome)
+ }
+ }
+
+ private fun configureWrapper(): Path {
+ myProjectSettings!!.distributionType = DistributionType.DEFAULT_WRAPPED
+ val projectRoot = myProjectRoot.toNioPath()
+ generateGradleWrapper(projectRoot, currentGradleVersion)
+
+ val gradleJarPath = getGradleDistributionJarPath(projectRoot)
+ val gradleDistributionRootPath = gradleJarPath.parent.parent
+ validateGradleJar(gradleJarPath)
+
+ if (!gradleJarPath.exists()) {
+ val localDistributionRoot = getLocalGradleDistributionRoot(currentGradleVersion)
+ if (localDistributionRoot != gradleDistributionRootPath && localDistributionRoot.exists()) {
+ gradleDistributionRootPath.delete(true)
+ localDistributionRoot.copyRecursively(gradleDistributionRootPath)
+ }
+ }
+ return gradleDistributionRootPath
+ }
+
+ private fun tearDownGradleVmOptions() {
+ GradleSystemSettings.getInstance().gradleVmOptions = ""
+ }
+
+ private fun requireWslJdkHome(distribution: WSLDistribution): String {
+ var jdkPath = System.getProperty("wsl.jdk.path")
+ if (jdkPath == null) {
+ jdkPath = "/usr/lib/jvm/java-11-openjdk-amd64"
+ }
+ return distribution.getWindowsPath(jdkPath)
+ }
+
private fun installExecutionDeprecationChecker() {
val notificationManager = ExternalSystemProgressNotificationManager.getInstance()
val notificationListener: ExternalSystemTaskNotificationListener = object : ExternalSystemTaskNotificationListener {
@@ -372,180 +441,31 @@ abstract class GradleImportingTestCase : JavaExternalSystemImportingTestCase() {
notificationManager.addNotificationListener(notificationListener, myTestDisposable)
}
- override fun handleImportFailure(errorMessage: String, errorDetails: String?) {
- val combinedMessage = errorMessage + "\n" + errorDetails
- if (combinedMessage.contains("org.gradle.wrapper.Download.download") && combinedMessage.contains("java.net.SocketException")) {
- reportUnavailability("Gradle distribution service", null)
+ private fun requireRealJdkHome(): String {
+ if (myWSLDistribution != null) {
+ return requireWslJdkHome(myWSLDistribution!!)
}
- super.handleImportFailure(errorMessage, errorDetails)
+ return requireJdkHome()
}
- @Throws(IOException::class)
- open fun importProject(config: @NonNls String) {
- importProject(config, null)
- }
-
- protected fun createBuildScriptBuilder(): TestGradleBuildScriptBuilder = TestGradleBuildScriptBuilder(this.currentGradleVersion)
- .addPrefix(MAVEN_REPOSITORY_PATCH_PLACE, "")
-
- fun script(configure: Consumer): String {
- val builder = createBuildScriptBuilder()
- configure.accept(builder)
- return builder.generate()
- }
-
- fun settingsScript(configure: Consumer>): String {
- val builder = create(this.currentGradleVersion, GradleDsl.GROOVY)
- configure.accept(builder)
- return builder.generate()
- }
-
- override fun createImportSpec(): ImportSpec {
- val importSpecBuilder = ImportSpecBuilder(super.createImportSpec())
- importSpecBuilder.withArguments("--stacktrace")
- return importSpecBuilder.build()
- }
-
- protected open fun injectRepo(config: @NonNls String): String {
- val mavenRepositoryPatch =
- """
- allprojects {
- repositories {
- maven {
- url = 'https://repo.labs.intellij.net/repo1'
- }
- }
- }
- """.trimIndent()
- if (config.contains(MAVEN_REPOSITORY_PATCH_PLACE)) {
- return config.replace(MAVEN_REPOSITORY_PATCH_PLACE, mavenRepositoryPatch)
- }
- else {
- return mavenRepositoryPatch + config
- }
- }
-
- protected fun createEmptyGradleRunConfiguration(name: String): GradleRunConfiguration {
- val runManager = RunManagerEx.getInstanceEx(myProject)
- val settings = runManager.createConfiguration(name, GradleExternalTaskConfigurationType::class.java)
- return settings.getConfiguration() as GradleRunConfiguration
- }
-
- override fun getCurrentExternalProjectSettings(): GradleProjectSettings = myProjectSettings!!
-
- override fun getExternalSystemId(): ProjectSystemId = GradleConstants.SYSTEM_ID
-
- @Throws(IOException::class)
- protected fun createSettingsFile(content: @NonNls String): VirtualFile = createProjectSubFile("settings.gradle", content)
-
- /**
- * Produces settings content and creates necessary directories.
- * @param projects list of sub-project to create
- * @return a block of `include 'project-name'` lines for settings.gradle
- */
- protected fun including(vararg projects: String): String = including(myProjectRoot, *projects)
-
- protected fun including(root: VirtualFile?, vararg projects: String): String {
- assertNotNull(root)
- return TestGradleSettingsScriptHelper(root!!.toNioPath(), projects as Array).build()
- }
-
- private fun configureWrapper(): PathAssembler.LocalDistribution {
- myProjectSettings!!.distributionType = DistributionType.DEFAULT_WRAPPED
-
- // Cannot generate Gradle wrapper using virtual files system.
- // Because the K2MppHighlightingIntegrationTest.testJvmMultifileClass test implicitly depends on the VFS cache.
- // Calling the for VFS refresh after Gradle wrapper generation using Java NIO API also fails this KMP test
- generateGradleWrapper(myProjectRoot.toNioPath(), this.currentGradleVersion)
-
- // VfsUtil.markDirtyAndRefresh(false, true, true, myProjectRoot)
- val wrapperConfiguration = GradleUtil.getWrapperConfiguration(myProjectRoot.toNioPath())
- val pathAssembler = PathAssembler(StartParameter.DEFAULT_GRADLE_USER_HOME, File(projectPath))
- val localDistribution = pathAssembler.getDistribution(wrapperConfiguration)
-
- val zip = localDistribution.zipFile
- try {
- if (zip.exists()) {
- try {
- ZipFile(zip).close()
- }
- catch (e: ZipException) {
- e.printStackTrace()
- println("Corrupted file will be removed: $zip")
- Files.delete(zip.toPath())
- }
- }
- }
- catch (e: IOException) {
- e.printStackTrace()
- }
- return localDistribution
- }
-
- protected fun assertMergedModuleCompileLibDepScope(moduleName: String, depName: String) {
- assertModuleLibDepScope(moduleName, depName, DependencyScope.COMPILE)
- }
-
- protected fun assertMergedModuleCompileModuleDepScope(moduleName: String, depName: String) {
- assertModuleModuleDepScope(moduleName, depName, DependencyScope.COMPILE)
- }
-
- protected fun isGradleOlderThan(ver: String): Boolean {
- return GradleVersionUtil.isGradleOlderThan(this.currentGradleBaseVersion, ver)
- }
-
- protected fun isGradleAtLeast(ver: String): Boolean {
- return GradleVersionUtil.isGradleAtLeast(this.currentGradleBaseVersion, ver)
- }
-
- protected fun enableGradleDebugWithSuspend() {
+ private fun setUpGradleVmOptions() {
val settings = GradleSystemSettings.getInstance()
- val currentOptions = settings.gradleVmOptions ?: ""
- settings.gradleVmOptions = "$currentOptions -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005"
+ val defaultVmOptions = settings.gradleVmOptions ?: ""
+
+ val requiredVmOptions = mutableSetOf()
+ configureGradleVmOptions(requiredVmOptions)
+
+ val effectiveVmOptions = String.format("%s %s", defaultVmOptions, Strings.join(requiredVmOptions, " ")).trim { it <= ' ' }
+ settings.gradleVmOptions = effectiveVmOptions
}
- @Throws(IOException::class)
- protected fun overrideGradleUserHome(relativeUserHomePath: String) {
- val gradleUserHome = myTestDir.resolve(relativeUserHomePath)
- val gradleCachedFolderName = "gradle-$gradleVersion-bin"
- val cachedGradleDistribution = findGradleDistributionInCache(gradleCachedFolderName)
- if (cachedGradleDistribution != null) {
- val targetGradleDistribution = gradleUserHome.resolve("wrapper/dists/").resolve(gradleCachedFolderName)
- Files.createDirectories(targetGradleDistribution.parent)
- cachedGradleDistribution.copyRecursively(targetGradleDistribution)
- }
- GradleSettings.getInstance(myProject).setServiceDirectoryPath(gradleUserHome.toString())
- }
-
- protected fun resetGradleUserHomeIfNeeded() {
- if (originalGradleUserHome != this.gradleUserHome) {
- val normalizedOldGradleUserHome = originalGradleUserHome!!.normalize().toString()
- val canonicalOldGradleUserHome = FileUtil.toCanonicalPath(normalizedOldGradleUserHome)
- GradleSettings.getInstance(myProject).setServiceDirectoryPath(canonicalOldGradleUserHome)
- }
- }
-
- protected fun convertToLibraryName(fsRoot: VirtualFile): String = "Gradle: ${fsRoot.getName()}"
-
- private fun tearDownGradleVmOptions() {
- val settings = GradleSystemSettings.getInstance()
- settings.gradleVmOptions = ""
- }
-
- private fun requireWslJdkHome(distribution: WSLDistribution): String {
- var jdkPath = System.getProperty("wsl.jdk.path")
- if (jdkPath == null) {
- jdkPath = "/usr/lib/jvm/java-11-openjdk-amd64"
- }
- return distribution.getWindowsPath(jdkPath)
- }
-
- private fun findGradleDistributionInCache(gradleCachedFolderName: String): Path? {
- val gradleWrapperPath = StartParameter.DEFAULT_GRADLE_USER_HOME.toPath().resolve("wrapper/dists/$gradleCachedFolderName")
- if (Files.exists(gradleWrapperPath)) {
- return gradleWrapperPath
- }
- return null
+ private fun createJdkFromJavaHome(): Sdk {
+ val jdkHomeDir = LocalFileSystem.getInstance().refreshAndFindFileByNioFile(Path.of(gradleJdkHome!!))
+ val javaSdk = JavaSdk.getInstance()
+ val javaSdkType: SdkType = javaSdk ?: SimpleJavaSdkType.getInstance()
+ val jdk = SdkConfigurationUtil.setupSdk(arrayOfNulls(0), jdkHomeDir!!, javaSdkType, true, null, GRADLE_JDK_NAME)
+ assertNotNull("Cannot create JDK for " + this.gradleJdkHome, jdk)
+ return jdk!!
}
companion object {
diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/util/testWrapperUtil.kt b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/util/testWrapperUtil.kt
new file mode 100644
index 000000000000..01851a6b4532
--- /dev/null
+++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/util/testWrapperUtil.kt
@@ -0,0 +1,55 @@
+// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+package org.jetbrains.plugins.gradle.util
+
+import com.intellij.openapi.project.Project
+import com.intellij.platform.eel.provider.getEelDescriptor
+import com.intellij.util.io.delete
+import org.gradle.StartParameter
+import org.gradle.util.GradleVersion
+import org.gradle.wrapper.PathAssembler
+import org.jetbrains.plugins.gradle.service.execution.gradleUserHomeDir
+import java.nio.file.Files
+import java.nio.file.Path
+import java.util.zip.ZipInputStream
+import kotlin.io.path.ExperimentalPathApi
+import kotlin.io.path.exists
+
+@OptIn(ExperimentalPathApi::class)
+internal fun validateGradleJar(gradleJar: Path) {
+ if (!gradleJar.exists()) {
+ return
+ }
+ try {
+ Files.newInputStream(gradleJar).use {
+ ZipInputStream(it).use {
+ // sanity check
+ }
+ }
+ }
+ catch (e: Exception) {
+ e.printStackTrace()
+ println("Corrupted Gradle wrapper file will be removed: $gradleJar")
+ gradleJar.delete()
+ }
+}
+
+@Suppress("IO_FILE_USAGE")
+internal fun getGradleDistributionJarPath(projectPath: Path): Path {
+ val descriptor = projectPath.getEelDescriptor()
+ // the file used only as a path-representation; no IO operations are expected
+ return PathAssembler(gradleUserHomeDir(descriptor).toFile(), projectPath.toFile())
+ .getDistribution(GradleUtil.getWrapperConfiguration(projectPath))
+ .zipFile
+ .toPath()
+}
+
+internal fun getGradleDistributionRoot(project: Project, version: GradleVersion): Path {
+ val descriptor = project.getEelDescriptor()
+ return getGradleDistributionRoot(gradleUserHomeDir(descriptor), version)
+}
+
+internal fun getLocalGradleDistributionRoot(version: GradleVersion): Path =
+ getGradleDistributionRoot(StartParameter.DEFAULT_GRADLE_USER_HOME.toPath(), version)
+
+internal fun getGradleDistributionRoot(gradleUserHome: Path, version: GradleVersion): Path =
+ gradleUserHome.resolve("wrapper/dists/gradle-${version.version}-bin")
\ No newline at end of file
diff --git a/plugins/kotlin/gradle/gradle-java/tests.shared/test/org/jetbrains/kotlin/gradle/multiplatformTests/AbstractKotlinMppGradleImportingTest.kt b/plugins/kotlin/gradle/gradle-java/tests.shared/test/org/jetbrains/kotlin/gradle/multiplatformTests/AbstractKotlinMppGradleImportingTest.kt
index 450eaefc2bfc..c86bef49a378 100644
--- a/plugins/kotlin/gradle/gradle-java/tests.shared/test/org/jetbrains/kotlin/gradle/multiplatformTests/AbstractKotlinMppGradleImportingTest.kt
+++ b/plugins/kotlin/gradle/gradle-java/tests.shared/test/org/jetbrains/kotlin/gradle/multiplatformTests/AbstractKotlinMppGradleImportingTest.kt
@@ -122,8 +122,12 @@ abstract class AbstractKotlinMppGradleImportingTest : GradleImportingTestCase(),
@get:Rule
val pluginTargetVersionRule = PluginTargetVersionsRule()
- // The property below are needed solely for compatibility with PluginTargetVersionsRule;
- // please, use context.testPropertiesService if you need the version in your code
+ // Two properties below are needed solely for compatibility with PluginTargetVersionsRule;
+ // please, use context.testPropertiesService if you need those versions in your code
+ override var gradleVersion: String
+ get() = context.testProperties.gradleVersion.version
+ set(_) {}
+
final override val kotlinPluginVersion: KotlinToolingVersion
get() = context.testProperties.kotlinVersion
diff --git a/plugins/kotlin/gradle/gradle-java/tests.shared/test/org/jetbrains/kotlin/idea/codeInsight/gradle/MultiplePluginVersionGradleImportingTestCase.kt b/plugins/kotlin/gradle/gradle-java/tests.shared/test/org/jetbrains/kotlin/idea/codeInsight/gradle/MultiplePluginVersionGradleImportingTestCase.kt
index 86e188dc1918..d75e5649d8d6 100644
--- a/plugins/kotlin/gradle/gradle-java/tests.shared/test/org/jetbrains/kotlin/idea/codeInsight/gradle/MultiplePluginVersionGradleImportingTestCase.kt
+++ b/plugins/kotlin/gradle/gradle-java/tests.shared/test/org/jetbrains/kotlin/idea/codeInsight/gradle/MultiplePluginVersionGradleImportingTestCase.kt
@@ -58,6 +58,10 @@ abstract class MultiplePluginVersionGradleImportingTestCase : KotlinGradleImport
"Missing 'kotlinPluginVersionParam'"
}.version
+ override var gradleVersion: String
+ get() = super.gradleVersion
+ set(_) {}
+
override fun setUp() {
super.setUp()
setupSystemProperties()