IDEA-238573 added force using of project sdk for new gradle projects.

GitOrigin-RevId: e1c2a6ed96a3fea2d38e316a2bd30697fd91436b
This commit is contained in:
Sergei Vorobyov
2020-05-14 21:17:32 +00:00
committed by intellij-monorepo-bot
parent 09cf741a06
commit 87de06c007
8 changed files with 102 additions and 107 deletions
@@ -28,12 +28,9 @@ abstract class SdkTestCase : LightPlatformTestCase() {
super.setUp()
TestSdkGenerator.reset()
SdkType.EP_NAME.getPoint(null)
.registerExtension(TestSdkType, testRootDisposable)
SdkType.EP_NAME.getPoint(null)
.registerExtension(DependentTestSdkType, testRootDisposable)
SdkDownload.EP_NAME.getPoint(null)
.registerExtension(TestSdkDownloader, testRootDisposable)
SdkType.EP_NAME.point.registerExtension(TestSdkType, testRootDisposable)
SdkType.EP_NAME.point.registerExtension(DependentTestSdkType, testRootDisposable)
SdkDownload.EP_NAME.point.registerExtension(TestSdkDownloader, testRootDisposable)
}
fun createAndRegisterSdk(isProjectSdk: Boolean = false): TestSdk {
@@ -82,7 +79,7 @@ abstract class SdkTestCase : LightPlatformTestCase() {
sdks.forEach(::removeSdk)
}
private fun setProjectSdk(sdk: TestSdk) {
private fun setProjectSdk(sdk: Sdk?) {
invokeAndWaitIfNeeded {
runWriteAction {
val rootManager = ProjectRootManager.getInstance(project)
@@ -91,6 +88,26 @@ abstract class SdkTestCase : LightPlatformTestCase() {
}
}
fun withProjectSdk(sdk: TestSdk, action: () -> Unit) {
val projectSdk = projectSdk
setProjectSdk(sdk)
try {
action()
}
finally {
setProjectSdk(projectSdk)
}
}
fun withRegisteredSdk(sdk: TestSdk, isProjectSdk: Boolean, action: () -> Unit) {
withRegisteredSdks(sdk) {
when (isProjectSdk) {
true -> withProjectSdk(sdk, action)
else -> action()
}
}
}
fun withRegisteredSdks(vararg sdks: TestSdk, action: () -> Unit) {
registerSdks(*sdks)
try {
@@ -242,9 +242,8 @@ public abstract class AbstractGradleModuleBuilder extends AbstractExternalModule
}
private void setupAndLinkGradleProject(@NotNull Project project) {
Sdk projectSdk = ObjectUtils.chooseNotNull(getModuleJdk(), getNewProjectJdk(myWizardContext));
GradleProjectSettings projectSettings = getExternalProjectSettings();
setupGradleSettings(projectSettings, rootProjectPath, project, projectSdk);
setupGradleSettings(projectSettings, rootProjectPath, project);
getSystemSettings(project).linkProject(projectSettings);
GradleJvmValidationUtil.validateJavaHome(project, rootProjectPath, projectSettings.resolveGradleVersion());
}
@@ -241,16 +241,7 @@ abstract class GradleCreateProjectTestCase : GradleImportingTestCase() {
}
}
fun Project.use(save: Boolean = false, action: (Project) -> Unit) {
utilUse(save) {
try {
action(this)
}
finally {
GradleSetupProjectTest.removeGradleJvmSdk(this)
}
}
}
fun Project.use(save: Boolean = false, action: (Project) -> Unit) = utilUse(save, action)
companion object {
/**
@@ -17,8 +17,6 @@ import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil
import com.intellij.openapi.project.Project
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.vfs.VirtualFile
@@ -38,9 +36,8 @@ internal class GradleOpenProjectProvider : AbstractOpenProjectProvider() {
}
override fun linkAndRefreshProject(projectDirectory: String, project: Project) {
val projectSdk = ProjectRootManager.getInstance(project).projectSdk
val gradleProjectSettings = GradleProjectSettings()
setupGradleSettings(gradleProjectSettings, projectDirectory, project, projectSdk)
setupGradleSettings(gradleProjectSettings, projectDirectory, project)
attachGradleProjectAndRefresh(gradleProjectSettings, project)
validateJavaHome(project, projectDirectory, gradleProjectSettings.resolveGradleVersion())
}
@@ -68,9 +65,10 @@ internal class GradleOpenProjectProvider : AbstractOpenProjectProvider() {
.callback(createFinalImportCallback(project, externalProjectPath)))
}
fun setupGradleSettings(settings: GradleProjectSettings, projectDirectory: String, project: Project, projectSdk: Sdk? = null) {
fun setupGradleSettings(settings: GradleProjectSettings, projectDirectory: String, project: Project) {
GradleSettings.getInstance(project).setupGradleSettings()
settings.setupGradleProjectSettings(projectDirectory, project, projectSdk)
settings.setupGradleProjectSettings(projectDirectory)
setupGradleJvm(project, settings, projectDirectory)
}
private fun GradleSettings.setupGradleSettings() {
@@ -80,13 +78,12 @@ internal class GradleOpenProjectProvider : AbstractOpenProjectProvider() {
storeProjectFilesExternally = true
}
private fun GradleProjectSettings.setupGradleProjectSettings(projectDirectory: String, project: Project, projectSdk: Sdk? = null) {
private fun GradleProjectSettings.setupGradleProjectSettings(projectDirectory: String) {
externalProjectPath = projectDirectory
isUseQualifiedModuleNames = true
distributionType = GradleEnvironment.Headless.GRADLE_DISTRIBUTION_TYPE?.let(DistributionType::valueOf)
?: DistributionType.DEFAULT_WRAPPED
gradleHome = GradleEnvironment.Headless.GRADLE_HOME ?: suggestGradleHome()
setupGradleJvm(project, projectSdk, this, projectDirectory, resolveGradleVersion())
}
private fun suggestGradleHome(): String? {
@@ -5,7 +5,6 @@ package org.jetbrains.plugins.gradle.service.project.open
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
import com.intellij.openapi.externalSystem.util.ExternalSystemBundle
import com.intellij.openapi.project.Project
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.ui.Messages
import com.intellij.openapi.ui.ValidationInfo
import com.intellij.openapi.util.io.FileUtil
@@ -45,8 +44,8 @@ fun linkAndRefreshGradleProject(projectFilePath: String, project: Project) {
GradleOpenProjectProvider().linkToExistingProject(projectFile, project)
}
fun setupGradleSettings(settings: GradleProjectSettings, projectDirectory: String, project: Project, projectSdk: Sdk? = null) =
GradleOpenProjectProvider().setupGradleSettings(settings, projectDirectory, project, projectSdk)
fun setupGradleSettings(settings: GradleProjectSettings, projectDirectory: String, project: Project) =
GradleOpenProjectProvider().setupGradleSettings(settings, projectDirectory, project)
private fun validateGradleProject(projectFilePath: String, project: Project): ValidationInfo? {
val systemSettings = ExternalSystemApiUtil.getSettings(project, GradleConstants.SYSTEM_ID)
@@ -6,70 +6,65 @@ package org.jetbrains.plugins.gradle.util
import com.intellij.openapi.application.runReadAction
import com.intellij.openapi.externalSystem.service.execution.ExternalSystemJdkUtil
import com.intellij.openapi.externalSystem.service.execution.nonblockingResolveSdkBySdkName
import com.intellij.openapi.project.Project
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.SdkLookupBuilderEx
import com.intellij.openapi.roots.ui.configuration.SdkLookupProvider
import com.intellij.openapi.roots.ui.configuration.SdkLookupProvider.Id
import org.gradle.util.GradleVersion
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.plugins.gradle.settings.GradleProjectSettings
import org.jetbrains.plugins.gradle.settings.GradleSettings
import org.jetbrains.plugins.gradle.util.JavaHomeValidationStatus.Success
private data class GradleJvmProviderId(val projectSettings: GradleProjectSettings) : SdkLookupProvider.Id
private data class GradleJvmProviderId(val projectSettings: GradleProjectSettings) : Id
fun getGradleJvmLookupProvider(project: Project, projectSettings: GradleProjectSettings) =
SdkLookupProvider.getInstance(project, GradleJvmProviderId(projectSettings))
fun setupGradleJvm(
project: Project,
projectSdk: Sdk?,
projectSettings: GradleProjectSettings,
externalProjectPath: String,
gradleVersion: GradleVersion
) {
with(GradleJvmResolutionContext(project, projectSdk, externalProjectPath, gradleVersion)) {
projectSettings.gradleJvm = null
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()
if (projectSettings.gradleJvm != null) return
when {
canUseProjectSdk() -> projectSettings.gradleJvm = ExternalSystemJdkUtil.USE_PROJECT_JDK
canUseGradleJavaHomeJdk() -> projectSettings.gradleJvm = USE_GRADLE_JAVA_HOME
canUseJavaHomeJdk() -> projectSettings.gradleJvm = ExternalSystemJdkUtil.USE_JAVA_HOME
else -> SdkLookupBuilderEx<String> {
getGradleJvmLookupProvider(project, projectSettings)
.newLookupBuilder()
.testSuggestedSdksFirst(getGradleJdks())
.testSuggestedSdkFirst(ExternalSystemJdkUtil.USE_PROJECT_JDK) { getProjectJdk() }
.withVersionFilter { isSupported(gradleVersion, it) }
.withSdkType(ExternalSystemJdkUtil.getJavaSdkType())
.withSdkHomeFilter { ExternalSystemJdkUtil.isValidJdk(it) }
.onSdkNameResolved { id, sdk ->
/* We have two types of sdk resolving:
* 1. Download sdk manually
* a. by download action from SdkComboBox
* b. by sdk downloader
* c. by action that detects incorrect project sdk
* 2. Lookup sdk (search in fs, download and etc)
* a. search in fs, search in sdk table and etc
* b. download
*
* All download actions generates fake (invalid) sdk and puts it to jdk table.
* This code allows to avoid some irregular conflicts
* For example: strange duplications in SdkComboBox or unexpected modifications of gradleJvm
*/
val fakeSdk = sdk?.let(::findRegisteredSdk)
if (fakeSdk != null && projectSettings.gradleJvm == null) {
projectSettings.gradleJvm = id ?: fakeSdk.name
}
else -> getGradleJvmLookupProvider(project, projectSettings)
.newLookupBuilder()
.withVersionFilter { isSupported(gradleVersion, it) }
.withSdkType(ExternalSystemJdkUtil.getJavaSdkType())
.withSdkHomeFilter { ExternalSystemJdkUtil.isValidJdk(it) }
.onSdkNameResolved { sdk ->
/* We have two types of sdk resolving:
* 1. Download sdk manually
* a. by download action from SdkComboBox
* b. by sdk downloader
* c. by action that detects incorrect project sdk
* 2. Lookup sdk (search in fs, download and etc)
* a. search in fs, search in sdk table and etc
* b. download
*
* All download actions generates fake (invalid) sdk and puts it to jdk table.
* This code allows to avoid some irregular conflicts
* For example: strange duplications in SdkComboBox or unexpected modifications of gradleJvm
*/
val fakeSdk = sdk?.let(::findRegisteredSdk)
if (fakeSdk != null && projectSettings.gradleJvm == null) {
projectSettings.gradleJvm = fakeSdk.name
}
.onSdkResolved { id, sdk ->
if (projectSettings.gradleJvm == null) {
projectSettings.gradleJvm = id ?: sdk?.name
}
}
.onSdkResolved { sdk ->
if (projectSettings.gradleJvm == null) {
projectSettings.gradleJvm = sdk?.name
}
.executeLookup()
}
}
.executeLookup()
}
}
}
@@ -79,27 +74,19 @@ fun updateGradleJvm(project: Project, externalProjectPath: String) {
val projectSettings = settings.getLinkedProjectSettings(externalProjectPath) ?: return
val gradleJvm = projectSettings.gradleJvm ?: return
val gradleVersion = projectSettings.resolveGradleVersion()
with(GradleJvmResolutionContext(project, null, externalProjectPath, gradleVersion)) {
with(GradleJvmResolutionContext(project, externalProjectPath, gradleVersion)) {
val projectSdk = projectSdk ?: return
if (projectSdk.name != gradleJvm) return
if (!isValidAndSupported(projectSdk)) return
projectSettings.gradleJvm = ExternalSystemJdkUtil.USE_PROJECT_JDK
}
}
private class GradleJvmResolutionContext(
val project: Project,
projectSdk: Sdk?,
val externalProjectPath: String,
val gradleVersion: GradleVersion
) {
val projectSdk: Sdk? by lazy { projectSdk ?: ProjectRootManager.getInstance(project).projectSdk }
}
private fun GradleJvmResolutionContext.isValidAndSupported(sdk: Sdk): Boolean {
if (!ExternalSystemJdkUtil.isValidJdk(sdk)) return false
val versionString = sdk.versionString ?: return false
return isSupported(gradleVersion, versionString)
val projectSdk: Sdk? by lazy { ProjectRootManager.getInstance(project).projectSdk }
}
private fun GradleJvmResolutionContext.canUseGradleJavaHomeJdk(): Boolean {
@@ -115,20 +102,17 @@ private fun GradleJvmResolutionContext.canUseJavaHomeJdk(): Boolean {
return validationStatus is Success
}
private fun GradleJvmResolutionContext.getGradleJdks(): Sequence<Sdk?> = sequence {
private fun GradleJvmResolutionContext.findGradleJvm(): String? {
val settings = GradleSettings.getInstance(project)
for (projectSettings in settings.linkedProjectsSettings) {
val provider = getGradleJvmLookupProvider(project, projectSettings)
val gradleJvm = projectSettings.gradleJvm
yield(provider.nonblockingResolveSdkBySdkName(gradleJvm))
}
return settings.linkedProjectsSettings.asSequence()
.mapNotNull { it.gradleJvm }
.firstOrNull()
}
private fun GradleJvmResolutionContext.getProjectJdk(): Sdk? {
val projectSdk = projectSdk ?: return null
private fun GradleJvmResolutionContext.canUseProjectSdk(): Boolean {
val projectSdk = projectSdk ?: return false
val resolvedProjectSdk = ExternalSystemJdkUtil.resolveDependentJdk(projectSdk)
if (!isValidAndSupported(resolvedProjectSdk)) return null
return resolvedProjectSdk
return ExternalSystemJdkUtil.isValidJdk(resolvedProjectSdk)
}
private fun findRegisteredSdk(sdk: Sdk): Sdk? = runReadAction {
@@ -17,7 +17,9 @@ class GradleJdkResolutionTest : GradleJdkResolutionTestCase() {
assertGradleJvmSuggestion(expected = earliestSdk)
}
}
assertGradleJvmSuggestion(expected = USE_PROJECT_JDK, projectSdk = latestSdk)
withRegisteredSdk(latestSdk, isProjectSdk = true) {
assertGradleJvmSuggestion(expected = USE_PROJECT_JDK)
}
environment.withVariables(JAVA_HOME to latestSdk.homePath) {
assertGradleJvmSuggestion(expected = USE_JAVA_HOME)
}
@@ -45,15 +47,21 @@ class GradleJdkResolutionTest : GradleJdkResolutionTestCase() {
assertGradleJvmSuggestion(expected = latestSdk)
}
withGradleLinkedProject(java = unsupportedSdk) {
assertGradleJvmSuggestion(expected = latestSdk)
assertGradleJvmSuggestion(expected = unsupportedSdk)
}
}
@Test
fun `test gradle jvm resolution (project sdk)`() {
assertGradleJvmSuggestion(expected = USE_PROJECT_JDK, projectSdk = earliestSdk)
assertGradleJvmSuggestion(expected = USE_PROJECT_JDK, projectSdk = latestSdk)
assertGradleJvmSuggestion(expected = latestSdk, projectSdk = unsupportedSdk, expectsSdkRegistration = true)
withRegisteredSdk(earliestSdk, isProjectSdk = true) {
assertGradleJvmSuggestion(expected = USE_PROJECT_JDK)
}
withRegisteredSdk(latestSdk, isProjectSdk = true) {
assertGradleJvmSuggestion(expected = USE_PROJECT_JDK)
}
withRegisteredSdk(unsupportedSdk, isProjectSdk = true) {
assertGradleJvmSuggestion(expected = USE_PROJECT_JDK)
}
}
@Test
@@ -46,29 +46,29 @@ abstract class GradleJdkResolutionTestCase : ExternalSystemJdkUtilTestCase() {
environment.variables(GradleConstants.SYSTEM_DIRECTORY_PATH_KEY to null)
}
fun assertGradleJvmSuggestion(expected: TestSdk, projectSdk: TestSdk? = null, expectsSdkRegistration: Boolean = false) {
assertGradleJvmSuggestion({ expected }, projectSdk, expectsSdkRegistration)
fun assertGradleJvmSuggestion(expected: TestSdk, expectsSdkRegistration: Boolean = false) {
assertGradleJvmSuggestion({ expected }, expectsSdkRegistration)
}
fun assertGradleJvmSuggestion(expected: () -> TestSdk, projectSdk: TestSdk? = null, expectsSdkRegistration: Boolean = false) {
fun assertGradleJvmSuggestion(expected: () -> TestSdk, expectsSdkRegistration: Boolean = false) {
assertNewlyRegisteredSdks({ if (expectsSdkRegistration) expected() else null }) {
val gradleJvm = suggestGradleJvm(project, projectSdk, externalProjectPath, gradleVersion)
val gradleJvm = suggestGradleJvm(project, externalProjectPath, gradleVersion)
val gradleJdk = SdkLookupProviderImpl().nonblockingResolveSdkBySdkName(gradleJvm)
requireNotNull(gradleJdk) { "expected: ${expected()}" }
assertSdk(expected(), gradleJdk)
}
}
fun assertGradleJvmSuggestion(expected: String, projectSdk: TestSdk? = null) {
fun assertGradleJvmSuggestion(expected: String) {
assertUnexpectedSdksRegistration {
val gradleJvm = suggestGradleJvm(project, projectSdk, externalProjectPath, gradleVersion)
val gradleJvm = suggestGradleJvm(project, externalProjectPath, gradleVersion)
assertEquals(expected, gradleJvm)
}
}
private fun suggestGradleJvm(project: Project, projectSdk: Sdk?, externalProjectPath: String, gradleVersion: GradleVersion): String? {
private fun suggestGradleJvm(project: Project, externalProjectPath: String, gradleVersion: GradleVersion): String? {
val projectSettings = GradleProjectSettings()
setupGradleJvm(project, projectSdk, projectSettings, externalProjectPath, gradleVersion)
setupGradleJvm(project, projectSettings, externalProjectPath, gradleVersion)
val provider = getGradleJvmLookupProvider(project, projectSettings)
provider.waitForLookup()
return projectSettings.gradleJvm