2
* Created on 05/08/2005
4
package org.python.pydev.runners;
7
import java.io.IOException;
8
import java.util.ArrayList;
9
import java.util.HashMap;
10
import java.util.Iterator;
11
import java.util.List;
14
import org.eclipse.core.resources.IProject;
15
import org.eclipse.core.runtime.CoreException;
16
import org.eclipse.core.runtime.IProgressMonitor;
17
import org.eclipse.core.runtime.NullProgressMonitor;
18
import org.eclipse.core.runtime.Platform;
19
import org.eclipse.core.variables.VariablesPlugin;
20
import org.eclipse.debug.core.DebugPlugin;
21
import org.eclipse.debug.core.ILaunchManager;
22
import org.eclipse.osgi.service.environment.Constants;
23
import org.python.pydev.core.IPythonPathNature;
24
import org.python.pydev.core.REF;
25
import org.python.pydev.core.Tuple;
26
import org.python.pydev.core.log.Log;
27
import org.python.pydev.plugin.PydevPlugin;
28
import org.python.pydev.plugin.nature.PythonNature;
30
public abstract class SimpleRunner {
33
* Just execute the string. Does nothing else.
35
public Process createProcess(String executionString, File workingDir) throws IOException {
36
return Runtime.getRuntime().exec(executionString, null, workingDir);
40
* THIS CODE IS COPIED FROM org.eclipse.debug.internal.core.LaunchManager
42
* changed so that we always set the PYTHONPATH in the environment
44
* @return the system environment with the PYTHONPATH env variable added for a given project (if it is null, return it with the
45
* default PYTHONPATH added).
47
public String[] getEnvironment(IProject project) throws CoreException {
48
PythonNature pythonNature = PythonNature.getPythonNature(project);
49
if(pythonNature == null){ //no associated nature in the project... just get the default env
50
return getDefaultSystemEnvAsArray();
54
String pythonPathEnvStr = "";
57
if (PydevPlugin.getInterpreterManager(pythonNature).hasInfoOnDefaultInterpreter(pythonNature)){ //check if we have a default interpreter.
58
pythonPathEnvStr = makePythonPathEnvString(project);
60
} catch (Exception e) {
61
return null; //we cannot get it
64
DebugPlugin defaultPlugin = DebugPlugin.getDefault();
65
if(defaultPlugin != null){
66
Map<String,String> env = getDefaultSystemEnv(defaultPlugin);
68
env.put("PYTHONPATH", pythonPathEnvStr); //put the environment
69
return getMapEnvAsArray(env);
76
* @return an array with the env variables for the system with the format xx=yy
78
public String[] getDefaultSystemEnvAsArray() throws CoreException {
79
Map defaultSystemEnv = getDefaultSystemEnv();
80
if(defaultSystemEnv != null){
81
return getMapEnvAsArray(defaultSystemEnv);
87
* @return a map with the env variables for the system
89
public Map getDefaultSystemEnv() throws CoreException {
90
DebugPlugin defaultPlugin = DebugPlugin.getDefault();
91
return getDefaultSystemEnv(defaultPlugin);
95
* @return a map with the env variables for the system
97
private Map<String,String> getDefaultSystemEnv(DebugPlugin defaultPlugin) throws CoreException {
98
if(defaultPlugin != null){
99
ILaunchManager launchManager = defaultPlugin.getLaunchManager();
101
// build base environment
102
Map<String,String> env = new HashMap<String,String>();
103
env.putAll(launchManager.getNativeEnvironment());
105
// Add variables from config
106
boolean win32= isWindowsPlatform();
107
for(Iterator iter= env.entrySet().iterator(); iter.hasNext(); ) {
108
Map.Entry entry= (Map.Entry) iter.next();
109
String key= (String) entry.getKey();
111
// Win32 vars are case insensitive. Uppercase everything so
112
// that (for example) "pAtH" will correctly replace "PATH"
113
key= key.toUpperCase();
115
String value = (String) entry.getValue();
116
// translate any string substitution variables
117
String translated = value;
119
translated = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(value, false);
120
} catch (Exception e) {
123
env.put(key, translated);
131
* @return whether we are in windows or not
133
public static boolean isWindowsPlatform() {
135
return Platform.getOS().equals(Constants.OS_WIN32);
136
} catch (NullPointerException e) {
137
String env = System.getenv("os");
138
if(env.toLowerCase().indexOf("win") != -1){
147
* copied from org.eclipse.jdt.internal.launching.StandardVMRunner
148
* @param args - other arguments to be added to the command line (may be null)
151
public static String getCommandLineAsString(String[] commandLine, String ... args) {
152
if(args != null && args.length > 0){
153
String[] newCommandLine = new String[commandLine.length + args.length];
154
System.arraycopy(commandLine, 0, newCommandLine, 0, commandLine.length);
155
System.arraycopy(args, 0, newCommandLine, commandLine.length, args.length);
156
commandLine = newCommandLine;
160
if (commandLine.length < 1)
161
return ""; //$NON-NLS-1$
162
StringBuffer buf= new StringBuffer();
163
for (int i= 0; i < commandLine.length; i++) {
164
if(commandLine[i] == null){
165
continue; //ignore nulls (changed from original code)
169
char[] characters= commandLine[i].toCharArray();
170
StringBuffer command= new StringBuffer();
171
boolean containsSpace= false;
172
for (int j = 0; j < characters.length; j++) {
173
char character= characters[j];
174
if (character == '\"') {
175
command.append('\\');
176
} else if (character == ' ') {
177
containsSpace = true;
179
command.append(character);
183
buf.append(command.toString());
186
buf.append(command.toString());
189
return buf.toString();
193
* Creates a string that can be passed as the PYTHONPATH
195
* @param project the project we want to get the settings from. If it is null, the system pythonpath is returned
196
* @return a string that can be used as the PYTHONPATH env variable
198
public static String makePythonPathEnvString(IProject project) {
201
return ""; //no pythonpath can be gotten (set to empty, so that the default is gotten)
204
//if we have a project, get its complete pythonpath
205
IPythonPathNature pythonPathNature = PythonNature.getPythonPathNature(project);
206
if(pythonPathNature == null){
207
throw new RuntimeException("The project "+project.getName()+" does not have the pythonpath configured, \n" +
208
"please configure it correcly (please check the pydev faq at \n" +
209
"http://pydev.sf.net/faq.html for better information on how to do it).");
211
paths = pythonPathNature.getCompleteProjectPythonPath();
213
String separator = getPythonPathSeparator();
214
StringBuffer pythonpath = new StringBuffer();
215
for (int i = 0; i < paths.size(); i++) {
217
pythonpath.append(separator);
219
String path = REF.getFileAbsolutePath(new File((String) paths.get(i)));
220
pythonpath.append(path);
222
return pythonpath.toString();
226
* @return the separator for the pythonpath variables (system dependent)
228
public static String getPythonPathSeparator(){
229
return System.getProperty( "path.separator" ); //is system dependent, and should cover for all cases...
230
// boolean win32= isWindowsPlatform();
231
// String separator = ";";
233
// separator = ":"; //system dependent
239
* @param env a map that will have its values formatted to xx=yy, so that it can be passed in an exec
240
* @return an array with the formatted map
242
private String[] getMapEnvAsArray(Map env) {
243
List<String> strings= new ArrayList<String>(env.size());
244
for(Iterator iter= env.entrySet().iterator(); iter.hasNext(); ) {
245
Map.Entry entry = (Map.Entry) iter.next();
246
StringBuffer buffer= new StringBuffer((String) entry.getKey());
247
buffer.append('=').append((String) entry.getValue());
248
strings.add(buffer.toString());
251
return strings.toArray(new String[strings.size()]);
257
public Tuple<String,String> runAndGetOutput(String executionString, File workingDir, IProgressMonitor monitor) {
258
return runAndGetOutput(executionString, workingDir, null, monitor);
264
public Tuple<String,String> runAndGetOutput(String executionString, File workingDir) {
265
return runAndGetOutput(executionString, workingDir, null, new NullProgressMonitor());
271
public Tuple<String,String> runAndGetOutput(String executionString, File workingDir, IProject project) {
272
return runAndGetOutput(executionString, workingDir, project, new NullProgressMonitor());
278
public Tuple<String,String> runAndGetOutput(String script, String[] args, File workingDir) {
279
return runAndGetOutput(script, args, workingDir, null);
283
* This is the method that actually does the running (all others are just 'shortcuts' to this one).
285
* @param executionString this is the string that will be executed
286
* @param workingDir this is the directory where the execution will happen
287
* @param project this is the project that is related to the run (it is used to get the environment for the shell we are going to
288
* execute with the correct pythonpath environment variable).
289
* @param monitor this is the monitor used to communicate the progress to the user
291
* @return the string that is the output of the process (stdout).
293
public abstract Tuple<String,String> runAndGetOutput(String executionString, File workingDir, IProject project, IProgressMonitor monitor);
296
* Execute the script specified with the interpreter for a given project
298
* @param script the script we will execute
299
* @param args the arguments to pass to the script
300
* @param workingDir the working directory
301
* @param project the project that is associated to this run
303
* @return a string with the output of the process (stdout)
305
public abstract Tuple<String,String> runAndGetOutput(String script, String args[], File workingDir, IProject project);