mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-30 02:09:59 +07:00
PY-57146, DS-4124, DS-3992: Fix local conda activation on Windows for newly created SDKs
What was wrong: For SDK creation we execute python to get python path for homePath (see ``PyAddCondaTools``). So, we execute python on conda before homePath set. On each execution we read vars from ``activate.bat`` to workaround conda SSL in path problem and activate terminal (since cmd in terminal still uses old API). ``PySdkUtil`` can't read vars when homePath not set, hence caches empty vars for SDK and both terminal and conda workaround stop working until IDE restart. We now stopped caching empty vars if homePath is empty. GitOrigin-RevId: de3e37bbbc5281775e3fca79840089561ceed189
This commit is contained in:
committed by
intellij-monorepo-bot
parent
7c82d7196b
commit
ab43751a51
@@ -212,7 +212,12 @@ public final class PySdkUtil {
|
||||
if (cached != null) return cached;
|
||||
|
||||
final String sdkHome = sdk.getHomePath();
|
||||
if (sdkHome == null) return Collections.emptyMap();
|
||||
if (sdkHome == null || sdkHome.trim().isEmpty()) {
|
||||
// homePath is empty (not null) by default.
|
||||
// If we cache values when path is empty, we would stuck with empty env and never reread it once path set
|
||||
LOG.warn("homePath is null or empty, skipping env loading");
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
var additionalData = ObjectUtils.tryCast(sdk.getSdkAdditionalData(), PythonSdkAdditionalData.class);
|
||||
if (additionalData == null) {
|
||||
|
||||
@@ -41,6 +41,8 @@ suspend fun PyCondaCommand.createCondaSdkFromExistingEnv(condaIdentity: PyCondaE
|
||||
val sdk = ProjectJdkImpl(SdkConfigurationUtil.createUniqueSdkName(condaIdentity.userReadableName, existingSdks),
|
||||
PythonSdkType.getInstance())
|
||||
sdk.sdkAdditionalData = additionalData
|
||||
// homePath is not required by conda, but used by lots of tools all over the code and required by CondaPathFix
|
||||
// Because homePath is not set yet, CondaPathFix does not work
|
||||
sdk.homePath = sdk.getPythonBinaryPath(project).getOrThrow()
|
||||
saveLocalPythonCondaPath(Path.of(fullCondaPathOnTarget))
|
||||
return sdk
|
||||
|
||||
@@ -1,26 +1,35 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.jetbrains.env.conda
|
||||
|
||||
import com.intellij.execution.target.TargetedCommandLineBuilder
|
||||
import com.intellij.execution.target.local.LocalTargetEnvironmentRequest
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.projectRoots.impl.ProjectJdkImpl
|
||||
import com.intellij.openapi.util.SystemInfoRt
|
||||
import com.intellij.testFramework.ProjectRule
|
||||
import com.jetbrains.getPythonVersion
|
||||
import com.jetbrains.python.sdk.PythonSdkType
|
||||
import com.jetbrains.python.sdk.add.target.conda.createCondaSdkAlongWithNewEnv
|
||||
import com.jetbrains.python.sdk.add.target.conda.createCondaSdkFromExistingEnv
|
||||
import com.jetbrains.python.sdk.configureBuilderToRunPythonOnTarget
|
||||
import com.jetbrains.python.sdk.flavors.conda.*
|
||||
import com.jetbrains.python.sdk.flavors.conda.CondaPathFix.Companion.shouldBeFixed
|
||||
import com.jetbrains.python.sdk.getOrCreateAdditionalData
|
||||
import com.jetbrains.python.sdk.getPythonBinaryPath
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.hamcrest.MatcherAssert
|
||||
import org.hamcrest.Matchers
|
||||
import org.jdom.Element
|
||||
import org.junit.Assert
|
||||
import org.junit.Assume
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.RuleChain
|
||||
import java.io.File
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Ensures conda SDK could be created
|
||||
@@ -38,6 +47,30 @@ internal class PyCondaSdkTest {
|
||||
internal val chain = RuleChain.outerRule(projectRule).around(condaRule).around(yamlRule)
|
||||
|
||||
|
||||
/**
|
||||
* When we create fresh local SDK on Windows, it must be patched with env vars, see [CondaPathFix]
|
||||
*/
|
||||
@Test
|
||||
fun testLocalActivationFix(): Unit = runTest {
|
||||
Assume.assumeTrue("Windows only", SystemInfoRt.isWindows)
|
||||
val env = PyCondaEnv.getEnvs(
|
||||
condaRule.condaCommand).getOrThrow().first { (it.envIdentity as? PyCondaEnvIdentity.UnnamedEnv)?.isBase == true }
|
||||
val condaSdk = condaRule.condaCommand.createCondaSdkFromExistingEnv(env.envIdentity, emptyList(), projectRule.project)
|
||||
val request = LocalTargetEnvironmentRequest()
|
||||
val builder = TargetedCommandLineBuilder(request)
|
||||
Assert.assertTrue("No conda path fix suggested for Windows?", builder.shouldBeFixed)
|
||||
condaSdk.configureBuilderToRunPythonOnTarget(builder)
|
||||
builder.apply {
|
||||
addParameter("-c")
|
||||
addParameter("import os; print(' '.join(list(os.environ.keys())))")
|
||||
}
|
||||
val envVars = builder.build().environmentVariables.map { it.key.uppercase(Locale.getDefault()) to it.value }.toMap()
|
||||
MatcherAssert.assertThat("Conda not activated?", envVars.keys, Matchers.hasItem("PATH"))
|
||||
MatcherAssert.assertThat("Conda not activated?", envVars.keys, Matchers.hasItem("CONDA_PREFIX"))
|
||||
val paths = envVars["PATH"]!!.split(File.pathSeparator).map { Path.of(it) }
|
||||
MatcherAssert.assertThat("No conda python in PATH", paths, Matchers.hasItem(Path.of(condaSdk.homePath!!).parent))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testConvertToConda() = runTest {
|
||||
System.setProperty("NO_FS_ROOTS_ACCESS_CHECK", "true")
|
||||
|
||||
@@ -49,5 +49,6 @@
|
||||
<orderEntry type="library" scope="TEST" name="kotlinx-coroutines-jdk8" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="jetbrains.kotlinx.coroutines.test" level="project" />
|
||||
<orderEntry type="module" module-name="intellij.python.community.core.impl" scope="TEST" />
|
||||
<orderEntry type="module" module-name="intellij.python.sdk" scope="TEST" />
|
||||
</component>
|
||||
</module>
|
||||
Reference in New Issue
Block a user