/**
  * @return A command line to be shown to the user. Note that this command line should not actually
  *     be used for an execution (only String[] should be passed to Runtie.exec)
  * @throws JDTNotAvailableException
  */
 public String getCommandLineAsString() throws JDTNotAvailableException {
   String[] args;
   try {
     args = getCommandLine(false);
     return SimpleRunner.getArgumentsAsStr(args);
   } catch (CoreException e) {
     throw new RuntimeException(e);
   }
 }
 /**
  * Can be used to extract the pythonpath used from a given configuration.
  *
  * @param conf the configuration from where we want to get the pythonpath
  * @return a string with the pythonpath used (with | as a separator)
  * @throws CoreException
  * @throws InvalidRunException
  * @throws MisconfigurationException
  */
 public static String getPythonpathFromConfiguration(
     ILaunchConfiguration conf, IInterpreterManager manager)
     throws CoreException, InvalidRunException, MisconfigurationException {
   IProject p = getProjectFromConfiguration(conf);
   PythonNature pythonNature = PythonNature.getPythonNature(p);
   if (pythonNature == null) {
     throw new CoreException(
         PydevDebugPlugin.makeStatus(
             IStatus.ERROR, "Project should have a python nature: " + p.getName(), null));
   }
   IInterpreterInfo l = getInterpreterLocation(conf, pythonNature, manager);
   return SimpleRunner.makePythonPathEnvString(pythonNature, l, manager);
 }
  /**
   * Create a command line for launching.
   *
   * @param actualRun if true it'll make the variable substitution and start the listen connector in
   *     the case of a debug session.
   * @return command line ready to be exec'd
   * @throws CoreException
   * @throws JDTNotAvailableException
   */
  public String[] getCommandLine(boolean actualRun) throws CoreException, JDTNotAvailableException {
    List<String> cmdArgs = new ArrayList<String>();

    if (isJython()) {
      // "java.exe" -classpath "C:\bin\jython21\jython.jar" org.python.util.jython script %ARGS%
      String javaLoc = JavaVmLocationFinder.findDefaultJavaExecutable().getAbsolutePath();
      if (!InterpreterInfo.isJythonExecutable(interpreter.toOSString())) {
        throw new RuntimeException(
            "The jython jar must be specified as the interpreter to run. Found: " + interpreter);
      }
      cmdArgs.add(javaLoc);

      // some nice things on the classpath config: http://mindprod.com/jgloss/classpath.html
      cmdArgs.add("-classpath");
      String cpath;

      // TODO: add some option in the project so that the user can choose to use the
      // classpath specified in the java project instead of the pythonpath itself

      //            if (project.getNature(Constants.JAVA_NATURE) != null){
      //                cpath  = getClasspath(JavaCore.create(project));
      //            } else {
      cpath = interpreter + SimpleRunner.getPythonPathSeparator() + pythonpathUsed;
      //            }
      cmdArgs.add(cpath);
      cmdArgs.add(
          "-Dpython.path="
              + pythonpathUsed); // will be added to the env variables in the run (check if this
      // works on all platforms...)

      addVmArgs(cmdArgs);

      if (isDebug) {
        // This was removed because it cannot be used. See:
        // http://bugs.jython.org/issue1438
        // cmdArgs.add("-Dpython.security.respectJavaAccessibility=false");

        cmdArgs.add("org.python.util.jython");
        addDebugArgs(cmdArgs, "jython", actualRun);
      } else {
        cmdArgs.add("org.python.util.jython");
      }

    } else {
      // python or iron python

      cmdArgs.add(interpreter.toOSString());
      // Next option is for unbuffered stdout, otherwise Eclipse will not see any output until done
      cmdArgs.add("-u");

      addVmArgs(cmdArgs);
      if (isDebug && isIronpython()) {
        addIronPythonDebugVmArgs(cmdArgs);
      }

      addDebugArgs(cmdArgs, "python", actualRun);
    }

    // Check if we should do code-coverage...
    boolean coverageRun = PyCoveragePreferences.getAllRunsDoCoverage();
    if (coverageRun && isDebug) {
      if (actualRun) {
        RunInUiThread.async(
            new Runnable() {

              public void run() {
                PyDialogHelpers.openWarning(
                    "Conflicting options: coverage with debug.",
                    "Making a debug run with coverage enabled will not yield the expected results.\n\n"
                        + "They'll conflict because both use the python tracing facility (i.e.: sys.settrace()).\n"
                        + "\n"
                        + "To debug a coverage run, do a regular run and use the remote debugger "
                        + "(but note that the coverage will stop when it's enabled).\n"
                        + "\n"
                        + "Note: the run will be continued anyways.");
              }
            });
      }
    }

    if (isUnittest()) {
      cmdArgs.add(getRunFilesScript());
    } else {
      if (coverageRun) {
        // Separate support (unittest has the coverage support builtin).
        cmdArgs.add(getCoverageScript());
        cmdArgs.add(PyCoverage.getCoverageFileLocation().getAbsolutePath());
        cmdArgs.add("run");
        cmdArgs.add("--source");
        cmdArgs.add(PyCodeCoverageView.getChosenDir().getLocation().toOSString());
      }
    }

    for (IPath p : resource) {
      cmdArgs.add(p.toOSString());
    }

    if (!isUnittest()) {
      // The program arguments are not used when running a unittest (excluded from the tab group in
      // favor
      // of a way to overriding the default unittest arguments).
      String runArguments[] = null;
      if (actualRun && arguments != null) {
        String expanded =
            getStringSubstitution(PythonNature.getPythonNature(project))
                .performStringSubstitution(arguments);
        runArguments = parseStringIntoList(expanded);
      }

      for (int i = 0; runArguments != null && i < runArguments.length; i++) {
        cmdArgs.add(runArguments[i]);
      }

    } else {
      // Last thing (first the files and last the special parameters the user passed -- i.e.: nose
      // parameters)
      addUnittestArgs(cmdArgs, actualRun, coverageRun);
    }

    String[] retVal = new String[cmdArgs.size()];
    cmdArgs.toArray(retVal);

    if (actualRun) {
      CreatedCommandLineParams createdCommandLineParams =
          new CreatedCommandLineParams(retVal, coverageRun);
      // Provide a way for clients to alter the command line.
      List<Object> participants =
          ExtensionHelper.getParticipants(ExtensionHelper.PYDEV_COMMAND_LINE_PARTICIPANT);
      for (Object object : participants) {
        try {
          IPyCommandLineParticipant c = (IPyCommandLineParticipant) object;
          createdCommandLineParams = c.updateCommandLine(createdCommandLineParams);
        } catch (Exception e) {
          Log.log(e);
        }
      }

      retVal = createdCommandLineParams.cmdLine;
      PythonRunnerCallbacks.onCreatedCommandLine.call(createdCommandLineParams);
    }

    return retVal;
  }
  /**
   * Sets defaults.
   *
   * @throws InvalidRunException
   * @throws MisconfigurationException
   */
  @SuppressWarnings("unchecked")
  public PythonRunnerConfig(
      ILaunchConfiguration conf, String mode, String run, boolean makeArgumentsVariableSubstitution)
      throws CoreException, InvalidRunException, MisconfigurationException {
    // 1st thing, see if this is a valid run.
    project = getProjectFromConfiguration(conf);

    if (project == null) { // Ok, we could not find it out
      throw Log.log("Could not get project for configuration: " + conf);
    }

    // We need the project to find out the default interpreter from the InterpreterManager.
    IPythonNature pythonNature = PythonNature.getPythonNature(project);
    if (pythonNature == null) {
      CoreException e = Log.log("No python nature for project: " + project.getName());
      throw e;
    }

    // now, go on configuring other things
    this.configuration = conf;
    this.run = run;
    isDebug = mode.equals(ILaunchManager.DEBUG_MODE);
    isInteractive = mode.equals("interactive");

    resource = getLocation(conf, pythonNature);
    arguments = getArguments(conf, makeArgumentsVariableSubstitution);
    IPath workingPath = getWorkingDirectory(conf, pythonNature);
    workingDirectory = workingPath == null ? null : workingPath.toFile();
    acceptTimeout = PydevPrefs.getPreferences().getInt(PydevEditorPrefs.CONNECT_TIMEOUT);

    interpreterLocation =
        getInterpreterLocation(conf, pythonNature, this.getRelatedInterpreterManager());
    interpreter = getInterpreter(interpreterLocation, conf, pythonNature);

    // make the environment
    ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager();
    envp = launchManager.getEnvironment(conf);
    IInterpreterManager manager;
    if (isJython()) {
      manager = PydevPlugin.getJythonInterpreterManager();
    } else if (isIronpython()) {
      manager = PydevPlugin.getIronpythonInterpreterManager();
    } else {
      manager = PydevPlugin.getPythonInterpreterManager();
    }

    boolean win32 = PlatformUtils.isWindowsPlatform();

    if (envp == null) {
      // ok, the user has done nothing to the environment, just get all the default environment
      // which has the pythonpath in it
      envp = SimpleRunner.getEnvironment(pythonNature, interpreterLocation, manager);

    } else {
      // ok, the user has done something to configure it, so, just add the pythonpath to the
      // current env (if he still didn't do so)
      Map envMap = conf.getAttribute(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES, (Map) null);

      String pythonpath =
          SimpleRunner.makePythonPathEnvString(pythonNature, interpreterLocation, manager);
      updateVar(pythonNature, manager, win32, envMap, "PYTHONPATH", pythonpath);
      if (isJython()) {
        // Also update the classpath env variable.
        updateVar(pythonNature, manager, win32, envMap, "CLASSPATH", pythonpath);
        // And the jythonpath env variable
        updateVar(pythonNature, manager, win32, envMap, "JYTHONPATH", pythonpath);

      } else if (isIronpython()) {
        // Also update the ironpythonpath env variable.
        updateVar(pythonNature, manager, win32, envMap, "IRONPYTHONPATH", pythonpath);
      }

      // And we also must get the environment variables specified in the interpreter manager.
      envp = interpreterLocation.updateEnv(envp, envMap.keySet());
    }

    boolean hasDjangoNature = project.hasNature(PythonNature.DJANGO_NATURE_ID);

    String settingsModule = null;
    Map<String, String> variableSubstitution = null;
    final String djangoSettingsKey = "DJANGO_SETTINGS_MODULE";
    String djangoSettingsEnvEntry = null;
    try {
      variableSubstitution = pythonNature.getPythonPathNature().getVariableSubstitution();
      settingsModule = variableSubstitution.get(djangoSettingsKey);
      if (settingsModule != null) {
        if (settingsModule.trim().length() > 0) {
          djangoSettingsEnvEntry = djangoSettingsKey + "=" + settingsModule.trim();
        }
      }
    } catch (Exception e1) {
      Log.log(e1);
    }
    if (djangoSettingsEnvEntry == null && hasDjangoNature) {
      // Default if not specified (only add it if the nature is there).
      djangoSettingsEnvEntry = djangoSettingsKey + "=" + project.getName() + ".settings";
    }

    // Note: set flag even if not debugging as the user may use remote-debugging later on.
    boolean geventSupport =
        DebugPrefsPage.getGeventDebugging()
            && pythonNature.getInterpreterType() == IPythonNature.INTERPRETER_TYPE_PYTHON;

    // Now, set the pythonpathUsed according to what's in the environment.
    String p = "";
    for (int i = 0; i < envp.length; i++) {
      String s = envp[i];
      Tuple<String, String> tup = StringUtils.splitOnFirst(s, '=');
      String var = tup.o1;
      if (win32) {
        // On windows it doesn't matter, always consider uppercase.
        var = var.toUpperCase();
      }

      if (var.equals("PYTHONPATH")) {
        p = tup.o2;

      } else if (var.equals(djangoSettingsKey)) {
        // Update it.
        if (djangoSettingsEnvEntry != null) {
          envp[i] = djangoSettingsEnvEntry;
          djangoSettingsEnvEntry = null;
        }
      }

      if (geventSupport) {
        if (var.equals("GEVENT_SUPPORT")) {
          // Flag already set in the environment
          geventSupport = false;
        }
      }
    }

    // Still not added, let's do that now.
    if (djangoSettingsEnvEntry != null) {
      envp = StringUtils.addString(envp, djangoSettingsEnvEntry);
    }
    if (geventSupport) {
      envp = StringUtils.addString(envp, "GEVENT_SUPPORT=True");
    }
    this.pythonpathUsed = p;
  }
Exemple #5
0
  /*
   * (non-Javadoc)
   * @see org.eclipse.debug.ui.ILaunchConfigurationTab#initializeFrom(org.eclipse.debug.core.ILaunchConfiguration)
   */
  public void initializeFrom(ILaunchConfiguration configuration) {

    try {
      String id = configuration.getType().getIdentifier();
      IInterpreterManager manager = null;
      if (Constants.ID_JYTHON_LAUNCH_CONFIGURATION_TYPE.equals(id)
          || Constants.ID_JYTHON_UNITTEST_LAUNCH_CONFIGURATION_TYPE.equals(id)) {
        manager = PydevPlugin.getJythonInterpreterManager();

      } else if (Constants.ID_IRONPYTHON_LAUNCH_CONFIGURATION_TYPE.equals(id)
          || Constants.ID_IRONPYTHON_UNITTEST_LAUNCH_CONFIGURATION_TYPE.equals(id)) {
        manager = PydevPlugin.getIronpythonInterpreterManager();

      } else if (Constants.ID_PYTHON_REGULAR_LAUNCH_CONFIGURATION_TYPE.equals(id)
          || Constants.ID_PYTHON_COVERAGE_LAUNCH_CONFIGURATION_TYPE.equals(id)
          || Constants.ID_PYTHON_UNITTEST_LAUNCH_CONFIGURATION_TYPE.equals(id)) {
        manager = PydevPlugin.getPythonInterpreterManager();
      } else {
        // Get from the project
        try {
          // could throw core exception if project does not exist.
          IProject project = PythonRunnerConfig.getProjectFromConfiguration(configuration);
          PythonNature nature = PythonNature.getPythonNature(project);
          if (nature != null) {
            manager = PydevPlugin.getInterpreterManager(nature);
          }
        } catch (Exception e) {
          Log.log(e);
        }

        if (manager == null) {
          Log.log("Could not recognize: '" + id + "' using default python interpreter manager.");
          manager = PydevPlugin.getPythonInterpreterManager();
        }
      }
      String pythonPath = PythonRunnerConfig.getPythonpathFromConfiguration(configuration, manager);

      fPythonPathList.removeAll();
      java.util.List<String> paths = SimpleRunner.splitPythonpath(pythonPath);
      for (String p : paths) {
        fPythonPathList.add(p);
      }
      setErrorMessage(null);
    } catch (Exception e) {
      // Exceptions here may have several reasons
      // - The interpreter is incorrectly configured
      // - The arguments use an unresolved variable.
      // In each case, the exception contains a meaningful message, that is displayed
      Log.log(e);

      String message = e.getMessage();
      if (message == null) {
        message = "null (see error log for the traceback).";
      }
      String errorMsg =
          org.python.pydev.shared_core.string.StringUtils.replaceNewLines(message, " ");

      fPythonPathList.removeAll();
      fPythonPathList.add(errorMsg);
      setErrorMessage(errorMsg);
    }
  }