~vil/pydev/upstream

« back to all changes in this revision

Viewing changes to org.python.pydev/src/org/python/pydev/runners/SimpleRunner.java

  • Committer: Vladimír Lapáček
  • Date: 2006-08-30 18:38:44 UTC
  • Revision ID: vladimir.lapacek@gmail.com-20060830183844-f4d82c1239a7770a
Initial import of upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Created on 05/08/2005
 
3
 */
 
4
package org.python.pydev.runners;
 
5
 
 
6
import java.io.File;
 
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;
 
12
import java.util.Map;
 
13
 
 
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;
 
29
 
 
30
public abstract class SimpleRunner {
 
31
 
 
32
    /**
 
33
     * Just execute the string. Does nothing else.
 
34
     */
 
35
    public Process createProcess(String executionString, File workingDir) throws IOException {
 
36
        return Runtime.getRuntime().exec(executionString, null, workingDir);
 
37
    }
 
38
 
 
39
    /**
 
40
     * THIS CODE IS COPIED FROM org.eclipse.debug.internal.core.LaunchManager
 
41
     * 
 
42
     * changed so that we always set the PYTHONPATH in the environment
 
43
     * 
 
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).
 
46
     */
 
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();
 
51
        }
 
52
        
 
53
        
 
54
        String pythonPathEnvStr = "";
 
55
        try {
 
56
            
 
57
            if (PydevPlugin.getInterpreterManager(pythonNature).hasInfoOnDefaultInterpreter(pythonNature)){ //check if we have a default interpreter.
 
58
                pythonPathEnvStr = makePythonPathEnvString(project);
 
59
            }
 
60
        } catch (Exception e) {
 
61
            return null; //we cannot get it
 
62
        }
 
63
    
 
64
        DebugPlugin defaultPlugin = DebugPlugin.getDefault();
 
65
        if(defaultPlugin != null){
 
66
            Map<String,String> env = getDefaultSystemEnv(defaultPlugin);                
 
67
    
 
68
                env.put("PYTHONPATH", pythonPathEnvStr); //put the environment
 
69
                return getMapEnvAsArray(env);
 
70
        }else{
 
71
            return null;
 
72
        }
 
73
    }
 
74
 
 
75
    /**
 
76
     * @return an array with the env variables for the system with the format xx=yy  
 
77
     */
 
78
    public String[] getDefaultSystemEnvAsArray() throws CoreException {
 
79
        Map defaultSystemEnv = getDefaultSystemEnv();
 
80
        if(defaultSystemEnv != null){
 
81
            return getMapEnvAsArray(defaultSystemEnv);
 
82
        }
 
83
        return null;
 
84
    }
 
85
 
 
86
    /**
 
87
     * @return a map with the env variables for the system  
 
88
     */
 
89
    public Map getDefaultSystemEnv() throws CoreException {
 
90
        DebugPlugin defaultPlugin = DebugPlugin.getDefault();
 
91
        return getDefaultSystemEnv(defaultPlugin);
 
92
    }
 
93
 
 
94
    /**
 
95
     * @return a map with the env variables for the system  
 
96
     */
 
97
    private Map<String,String> getDefaultSystemEnv(DebugPlugin defaultPlugin) throws CoreException {
 
98
        if(defaultPlugin != null){
 
99
            ILaunchManager launchManager = defaultPlugin.getLaunchManager();
 
100
    
 
101
            // build base environment
 
102
            Map<String,String> env = new HashMap<String,String>();
 
103
            env.putAll(launchManager.getNativeEnvironment());
 
104
            
 
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();
 
110
                if (win32) {
 
111
                        // Win32 vars are case insensitive. Uppercase everything so
 
112
                        // that (for example) "pAtH" will correctly replace "PATH"
 
113
                        key= key.toUpperCase();
 
114
                }
 
115
                String value = (String) entry.getValue();
 
116
                // translate any string substitution variables
 
117
                String translated = value;
 
118
                try {
 
119
                                        translated = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(value, false);
 
120
                                } catch (Exception e) {
 
121
                                        Log.log(e);
 
122
                                }
 
123
                env.put(key, translated);
 
124
            }
 
125
            return env;
 
126
        }
 
127
        return null;
 
128
    }
 
129
 
 
130
    /**
 
131
     * @return whether we are in windows or not
 
132
     */
 
133
    public static boolean isWindowsPlatform() {
 
134
        try {
 
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){
 
139
                return true;
 
140
            }
 
141
            return false;
 
142
        }
 
143
    }
 
144
 
 
145
 
 
146
    /**
 
147
     * copied from org.eclipse.jdt.internal.launching.StandardVMRunner
 
148
     * @param args - other arguments to be added to the command line (may be null)
 
149
     * @return
 
150
     */
 
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;
 
157
        }
 
158
        
 
159
        
 
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)
 
166
            }
 
167
            
 
168
            buf.append(' ');
 
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;
 
178
                }
 
179
                command.append(character);
 
180
            }
 
181
            if (containsSpace) {
 
182
                buf.append('\"');
 
183
                buf.append(command.toString());
 
184
                buf.append('\"');
 
185
            } else {
 
186
                buf.append(command.toString());
 
187
            }
 
188
        }   
 
189
        return buf.toString();
 
190
    }   
 
191
 
 
192
    /**
 
193
     * Creates a string that can be passed as the PYTHONPATH 
 
194
     * 
 
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
 
197
     */
 
198
    public static String makePythonPathEnvString(IProject project) {
 
199
        List paths;
 
200
        if(project == null){
 
201
            return ""; //no pythonpath can be gotten (set to empty, so that the default is gotten)
 
202
        }
 
203
        
 
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).");
 
210
        }
 
211
        paths = pythonPathNature.getCompleteProjectPythonPath();
 
212
    
 
213
        String separator = getPythonPathSeparator();
 
214
        StringBuffer pythonpath = new StringBuffer();
 
215
        for (int i = 0; i < paths.size(); i++) {
 
216
                if (i > 0){
 
217
                        pythonpath.append(separator);
 
218
                }
 
219
                String path = REF.getFileAbsolutePath(new File((String) paths.get(i)));
 
220
            pythonpath.append(path);
 
221
        }
 
222
        return pythonpath.toString();
 
223
    }
 
224
    
 
225
    /**
 
226
     * @return the separator for the pythonpath variables (system dependent)
 
227
     */
 
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 = ";";
 
232
//        if(!win32){
 
233
//            separator = ":"; //system dependent
 
234
//        }
 
235
//        return separator;
 
236
    }
 
237
 
 
238
    /**
 
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
 
241
     */
 
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());
 
249
        }
 
250
        
 
251
        return strings.toArray(new String[strings.size()]);
 
252
    }
 
253
 
 
254
    /**
 
255
     * shortcut
 
256
     */
 
257
    public Tuple<String,String> runAndGetOutput(String executionString, File workingDir, IProgressMonitor monitor) {
 
258
        return runAndGetOutput(executionString, workingDir, null, monitor);
 
259
    }
 
260
    
 
261
    /**
 
262
     * shortcut
 
263
     */
 
264
    public Tuple<String,String>  runAndGetOutput(String executionString, File workingDir) {
 
265
        return runAndGetOutput(executionString, workingDir, null, new NullProgressMonitor());
 
266
    }
 
267
    
 
268
    /**
 
269
     * shortcut
 
270
     */
 
271
    public Tuple<String,String>  runAndGetOutput(String executionString, File workingDir, IProject project) {
 
272
        return runAndGetOutput(executionString, workingDir, project, new NullProgressMonitor());
 
273
    }
 
274
    
 
275
    /**
 
276
     * shortcut
 
277
     */
 
278
    public Tuple<String,String>  runAndGetOutput(String script, String[] args, File workingDir) {
 
279
        return runAndGetOutput(script, args, workingDir, null);
 
280
    }
 
281
 
 
282
    /**
 
283
     * This is the method that actually does the running (all others are just 'shortcuts' to this one).
 
284
     * 
 
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
 
290
     * 
 
291
     * @return the string that is the output of the process (stdout).
 
292
     */
 
293
    public abstract Tuple<String,String>  runAndGetOutput(String executionString, File workingDir, IProject project, IProgressMonitor monitor);
 
294
 
 
295
    /**
 
296
     * Execute the script specified with the interpreter for a given project 
 
297
     * 
 
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
 
302
     * 
 
303
     * @return a string with the output of the process (stdout)
 
304
     */
 
305
    public abstract Tuple<String,String>  runAndGetOutput(String script, String args[], File workingDir, IProject project);
 
306
 
 
307
}