Pass virtualenv variables to the python process (PY-15085)

This commit is contained in:
Dmitry Trofimov
2016-09-02 12:50:17 +02:00
parent 2b7316131e
commit 3ef027c10a
4 changed files with 70 additions and 23 deletions
@@ -19,9 +19,8 @@ import com.intellij.openapi.module.ModuleManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.util.SystemInfo
import com.intellij.util.EnvironmentUtil
import com.jetbrains.python.sdk.flavors.PythonSdkFlavor
import com.jetbrains.python.sdk.flavors.VirtualEnvSdkFlavor
import com.jetbrains.python.run.PyVirtualEnvReader
import com.jetbrains.python.run.findActivateScript
import org.jetbrains.plugins.terminal.LocalTerminalCustomizer
import java.io.File
@@ -81,21 +80,3 @@ class PyVirtualEnvTerminalCustomizer : LocalTerminalCustomizer() {
}
}
class PyVirtualEnvReader(virtualEnvSdkPath: String) : EnvironmentUtil.ShellEnvReader() {
val activate = findActivateScript(virtualEnvSdkPath, shell)
override fun getShellProcessCommand(): MutableList<String>? {
return if (activate != null) mutableListOf(shell, "--rcfile", activate, "-i")
else super.getShellProcessCommand()
}
}
private fun findActivateScript(path: String?, shellPath: String): String? {
val shellName = File(shellPath).name
val activate = if (shellName == "fish" || shellName == "csh") File(File(path).parentFile, "activate." + shellName)
else File(File(path).parentFile, "activate")
return if (activate.exists()) activate.absolutePath else null
}
@@ -0,0 +1,43 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jetbrains.python.run
import com.intellij.util.EnvironmentUtil
import java.io.File
/**
* @author traff
*/
class PyVirtualEnvReader(virtualEnvSdkPath: String) : EnvironmentUtil.ShellEnvReader() {
val activate = findActivateScript(virtualEnvSdkPath, shell)
override fun getShellProcessCommand(): MutableList<String>? {
return if (activate != null) mutableListOf(shell, "--rcfile", activate, "-i")
else super.getShellProcessCommand()
}
}
fun findActivateScript(path: String?, shellPath: String): String? {
val shellName = File(shellPath).name
val activate = if (shellName == "fish" || shellName == "csh") File(File(path).parentFile, "activate." + shellName)
else File(File(path).parentFile, "activate")
return if (activate.exists()) activate.absolutePath else null
}
@@ -35,6 +35,7 @@ import com.intellij.execution.ui.ConsoleView;
import com.intellij.facet.Facet;
import com.intellij.facet.FacetManager;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.module.ModuleUtilCore;
@@ -75,9 +76,10 @@ import java.nio.charset.Charset;
import java.util.*;
/**
* @author Leonid Shalupov
* @author traff, Leonid Shalupov
*/
public abstract class PythonCommandLineState extends CommandLineState {
private static final Logger LOG = Logger.getInstance("#com.jetbrains.python.run.PythonCommandLineState");
// command line has a number of fixed groups of parameters; patchers should only operate on them and not the raw list.
@@ -291,13 +293,30 @@ public abstract class PythonCommandLineState extends CommandLineState {
addCommonEnvironmentVariables(getInterpreterPath(project, myConfig), env);
setupVirtualEnvVariables(env, myConfig.getSdkHome());
commandLine.getEnvironment().clear();
commandLine.getEnvironment().putAll(env);
commandLine.withParentEnvironmentType(myConfig.isPassParentEnvs() ? ParentEnvironmentType.CONSOLE : ParentEnvironmentType.NONE);
buildPythonPath(project, commandLine, myConfig, isDebug);
}
private static void setupVirtualEnvVariables(Map<String, String> env, String sdkHome) {
if (PythonSdkType.isVirtualEnv(sdkHome)) {
PyVirtualEnvReader reader = new PyVirtualEnvReader(sdkHome);
if (reader.getActivate() != null) {
try {
env.putAll(reader.readShellEnv());
}
catch (Exception e) {
LOG.error("Couldn't read virtualenv variables", e);
}
}
}
}
protected static void addCommonEnvironmentVariables(@Nullable String homePath, Map<String, String> env) {
PythonEnvUtil.setPythonUnbuffered(env);
if (homePath != null) {
@@ -303,8 +303,12 @@ public final class PythonSdkType extends SdkType {
});
}
public static boolean isVirtualEnv(Sdk sdk) {
public static boolean isVirtualEnv(@NotNull Sdk sdk) {
final String path = sdk.getHomePath();
return isVirtualEnv(path);
}
public static boolean isVirtualEnv(String path) {
return path != null && getVirtualEnvRoot(path) != null;
}