'Path' env variable on windows to uppercase (PY-21510)
[idea/community.git] / python / python-terminal / src / com / jetbrains / python / sdk / PyVirtualEnvTerminalCustomizer.kt
1 /*
2  * Copyright 2000-2016 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.jetbrains.python.sdk
17
18 import com.intellij.openapi.module.ModuleManager
19 import com.intellij.openapi.project.Project
20 import com.intellij.openapi.projectRoots.Sdk
21 import com.intellij.openapi.util.SystemInfo
22 import com.jetbrains.python.run.PyVirtualEnvReader
23 import com.jetbrains.python.run.findActivateScript
24 import org.jetbrains.plugins.terminal.LocalTerminalCustomizer
25 import java.io.File
26
27 /**
28  * @author traff
29  */
30
31 class PyVirtualEnvTerminalCustomizer : LocalTerminalCustomizer() {
32
33
34   override fun customizeCommandAndEnvironment(project: Project,
35                                               command: Array<out String>,
36                                               envs: MutableMap<String, String>): Array<out String> {
37     val sdk: Sdk? = findSdk(project)
38
39     if (sdk != null && PythonSdkType.isVirtualEnv(sdk)) {
40       // in case of virtualenv sdk on unix we activate virtualenv
41       val path = sdk.homePath
42
43       if (path != null) {
44
45         val shellPath = command[0]
46         val shellName = File(shellPath).name
47
48         if (shellName == "bash" || (SystemInfo.isMac && shellName == "sh") || (shellName == "zsh") || (shellName == "fish")) {
49           //for bash we pass activate script to jediterm shell integration (see jediterm-bash.in) to source it there
50           findActivateScript(path, shellPath)?.let { activate -> envs.put("JEDITERM_SOURCE", activate) }
51         }
52         else {
53           //for other shells we read envs from activate script by the default shell and pass them to the process
54           val reader = PyVirtualEnvReader(path)
55           reader.activate?.let {
56             envs.putAll(reader.readShellEnv().mapKeys { k-> k.key.toUpperCase() }.filterKeys { k -> k in arrayOf("PATH", "PS1", "VIRTUAL_ENV", "PYTHONHOME", "PROMPT") })
57           }
58         }
59       }
60     }
61
62     // for some reason virtualenv isn't activated in the rcfile for the login shell, so we make it non-login
63     return command.filter { arg -> arg != "--login" && arg != "-l"}.toTypedArray()
64   }
65
66
67   private fun findSdk(project: Project): Sdk? {
68     for (m in ModuleManager.getInstance(project).modules) {
69       val sdk: Sdk? = PythonSdkType.findPythonSdk(m)
70       if (sdk != null && !PythonSdkType.isRemote(sdk)) {
71         return sdk
72       }
73     }
74
75     return null
76   }
77
78
79   override fun getDefaultFolder(): String? {
80     return null
81   }
82 }
83