Merge branch 'master' into traff/zip_helpers
[idea/community.git] / python / src / com / jetbrains / python / PythonHelper.java
1 /*
2  * Copyright 2000-2015 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;
17
18 import com.google.common.collect.Lists;
19 import com.intellij.execution.configurations.GeneralCommandLine;
20 import com.intellij.execution.configurations.ParamsGroup;
21 import com.intellij.openapi.util.io.FileUtil;
22 import com.jetbrains.python.sdk.PythonEnvUtil;
23 import org.jetbrains.annotations.NotNull;
24
25 import java.io.File;
26 import java.util.List;
27 import java.util.Map;
28
29 import static com.jetbrains.python.PythonHelpersLocator.getHelperFile;
30 import static com.jetbrains.python.PythonHelpersLocator.getHelpersRoot;
31
32 /**
33  * @author traff
34  */
35 public enum PythonHelper implements HelperPackage {
36   COVERAGEPY("coveragepy", ""), COVERAGE("coverage_runner", "run_coverage"),
37   DEBUGGER("pydev", "pydevd"),
38   ATTACH_DEBUGGER("pydev", "pydevd_attach_to_process.attach_pydevd"),
39
40   CONSOLE("pydev", "pydevconsole"),
41   RUN_IN_CONSOLE("pydev", "pydev_run_in_console"),
42   PROFILER("profiler", "run_profiler"),
43
44   LOAD_ENTRY_POINT("pycharm", "pycharm_load_entry_point"),
45
46   // Test runners
47   UT("pycharm", "utrunner"),
48   SETUPPY("pycharm", "pycharm_setup_runner"),
49   NOSE("pycharm", "noserunner"),
50   PYTEST("pycharm", "pytestrunner"),
51   ATTEST("pycharm", "attestrunner"),
52   DOCSTRING("pycharm", "docrunner"),
53
54   BEHAVE("pycharm", "behave_runner"),
55   LETTUCE("pycharm", "lettuce_runner"),
56
57   DJANGO_TEST_MANAGE("pycharm", "django_test_manage"),
58   DJANGO_MANAGE("pycharm", "django_manage"),
59   MANAGE_TASKS_PROVIDER("pycharm", "_jb_manage_tasks_provider"),
60
61   BUILDOUT_ENGULFER("pycharm", "buildout_engulfer"),
62
63   EPYDOC_FORMATTER("epydoc_formatter.py"),
64   REST_FORMATTER("rest_formatter.py"),
65   GOOGLE_FORMATTER("google_formatter.py"),
66   NUMPY_FORMATTER("numpy_formatter.py"),
67
68   EXTRA_SYSPATH("extra_syspath.py"),
69   SYSPATH("syspath.py"),
70
71   PEP8("pep8.py"),
72
73   REST_RUNNER("rest_runners/rst2smth.py"),
74
75   SPHINX_RUNNER("rest_runners/sphinx_runner.py");
76
77   @NotNull
78   private static PathHelperPackage findModule(String moduleEntryPoint, String path, boolean asModule) {
79     if (getHelperFile(path + ".zip").isFile()) {
80       return new ModuleHelperPackage(moduleEntryPoint, path + ".zip");
81     }
82
83     if (!asModule && new File(getHelperFile(path), moduleEntryPoint + ".py").isFile()) {
84       return new ScriptPythonHelper(moduleEntryPoint + ".py", getHelperFile(path));
85     }
86
87     return new ModuleHelperPackage(moduleEntryPoint, path);
88   }
89
90   private PathHelperPackage myModule;
91
92   PythonHelper(String pythonPath, String moduleName) {
93     this(pythonPath, moduleName, false);
94   }
95
96   PythonHelper(String pythonPath, String moduleName, boolean asModule) {
97     myModule = findModule(moduleName, pythonPath, asModule);
98   }
99
100   PythonHelper(String helperScript) {
101     myModule = new ScriptPythonHelper(helperScript, getHelpersRoot());
102   }
103
104
105   public String getPythonPath() {
106     return myModule.getPythonPath();
107   }
108
109   public abstract static class PathHelperPackage implements HelperPackage {
110     protected final File myPath;
111
112     PathHelperPackage(String path) {
113       myPath = new File(path);
114     }
115
116     @Override
117     public void addToPythonPath(@NotNull Map<String, String> environment) {
118       PythonEnvUtil.addToPythonPath(environment, myPath.getAbsolutePath());
119     }
120
121     @Override
122     public void addToGroup(@NotNull ParamsGroup group, @NotNull GeneralCommandLine cmd) {
123       addToPythonPath(cmd.getEnvironment());
124       group.addParameter(asParamString());
125     }
126
127     @Override
128     public String asParamString() {
129       return FileUtil.toSystemDependentName(myPath.getAbsolutePath());
130     }
131
132     @Override
133     public GeneralCommandLine newCommandLine(String sdkPath, List<String> parameters) {
134       List<String> args = Lists.newArrayList();
135       args.add(sdkPath);
136       args.add(asParamString());
137       args.addAll(parameters);
138       GeneralCommandLine cmd = new GeneralCommandLine(args);
139       addToPythonPath(cmd.getEnvironment());
140       return cmd;
141     }
142   }
143
144   /**
145    * Module Python helper can be executed from zip-archive
146    */
147   public static class ModuleHelperPackage extends PathHelperPackage {
148     private final String myModuleName;
149
150     public ModuleHelperPackage(String moduleName, String relativePath) {
151       super(getHelperFile(relativePath).getAbsolutePath());
152       this.myModuleName = moduleName;
153     }
154
155     @Override
156     public String asParamString() {
157       return "-m" + myModuleName;
158     }
159
160     @Override
161     public String getPythonPath() {
162       return FileUtil.toSystemDependentName(myPath.getAbsolutePath());
163     }
164   }
165
166   /**
167    * Script Python helper can be executed as a Python script, therefore
168    * PYTHONDONTWRITEBYTECODE option is set not to spoil installation
169    * with .pyc files
170    */
171   public static class ScriptPythonHelper extends PathHelperPackage {
172     private String myPythonPath;
173
174     public ScriptPythonHelper(String script, File pythonPath) {
175       super(new File(pythonPath, script).getAbsolutePath());
176       myPythonPath = pythonPath.getAbsolutePath();
177     }
178
179     @Override
180     public void addToPythonPath(@NotNull Map<String, String> environment) {
181       PythonEnvUtil.setPythonDontWriteBytecode(environment);
182       PythonEnvUtil.addToPythonPath(environment, myPythonPath);
183     }
184
185     @Override
186     public String getPythonPath() {
187       return myPythonPath;
188     }
189   }
190
191
192   @Override
193   public void addToPythonPath(@NotNull Map<String, String> environment) {
194     myModule.addToPythonPath(environment);
195   }
196
197   @Override
198   public void addToGroup(@NotNull ParamsGroup group, @NotNull GeneralCommandLine cmd) {
199     myModule.addToGroup(group, cmd);
200   }
201
202
203   @Override
204   public String asParamString() {
205     return myModule.asParamString();
206   }
207
208   @Override
209   public GeneralCommandLine newCommandLine(String sdkPath, List<String> parameters) {
210     return myModule.newCommandLine(sdkPath, parameters);
211   }
212
213 }