IDEA-240215 added choosing of gradle wrapper version by project JDK

GitOrigin-RevId: 002b98763e2a86b369c32f96b040dfa7a272bf5d
This commit is contained in:
Sergei Vorobyov
2020-05-14 21:17:32 +00:00
committed by intellij-monorepo-bot
parent 87de06c007
commit 7e46431d30
7 changed files with 222 additions and 36 deletions
@@ -57,9 +57,11 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.frameworkSupport.BuildScriptDataBuilder;
import org.jetbrains.plugins.gradle.frameworkSupport.KotlinBuildScriptDataBuilder;
import org.jetbrains.plugins.gradle.model.data.GradleSourceSetData;
import org.jetbrains.plugins.gradle.service.execution.GradleExecutionUtil;
import org.jetbrains.plugins.gradle.settings.DistributionType;
import org.jetbrains.plugins.gradle.settings.GradleProjectSettings;
import org.jetbrains.plugins.gradle.util.GradleConstants;
import org.jetbrains.plugins.gradle.util.GradleJvmResolutionUtil;
import org.jetbrains.plugins.gradle.util.GradleJvmValidationUtil;
import java.io.File;
@@ -207,6 +209,8 @@ public abstract class AbstractGradleModuleBuilder extends AbstractExternalModule
VirtualFile buildScriptFile = createAndConfigureBuildScriptFile(module);
FileDocumentManager.getInstance().saveAllDocuments();
// it will be set later in any case, but save is called immediately after project creation, so, to ensure that it will be properly saved as external system module
ExternalSystemModulePropertyManager modulePropertyManager = ExternalSystemModulePropertyManager.getInstance(module);
modulePropertyManager.setExternalId(GradleConstants.SYSTEM_ID);
@@ -214,9 +218,12 @@ public abstract class AbstractGradleModuleBuilder extends AbstractExternalModule
modulePropertyManager.setRootProjectPath(rootProjectPath);
modulePropertyManager.setLinkedProjectPath(rootProjectPath);
final Project project = module.getProject();
FileDocumentManager.getInstance().saveAllDocuments();
if (myParentProject == null) setupAndLinkGradleProject(project);
Project project = module.getProject();
GradleVersion gradleVersion = suggestGradleVersion(project);
if (myParentProject == null) {
setupAndLinkGradleProject(project, gradleVersion);
}
if (myWizardContext.isCreatingNewProject()) {
project.putUserData(ExternalSystemDataKeys.NEWLY_CREATED_PROJECT, Boolean.TRUE);
// Needed to ignore postponed project refresh
@@ -227,25 +234,49 @@ public abstract class AbstractGradleModuleBuilder extends AbstractExternalModule
ApplicationManager.getApplication().invokeLater(() -> {
if (myWizardContext.isCreatingNewProject()) {
// update external projects data to be able to add child modules before the initial import finish
ImportSpecBuilder previewSpec = new ImportSpecBuilder(project, GradleConstants.SYSTEM_ID);
previewSpec.usePreviewMode();
previewSpec.use(MODAL_SYNC);
previewSpec.callback(new ConfigureGradleModuleCallback(previewSpec));
ExternalSystemUtil.refreshProject(rootProjectPath, previewSpec);
loadPreviewProject(project);
}
ImportSpecBuilder importSpec = new ImportSpecBuilder(project, GradleConstants.SYSTEM_ID);
importSpec.createDirectoriesForEmptyContentRoots();
importSpec.callback(new ConfigureGradleModuleCallback(importSpec));
ExternalSystemUtil.refreshProject(rootProjectPath, importSpec);
openBuildScriptFile(project, buildScriptFile);
if (myParentProject == null) {
createWrapper(project, gradleVersion, () -> {
reloadProject(project);
});
}
else {
reloadProject(project);
}
}, ModalityState.NON_MODAL, project.getDisposed());
}
private void setupAndLinkGradleProject(@NotNull Project project) {
private void setupAndLinkGradleProject(@NotNull Project project, @NotNull GradleVersion gradleVersion) {
GradleProjectSettings projectSettings = getExternalProjectSettings();
setupGradleSettings(projectSettings, rootProjectPath, project);
setupGradleSettings(project, projectSettings, rootProjectPath, gradleVersion);
getSystemSettings(project).linkProject(projectSettings);
GradleJvmValidationUtil.validateJavaHome(project, rootProjectPath, projectSettings.resolveGradleVersion());
GradleJvmValidationUtil.validateJavaHome(project, rootProjectPath, gradleVersion);
}
private void loadPreviewProject(@NotNull Project project) {
ImportSpecBuilder previewSpec = new ImportSpecBuilder(project, GradleConstants.SYSTEM_ID);
previewSpec.usePreviewMode();
previewSpec.use(MODAL_SYNC);
previewSpec.callback(new ConfigureGradleModuleCallback(previewSpec));
ExternalSystemUtil.refreshProject(rootProjectPath, previewSpec);
}
private void reloadProject(@NotNull Project project) {
ImportSpecBuilder importSpec = new ImportSpecBuilder(project, GradleConstants.SYSTEM_ID);
importSpec.createDirectoriesForEmptyContentRoots();
importSpec.callback(new ConfigureGradleModuleCallback(importSpec));
ExternalSystemUtil.refreshProject(rootProjectPath, importSpec);
}
private void createWrapper(@NotNull Project project, @NotNull GradleVersion gradleVersion, @NotNull Runnable callback) {
GradleExecutionUtil.ensureInstalledWrapper(project, rootProjectPath, gradleVersion, callback);
}
private static @NotNull GradleVersion suggestGradleVersion(@NotNull Project project) {
GradleVersion gradleVersion = GradleJvmResolutionUtil.suggestGradleVersion(project);
return gradleVersion == null ? GradleVersion.current() : gradleVersion;
}
private static AbstractExternalSystemSettings<?, GradleProjectSettings, ?> getSystemSettings(@NotNull Project project) {
@@ -162,3 +162,5 @@ gradle.tasks.annotations.title=Resolving known external annotations
gradle.tasks.annotations.looking.for=Looking for annotations for {0}
compiler.build.messages.gradle.configuration.not.found=Unable to make ''{0}''.\nRelated gradle configuration was not found. "Please, re-import the Gradle project and try again.
gradle.project.generation.wrapper.progress.title=Generating of Gradle Wrapper
@@ -299,6 +299,15 @@ public class GradleExecutionHelper {
@NotNull GradleExecutionSettings settings,
@NotNull ExternalSystemTaskNotificationListener listener,
@NotNull CancellationToken cancellationToken) {
ensureInstalledWrapper(id, projectPath, settings, GradleVersion.current(), listener, cancellationToken);
}
public void ensureInstalledWrapper(@NotNull ExternalSystemTaskId id,
@NotNull String projectPath,
@NotNull GradleExecutionSettings settings,
@NotNull GradleVersion gradleVersion,
@NotNull ExternalSystemTaskNotificationListener listener,
@NotNull CancellationToken cancellationToken) {
if (!settings.getDistributionType().isWrapped()) return;
@@ -329,6 +338,7 @@ public class GradleExecutionHelper {
" wrapper.jarFile = new File('" + StringUtil.escapeBackSlashes(jarFile.getCanonicalPath()) + "')",
" wrapper.scriptFile = new File('" + StringUtil.escapeBackSlashes(scriptFile.getCanonicalPath()) + "')",
" }",
" wrapper.gradleVersion = '" + gradleVersion.getVersion() + "'",
" wrapper.doLast {",
" new File('" + StringUtil.escapeBackSlashes(pathToProperties.getCanonicalPath()) + "').write wrapper.propertiesFile.getCanonicalPath()",
" }",
@@ -0,0 +1,114 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
@file:JvmName("GradleExecutionUtil")
package org.jetbrains.plugins.gradle.service.execution
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListener
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListenerAdapter
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType.EXECUTE_TASK
import com.intellij.openapi.externalSystem.service.execution.ExternalSystemJdkProvider
import com.intellij.openapi.externalSystem.service.internal.AbstractExternalSystemTask
import com.intellij.openapi.externalSystem.service.remote.ExternalSystemProgressNotificationManagerImpl
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.progress.Task
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.io.FileUtil
import org.gradle.tooling.GradleConnector
import org.gradle.util.GradleVersion
import org.jetbrains.plugins.gradle.service.GradleInstallationManager
import org.jetbrains.plugins.gradle.settings.DistributionType
import org.jetbrains.plugins.gradle.settings.GradleExecutionSettings
import org.jetbrains.plugins.gradle.settings.GradleSettings
import org.jetbrains.plugins.gradle.util.GradleBundle
import org.jetbrains.plugins.gradle.util.GradleConstants.SYSTEM_ID
import org.jetbrains.plugins.gradle.util.GradleUtil
fun ensureInstalledWrapper(project: Project, externalProjectPath: String, gradleVersion: GradleVersion, callback: Runnable) {
val ensureInstalledWrapperTask = EnsureInstalledWrapperExecutionTask(project, externalProjectPath, gradleVersion)
val title = GradleBundle.message("gradle.project.generation.wrapper.progress.title")
val task = object : Task.Backgroundable(project, title, true) {
override fun run(indicator: ProgressIndicator) {
val listener = object : ExternalSystemTaskNotificationListenerAdapter() {
override fun onEnd(id: ExternalSystemTaskId) = callback.run()
}
ensureInstalledWrapperTask.execute(indicator, listener)
}
}
task.queue()
}
private class EnsureInstalledWrapperExecutionTask(
project: Project,
externalProjectPath: String,
private val gradleVersion: GradleVersion
) : AbstractExternalSystemTask(SYSTEM_ID, EXECUTE_TASK, project, externalProjectPath) {
private val progressNotificationManager = ExternalSystemProgressNotificationManagerImpl.getInstanceImpl()
private val newCancellationTokenSource = GradleConnector.newCancellationTokenSource()
private fun createExecutionSettings(): GradleExecutionSettings {
val settings = GradleSettings.getInstance(ideProject)
val executionSettings = GradleExecutionSettings(
getGradleHome(),
settings.serviceDirectoryPath,
getDistributionType(),
settings.gradleVmOptions,
settings.isOfflineWork
)
val jdkProvider = ExternalSystemJdkProvider.getInstance()
executionSettings.javaHome = jdkProvider.internalJdk.homePath
return executionSettings
}
private fun getGradleHome(): String? {
val installationManager = GradleInstallationManager.getInstance()
val gradleHome = installationManager.getGradleHome(ideProject, externalProjectPath)
return FileUtil.toCanonicalPath(gradleHome?.path)
}
private fun getDistributionType(): DistributionType {
val settings = GradleSettings.getInstance(ideProject)
val projectSettings = settings.getLinkedProjectSettings(externalProjectPath)
return when {
projectSettings != null -> projectSettings.distributionType ?: DistributionType.LOCAL
GradleUtil.isGradleDefaultWrapperFilesExist(externalProjectPath) -> DistributionType.DEFAULT_WRAPPED
else -> DistributionType.BUNDLED
}
}
private fun ensureInstalledWrapper(listener: ExternalSystemTaskNotificationListener) {
GradleExecutionHelper().ensureInstalledWrapper(
id,
externalProjectPath,
createExecutionSettings(),
gradleVersion,
listener,
newCancellationTokenSource.token()
)
}
override fun doExecute() {
val progressNotificationListener = wrapWithListener(progressNotificationManager)
try {
progressNotificationManager.onStart(id, externalProjectPath)
ensureInstalledWrapper(progressNotificationListener)
progressNotificationManager.onSuccess(id)
}
catch (e: Exception) {
progressNotificationManager.onFailure(id, e)
throw e
}
finally {
progressNotificationManager.onEnd(id)
}
}
override fun doCancel(): Boolean {
progressNotificationManager.beforeCancel(id)
newCancellationTokenSource.cancel()
progressNotificationManager.onCancel(id)
return true
}
}
@@ -21,6 +21,7 @@ import com.intellij.openapi.util.Disposer
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.util.text.nullize
import org.gradle.util.GradleVersion
import org.jetbrains.plugins.gradle.service.GradleInstallationManager
import org.jetbrains.plugins.gradle.settings.DistributionType
import org.jetbrains.plugins.gradle.settings.GradleProjectSettings
@@ -37,9 +38,10 @@ internal class GradleOpenProjectProvider : AbstractOpenProjectProvider() {
override fun linkAndRefreshProject(projectDirectory: String, project: Project) {
val gradleProjectSettings = GradleProjectSettings()
setupGradleSettings(gradleProjectSettings, projectDirectory, project)
val gradleVersion = gradleProjectSettings.resolveGradleVersion()
setupGradleSettings(project, gradleProjectSettings, projectDirectory, gradleVersion)
attachGradleProjectAndRefresh(gradleProjectSettings, project)
validateJavaHome(project, projectDirectory, gradleProjectSettings.resolveGradleVersion())
validateJavaHome(project, projectDirectory, gradleVersion)
}
override fun openProject(projectFile: VirtualFile, projectToClose: Project?, forceOpenInNewFrame: Boolean): Project? {
@@ -65,10 +67,10 @@ internal class GradleOpenProjectProvider : AbstractOpenProjectProvider() {
.callback(createFinalImportCallback(project, externalProjectPath)))
}
fun setupGradleSettings(settings: GradleProjectSettings, projectDirectory: String, project: Project) {
fun setupGradleSettings(project: Project, settings: GradleProjectSettings, projectDirectory: String, gradleVersion: GradleVersion) {
GradleSettings.getInstance(project).setupGradleSettings()
settings.setupGradleProjectSettings(projectDirectory)
setupGradleJvm(project, settings, projectDirectory)
setupGradleJvm(project, settings, projectDirectory, gradleVersion)
}
private fun GradleSettings.setupGradleSettings() {
@@ -10,6 +10,7 @@ import com.intellij.openapi.ui.ValidationInfo
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.openapi.vfs.VirtualFile
import org.gradle.util.GradleVersion
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.plugins.gradle.settings.GradleProjectSettings
import org.jetbrains.plugins.gradle.util.GradleConstants
@@ -44,8 +45,8 @@ fun linkAndRefreshGradleProject(projectFilePath: String, project: Project) {
GradleOpenProjectProvider().linkToExistingProject(projectFile, project)
}
fun setupGradleSettings(settings: GradleProjectSettings, projectDirectory: String, project: Project) =
GradleOpenProjectProvider().setupGradleSettings(settings, projectDirectory, project)
fun setupGradleSettings(project: Project, settings: GradleProjectSettings, projectDirectory: String, gradleVersion: GradleVersion) =
GradleOpenProjectProvider().setupGradleSettings(project, settings, projectDirectory, gradleVersion)
private fun validateGradleProject(projectFilePath: String, project: Project): ValidationInfo? {
val systemSettings = ExternalSystemApiUtil.getSettings(project, GradleConstants.SYSTEM_ID)
@@ -5,13 +5,16 @@
package org.jetbrains.plugins.gradle.util
import com.intellij.openapi.application.runReadAction
import com.intellij.openapi.externalSystem.service.execution.ExternalSystemJdkProvider
import com.intellij.openapi.externalSystem.service.execution.ExternalSystemJdkUtil
import com.intellij.openapi.project.Project
import com.intellij.openapi.projectRoots.JdkUtil
import com.intellij.openapi.projectRoots.ProjectJdkTable
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.openapi.roots.ui.configuration.SdkLookupProvider
import com.intellij.openapi.roots.ui.configuration.SdkLookupProvider.Id
import com.intellij.util.lang.JavaVersion
import org.gradle.util.GradleVersion
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.plugins.gradle.settings.GradleProjectSettings
@@ -23,10 +26,6 @@ private data class GradleJvmProviderId(val projectSettings: GradleProjectSetting
fun getGradleJvmLookupProvider(project: Project, projectSettings: GradleProjectSettings) =
SdkLookupProvider.getInstance(project, GradleJvmProviderId(projectSettings))
fun setupGradleJvm(project: Project, projectSettings: GradleProjectSettings, externalProjectPath: String) {
setupGradleJvm(project, projectSettings, externalProjectPath, projectSettings.resolveGradleVersion())
}
fun setupGradleJvm(project: Project, projectSettings: GradleProjectSettings, externalProjectPath: String, gradleVersion: GradleVersion) {
with(GradleJvmResolutionContext(project, externalProjectPath, gradleVersion)) {
projectSettings.gradleJvm = findGradleJvm()
@@ -73,21 +72,42 @@ fun updateGradleJvm(project: Project, externalProjectPath: String) {
val settings = GradleSettings.getInstance(project)
val projectSettings = settings.getLinkedProjectSettings(externalProjectPath) ?: return
val gradleJvm = projectSettings.gradleJvm ?: return
val gradleVersion = projectSettings.resolveGradleVersion()
with(GradleJvmResolutionContext(project, externalProjectPath, gradleVersion)) {
val projectSdk = projectSdk ?: return
if (projectSdk.name != gradleJvm) return
projectSettings.gradleJvm = ExternalSystemJdkUtil.USE_PROJECT_JDK
val projectRootManager = ProjectRootManager.getInstance(project)
val projectSdk = projectRootManager.projectSdk ?: return
if (projectSdk.name != gradleJvm) return
projectSettings.gradleJvm = ExternalSystemJdkUtil.USE_PROJECT_JDK
}
fun suggestGradleVersion(project: Project): GradleVersion? {
val gradleVersion = findGradleVersion(project)
if (gradleVersion != null) return gradleVersion
val projectJdk = resolveProjectJdk(project) ?: return null
if (!ExternalSystemJdkUtil.isValidJdk(projectJdk)) return null
val javaVersion = JavaVersion.tryParse(projectJdk.versionString) ?: return null
return suggestGradleVersion(javaVersion)
}
private fun suggestGradleVersion(javaVersion: JavaVersion): GradleVersion? {
return when (javaVersion.feature) {
in 8..14 -> GradleVersion.version("6.3")
7 -> GradleVersion.version("4.1")
6 -> GradleVersion.version("3.0")
else -> null
}
}
private fun findGradleVersion(project: Project): GradleVersion? {
val settings = GradleSettings.getInstance(project)
return settings.linkedProjectsSettings.asSequence()
.mapNotNull { it.resolveGradleVersion() }
.firstOrNull()
}
private class GradleJvmResolutionContext(
val project: Project,
val externalProjectPath: String,
val gradleVersion: GradleVersion
) {
val projectSdk: Sdk? by lazy { ProjectRootManager.getInstance(project).projectSdk }
}
)
private fun GradleJvmResolutionContext.canUseGradleJavaHomeJdk(): Boolean {
val properties = getGradleProperties(externalProjectPath)
@@ -110,11 +130,17 @@ private fun GradleJvmResolutionContext.findGradleJvm(): String? {
}
private fun GradleJvmResolutionContext.canUseProjectSdk(): Boolean {
val projectSdk = projectSdk ?: return false
val resolvedProjectSdk = ExternalSystemJdkUtil.resolveDependentJdk(projectSdk)
return ExternalSystemJdkUtil.isValidJdk(resolvedProjectSdk)
val projectJdk = resolveProjectJdk(project) ?: return false
return ExternalSystemJdkUtil.isValidJdk(projectJdk)
}
private fun resolveProjectJdk(project: Project): Sdk? {
val projectRootManager = ProjectRootManager.getInstance(project)
val projectSdk = projectRootManager.projectSdk ?: return null
return ExternalSystemJdkUtil.resolveDependentJdk(projectSdk)
}
private fun findRegisteredSdk(sdk: Sdk): Sdk? = runReadAction {
val projectJdkTable = ProjectJdkTable.getInstance()
projectJdkTable.findJdk(sdk.name, sdk.sdkType.name)