package org.eclipse.dltk.ruby.fastdebugger; import java.io.IOException; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.ILaunch; import org.eclipse.dltk.core.PreferencesLookupDelegate; import org.eclipse.dltk.core.environment.IDeployment; import org.eclipse.dltk.core.environment.IEnvironment; import org.eclipse.dltk.core.environment.IExecutionEnvironment; import org.eclipse.dltk.internal.launching.execution.DeploymentManager; import org.eclipse.dltk.launching.DebuggingEngineRunner; import org.eclipse.dltk.launching.IInterpreterInstall; import org.eclipse.dltk.launching.InterpreterConfig; import org.eclipse.dltk.launching.ScriptLaunchUtil; import org.eclipse.dltk.launching.debug.DbgpConnectionConfig; import org.eclipse.dltk.ruby.debug.RubyDebugPlugin; import org.eclipse.dltk.ruby.internal.launching.RubyGenericInstallType; import org.eclipse.dltk.ruby.launching.RubyLaunchConfigurationConstants; import org.eclipse.osgi.util.NLS; import org.osgi.framework.Bundle; public class FastDebuggerRunner extends DebuggingEngineRunner { public static final String ENGINE_ID = "org.eclipse.dltk.ruby.fastdebugger"; //$NON-NLS-1$ private static final String RUBY_HOST_VAR = "DBGP_RUBY_HOST"; //$NON-NLS-1$ private static final String RUBY_PORT_VAR = "DBGP_RUBY_PORT"; //$NON-NLS-1$ private static final String RUBY_KEY_VAR = "DBGP_RUBY_KEY"; //$NON-NLS-1$ private static final String RUBY_LOG_VAR = "DBGP_RUBY_LOG"; //$NON-NLS-1$ private static final String DEBUGGER_SCRIPT = "FastRunner.rb"; //$NON-NLS-1$ private static final String P_CHECK_RUBY_DEBUG = FastDebuggerConstants.CHECK_RUBY_DEBUG; protected IPath deploy(IDeployment deployment) throws CoreException { try { IPath deploymentPath = FastDebuggerPlugin.getDefault() .deployDebuggerSource(deployment); return deployment.getFile(deploymentPath).getPath(); } catch (IOException e) { // TODO: add code for handler throw new CoreException( new Status( IStatus.ERROR, FastDebuggerPlugin.PLUGIN_ID, Messages.FastDebuggerRunner_unableToDeployDebuggerSource, e)); } } public FastDebuggerRunner(IInterpreterInstall install) { super(install); } @Override protected InterpreterConfig addEngineConfig(InterpreterConfig config, PreferencesLookupDelegate delegate, ILaunch launch) throws CoreException { if (!(getInstall().getInterpreterInstallType() instanceof RubyGenericInstallType)) { throw new DebugException( new Status( IStatus.ERROR, FastDebuggerPlugin.PLUGIN_ID, Messages.FastDebuggerRunner_fastDebuggerCanOnlyBeRunWithGenericRubyInterpreter)); } IEnvironment env = getInstall().getEnvironment(); IExecutionEnvironment exeEnv = env .getAdapter(IExecutionEnvironment.class); IDeployment deployment = exeEnv.createDeployment(); if (deployment == null) { return null; } DeploymentManager.getInstance().addDeployment(launch, deployment); // Get debugger source location final IPath sourceLocation = deploy(deployment); final IPath scriptFile = sourceLocation.append(DEBUGGER_SCRIPT); // Creating new config InterpreterConfig newConfig = (InterpreterConfig) config.clone(); newConfig.addInterpreterArg("-r"); //$NON-NLS-1$ newConfig.addInterpreterArg(env.convertPathToString(scriptFile)); newConfig.addInterpreterArg("-I"); //$NON-NLS-1$ newConfig.addInterpreterArg(env.convertPathToString(sourceLocation)); // Environment DbgpConnectionConfig dbgpConfig = DbgpConnectionConfig.load(config); newConfig.addEnvVar(RUBY_HOST_VAR, dbgpConfig.getHost()); newConfig.addEnvVar(RUBY_PORT_VAR, Integer.toString(dbgpConfig .getPort())); String sessionId = dbgpConfig.getSessionId(); newConfig.addEnvVar(RUBY_KEY_VAR, sessionId); String logFileName = getLogFileName(delegate, sessionId); if (logFileName != null) { newConfig.addEnvVar(RUBY_LOG_VAR, logFileName); } final boolean check = delegate.getBoolean(FastDebuggerPlugin.PLUGIN_ID, FastDebuggerConstants.CHECK_RUBY_DEBUG); newConfig.setProperty(P_CHECK_RUBY_DEBUG, Boolean.valueOf(check)); return newConfig; } @Override protected String getDebuggingEngineId() { return ENGINE_ID; } /* * @see * org.eclipse.dltk.launching.DebuggingEngineRunner#getDebugPreferenceQualifier * () */ @Override protected String getDebugPreferenceQualifier() { return RubyDebugPlugin.PLUGIN_ID; } // FIXME TODO this is not used anywhere and is broken on non-1.8 installs // or when the install location is non-default such as with rvm. public IPath resolveGemsPath(boolean user) { IEnvironment env = getInstall().getEnvironment(); IPath gemsPath = new Path(getInstall().getInstallLocation() .toOSString()); if (gemsPath.segmentCount() < 2) return null; gemsPath = gemsPath.removeLastSegments(2); if (user == true) { gemsPath = gemsPath.append("lib/ruby/user-gems/1.8/gems"); //$NON-NLS-1$ IPath userGemsPathUbuntu = new Path("/var/lib/user-gems/1.8/gems"); //$NON-NLS-1$ if ((env.getFile(gemsPath).exists() != true) && (env.getFile(userGemsPathUbuntu).exists() == true)) { gemsPath = userGemsPathUbuntu; } } else { gemsPath = gemsPath.append("lib/ruby/gems/1.8/gems"); //$NON-NLS-1$ IPath gemsPathUbuntu = new Path("/var/lib/gems/1.8/gems"); //$NON-NLS-1$ if ((env.getFile(gemsPath).exists() != true) && (env.getFile(gemsPathUbuntu).exists() == true)) { gemsPath = gemsPathUbuntu; } } return gemsPath; } public boolean resolveRubyDebugGemExists() { IEnvironment environment = getInstall().getEnvironment(); IExecutionEnvironment executionEnvironment = environment .getAdapter(IExecutionEnvironment.class); Bundle bundle = FastDebuggerPlugin.getDefault().getBundle(); String output = ScriptLaunchUtil.runEmbeddedScriptReadContent( executionEnvironment, "scripts/check_debugger_gem.rb", bundle, //$NON-NLS-1$ getInstall().getInstallLocation(), new NullProgressMonitor()); return output.startsWith("true"); } @Override protected void checkConfig(InterpreterConfig config, IEnvironment environment) throws CoreException { super.checkConfig(config, environment); final Boolean check = (Boolean) config.getProperty(P_CHECK_RUBY_DEBUG); if (check != null && check.booleanValue()) { checkRubyDebug(); } } private void checkRubyDebug() throws CoreException { if (!resolveRubyDebugGemExists()) { abort( NLS .bind( Messages.FastDebuggerRunner_rubyDebugGemDoesntSeemToBeInstalled, new Object[] { getDebuggingEngine().getName(), getInstall().getInstallLocation() .toOSString() }), null); } } @Override protected String getDebuggingEnginePreferenceQualifier() { return FastDebuggerPlugin.PLUGIN_ID; } protected String getLoggingEnabledPreferenceKey() { return FastDebuggerConstants.ENABLE_LOGGING; } @Override protected String getLogFileNamePreferenceKey() { return FastDebuggerConstants.LOG_FILE_NAME; } protected String getLogFilePathPreferenceKey() { return FastDebuggerConstants.LOG_FILE_PATH; } @Override protected String getProcessType() { return RubyLaunchConfigurationConstants.ID_RUBY_PROCESS_TYPE; } }