Extract virtual env creating logic to util class

IDEA-CR-69125

GitOrigin-RevId: 9b7a3f1a9fd4589eb872d24ecde8203e3cf66f78
This commit is contained in:
Konstantin Hudyakov
2020-12-15 12:27:48 +00:00
committed by intellij-monorepo-bot
parent 5c6e87220d
commit 18fb6cb193
3 changed files with 80 additions and 46 deletions
@@ -1,27 +1,22 @@
// Copyright 2000-2020 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.
package com.jetbrains.python.sdk.add
import com.intellij.execution.ExecutionException
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory
import com.intellij.openapi.module.Module
import com.intellij.openapi.module.ModuleUtil
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.progress.Task
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.ProjectManager
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.ui.TextFieldWithBrowseButton
import com.intellij.openapi.ui.ValidationInfo
import com.intellij.openapi.util.UserDataHolder
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.vfs.StandardFileSystems
import com.intellij.ui.DocumentAdapter
import com.intellij.ui.components.JBCheckBox
import com.intellij.util.ui.FormBuilder
import com.jetbrains.python.PyBundle
import com.jetbrains.python.PySdkBundle
import com.jetbrains.python.packaging.PyPackageManager
import com.jetbrains.python.sdk.*
import com.jetbrains.python.sdk.PySdkSettings
import com.jetbrains.python.sdk.basePath
import com.jetbrains.python.sdk.configuration.PyProjectVirtualEnvConfiguration
import icons.PythonIcons
import org.jetbrains.annotations.SystemIndependent
import java.awt.BorderLayout
@@ -75,26 +70,9 @@ class PyAddNewVirtualEnvPanel(private val project: Project?,
validateSdkComboBox(baseSdkField, this))
override fun getOrCreateSdk(): Sdk? {
val root = pathField.text
val baseSdk = installSdkIfNeeded(baseSdkField.selectedSdk, module, existingSdks, context)
if (baseSdk == null) return null
val task = object : Task.WithResult<String, ExecutionException>(project, PySdkBundle.message("python.creating.venv.title"), false) {
override fun compute(indicator: ProgressIndicator): String {
indicator.isIndeterminate = true
val packageManager = PyPackageManager.getInstance(baseSdk)
return packageManager.createVirtualEnv(root, inheritSitePackagesField.isSelected)
}
}
val shared = makeSharedField.isSelected
val associatedPath = if (!shared) projectBasePath else null
val sdk = createSdkByGenerateTask(task, existingSdks, baseSdk, associatedPath, null) ?: return null
if (!shared) {
sdk.associateWithModule(module, newProjectPath)
}
moduleToExcludeSdkFrom(root, project)?.excludeInnerVirtualEnv(sdk)
PySdkSettings.instance.onVirtualEnvCreated(baseSdk, FileUtil.toSystemIndependentName(root), projectBasePath)
return sdk
return PyProjectVirtualEnvConfiguration.createVirtualEnvSynchronously(baseSdkField.selectedSdk, existingSdks, pathField.text,
newProjectPath, project, module, context,
inheritSitePackagesField.isSelected, makeSharedField.isSelected)
}
override fun addChangeListener(listener: Runnable) {
@@ -106,16 +84,6 @@ class PyAddNewVirtualEnvPanel(private val project: Project?,
baseSdkField.childComponent.addItemListener { listener.run() }
}
private fun moduleToExcludeSdkFrom(path: String, project: Project?): Module? {
val possibleProjects = if (project != null) listOf(project) else ProjectManager.getInstance().openProjects.asList()
val rootFile = StandardFileSystems.local().refreshAndFindFileByPath(path) ?: return null
return possibleProjects
.asSequence()
.map { ModuleUtil.findModuleForFile(rootFile, it) }
.filterNotNull()
.firstOrNull()
}
private val projectBasePath: @SystemIndependent String?
get() = newProjectPath ?: module?.basePath ?: project?.basePath
}
@@ -26,12 +26,12 @@ import com.intellij.openapi.ui.TextFieldWithBrowseButton
import com.intellij.openapi.ui.ValidationInfo
import com.intellij.openapi.util.NlsContexts
import com.intellij.openapi.util.UserDataHolder
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.text.StringUtil
import com.jetbrains.python.PySdkBundle
import com.jetbrains.python.newProject.steps.PyAddNewEnvironmentPanel
import com.jetbrains.python.sdk.*
import com.jetbrains.python.sdk.add.PyAddSdkDialogFlowAction.OK
import com.jetbrains.python.sdk.configuration.PyProjectVirtualEnvConfiguration
import icons.PythonIcons
import java.awt.Component
import java.io.File
@@ -162,14 +162,12 @@ fun addBaseInterpretersAsync(sdkComboBox: PySdkPathChoosingComboBox,
{ findBaseSdks(existingSdks, module, context).takeIf { it.isNotEmpty() } ?: getSdksToInstall() },
{
sdkComboBox.apply {
val preferredSdkPath = PySdkSettings.instance.preferredVirtualEnvBaseSdk.takeIf(FileUtil::exists)
val detectedPreferredSdk = items.find { it.homePath == preferredSdkPath }
selectedSdk = when {
detectedPreferredSdk != null -> detectedPreferredSdk
preferredSdkPath != null -> PyDetectedSdk(preferredSdkPath).apply {
childComponent.insertItemAt(this, 0)
val preferredSdk = PyProjectVirtualEnvConfiguration.findPreferredVirtualEnvBaseSdk(items)
if (preferredSdk != null) {
if (items.find { it.homePath == preferredSdk.homePath } == null) {
childComponent.insertItemAt(preferredSdk, 0)
}
else -> items.getOrNull(0)
selectedSdk = preferredSdk
}
}
callback()
@@ -0,0 +1,68 @@
// Copyright 2000-2020 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.
package com.jetbrains.python.sdk.configuration
import com.intellij.execution.ExecutionException
import com.intellij.openapi.module.Module
import com.intellij.openapi.module.ModuleUtil
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.progress.Task
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.ProjectManager
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.util.UserDataHolder
import com.intellij.openapi.util.UserDataHolderBase
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.vfs.StandardFileSystems
import com.intellij.util.concurrency.annotations.RequiresEdt
import com.jetbrains.python.PySdkBundle
import com.jetbrains.python.packaging.PyPackageManager
import com.jetbrains.python.sdk.*
object PyProjectVirtualEnvConfiguration {
@RequiresEdt
fun createVirtualEnvSynchronously(baseSdk: Sdk?,
existingSdks: List<Sdk>,
venvRoot: String,
projectBasePath: String?,
project: Project?,
module: Module?,
context: UserDataHolder = UserDataHolderBase(),
inheritSitePackages: Boolean = false,
makeShared: Boolean = false): Sdk? {
val installedSdk = installSdkIfNeeded(baseSdk, module, existingSdks, context)
if (installedSdk == null) return null
val projectPath = projectBasePath ?: module?.basePath ?: project?.basePath
val task = object : Task.WithResult<String, ExecutionException>(project, PySdkBundle.message("python.creating.venv.title"), false) {
override fun compute(indicator: ProgressIndicator): String {
indicator.isIndeterminate = true
val packageManager = PyPackageManager.getInstance(installedSdk)
return packageManager.createVirtualEnv(venvRoot, inheritSitePackages)
}
}
val associatedPath = if (!makeShared) projectPath else null
val venvSdk = createSdkByGenerateTask(task, existingSdks, installedSdk, associatedPath, null) ?: return null
if (!makeShared) {
venvSdk.associateWithModule(module, projectBasePath)
}
moduleToExcludeSdkFrom(venvRoot, project)?.excludeInnerVirtualEnv(venvSdk)
PySdkSettings.instance.onVirtualEnvCreated(installedSdk, FileUtil.toSystemIndependentName(venvRoot), projectPath)
return venvSdk
}
fun findPreferredVirtualEnvBaseSdk(existingBaseSdks: List<Sdk>): Sdk? {
val preferredSdkPath = PySdkSettings.instance.preferredVirtualEnvBaseSdk.takeIf(FileUtil::exists)
val detectedPreferredSdk = existingBaseSdks.find { it.homePath == preferredSdkPath }
return when {
detectedPreferredSdk != null -> detectedPreferredSdk
preferredSdkPath != null -> PyDetectedSdk(preferredSdkPath)
else -> existingBaseSdks.getOrNull(0)
}
}
private fun moduleToExcludeSdkFrom(path: String, project: Project?): Module? {
val possibleProjects = if (project != null) listOf(project) else ProjectManager.getInstance().openProjects.asList()
val rootFile = StandardFileSystems.local().refreshAndFindFileByPath(path) ?: return null
return possibleProjects.mapNotNull { ModuleUtil.findModuleForFile(rootFile, it) }.firstOrNull()
}
}