mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-23 17:05:26 +02:00
Code cleanup, to make CommandLauncher testable.
This commit is contained in:
parent
295466d26f
commit
88d576787e
17 changed files with 340 additions and 279 deletions
|
@ -20,7 +20,6 @@ import java.util.List;
|
|||
import org.eclipse.cdt.codan.core.externaltool.AbstractOutputParser;
|
||||
import org.eclipse.cdt.codan.core.externaltool.ConfigurationSettings;
|
||||
import org.eclipse.cdt.codan.core.externaltool.IArgsSeparator;
|
||||
import org.eclipse.cdt.codan.core.externaltool.ICommandLauncher;
|
||||
import org.eclipse.cdt.codan.core.externaltool.InvocationFailure;
|
||||
import org.eclipse.cdt.codan.core.externaltool.InvocationParameters;
|
||||
import org.eclipse.cdt.codan.core.externaltool.SingleConfigurationSetting;
|
||||
|
@ -29,7 +28,6 @@ import org.eclipse.cdt.codan.core.param.BasicProblemPreference;
|
|||
import org.eclipse.cdt.codan.core.param.IProblemPreference;
|
||||
import org.eclipse.cdt.codan.core.param.MapProblemPreference;
|
||||
import org.eclipse.cdt.codan.core.test.CodanTestCase;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
|
||||
/**
|
||||
|
@ -92,7 +90,6 @@ public class ExternalToolInvokerTest extends CodanTestCase {
|
|||
InvocationParameters parameters = new InvocationParameters(currentIFile, currentIFile,
|
||||
currentIFile.getLocation().toOSString(), cproject.getProject().getLocation());
|
||||
externalToolInvoker.invoke(parameters, settings, argsSeparator, parsers);
|
||||
launcher.assertThatReceivedProject(cproject.getProject());
|
||||
launcher.assertThatReceivedExternalToolName(settings.getExternalToolName());
|
||||
launcher.assertThatReceivedExecutablePath(settings.getPath());
|
||||
launcher.assertThatReceivedArgs(expectedArgs(parameters));
|
||||
|
@ -109,8 +106,7 @@ public class ExternalToolInvokerTest extends CodanTestCase {
|
|||
return expectedArgs;
|
||||
}
|
||||
|
||||
private static class CommandLauncherStub implements ICommandLauncher {
|
||||
private IProject project;
|
||||
private static class CommandLauncherStub extends CommandLauncher {
|
||||
private String externalToolName;
|
||||
private IPath executablePath;
|
||||
private String[] args;
|
||||
|
@ -118,12 +114,14 @@ public class ExternalToolInvokerTest extends CodanTestCase {
|
|||
private boolean shouldDisplayOutput;
|
||||
private List<AbstractOutputParser> parsers;
|
||||
|
||||
public CommandLauncherStub() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildAndLaunchCommand(IProject project, String externalToolName,
|
||||
IPath executablePath, String[] args, IPath workingDirectory,
|
||||
boolean shouldDisplayOutput, List<AbstractOutputParser> parsers) throws InvocationFailure,
|
||||
Throwable {
|
||||
this.project = project;
|
||||
public void buildAndLaunchCommand(String externalToolName, IPath executablePath,
|
||||
String[] args, IPath workingDirectory, boolean shouldDisplayOutput,
|
||||
List<AbstractOutputParser> parsers) throws InvocationFailure, Throwable {
|
||||
this.externalToolName = externalToolName;
|
||||
this.executablePath = executablePath;
|
||||
this.args = args;
|
||||
|
@ -132,10 +130,6 @@ public class ExternalToolInvokerTest extends CodanTestCase {
|
|||
this.parsers = parsers;
|
||||
}
|
||||
|
||||
void assertThatReceivedProject(IProject expected) {
|
||||
assertEquals(expected, project);
|
||||
}
|
||||
|
||||
void assertThatReceivedExternalToolName(String expected) {
|
||||
assertEquals(expected, externalToolName);
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ import org.eclipse.cdt.codan.internal.core.externaltool.ShouldDisplayOutputSetti
|
|||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
public class ConfigurationSettings {
|
||||
public final class ConfigurationSettings {
|
||||
private final PathSetting path;
|
||||
private final ArgsSetting args;
|
||||
private final ShouldDisplayOutputSetting shouldDisplayOutput;
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012 Google, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Alex Ruiz - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.codan.core.externaltool;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
|
||||
/**
|
||||
* Builds and launches the command necessary to invoke an external tool.
|
||||
*
|
||||
* @author alruiz@google.com (Alex Ruiz)
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
public interface ICommandLauncher {
|
||||
/**
|
||||
* Builds and launches the command necessary to invoke an external tool.
|
||||
* @param project the current project.
|
||||
* @param externalToolName the name of the external tool.
|
||||
* @param executablePath the path and name of the external tool executable.
|
||||
* @param args the arguments to pass to the external tool executable.
|
||||
* @param workingDirectory the directory where the external tool should be executed.
|
||||
* @param shouldDisplayOutput indicates whether the output of the external tools should be
|
||||
* displayed in an Eclipse console.
|
||||
* @param parsers parse the output of the external tool.
|
||||
* @throws InvocationFailure if the external tool reports that it cannot be executed.
|
||||
* @throws Throwable if the external tool cannot be launched.
|
||||
*/
|
||||
void buildAndLaunchCommand(IProject project, String externalToolName, IPath executablePath,
|
||||
String[] args, IPath workingDirectory, boolean shouldDisplayOutput,
|
||||
List<AbstractOutputParser> parsers) throws InvocationFailure, Throwable;
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012 Google, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Alex Ruiz - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.codan.core.externaltool;
|
||||
|
||||
/**
|
||||
* Prints the output of an external tool to an Eclipse console. It uses the name of the external
|
||||
* tool as the console ID.
|
||||
*
|
||||
* @author alruiz@google.com (Alex Ruiz)
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
public interface IConsolePrinter {
|
||||
/**
|
||||
* Clears the contents of the console.
|
||||
*/
|
||||
void clear();
|
||||
|
||||
/**
|
||||
* Prints the specified message to the console, followed by a line separator string.
|
||||
* @param message the message to print.
|
||||
*/
|
||||
void println(String message);
|
||||
|
||||
/**
|
||||
* Prints a line separator to the console.
|
||||
*/
|
||||
void println();
|
||||
|
||||
/**
|
||||
* Closes the output stream of the console.
|
||||
*/
|
||||
void close();
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012 Google, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Alex Ruiz - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.codan.core.externaltool;
|
||||
|
||||
/**
|
||||
* Finds an Eclipse console that uses the name of an external tool as its own.
|
||||
*
|
||||
* @author alruiz@google.com (Alex Ruiz)
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
public interface IConsolePrinterFinder {
|
||||
/**
|
||||
* Finds an Eclipse console that uses the name of an external tool as its own.
|
||||
* @param externalToolName the name of the external tool that will be used as the name of the
|
||||
* console.
|
||||
* @param shouldDisplayOutput indicates whether the user wants to see the output of the external
|
||||
* tool in the console.
|
||||
* @return the created or found console.
|
||||
*/
|
||||
IConsolePrinter findConsole(String externalToolName, boolean shouldDisplayOutput);
|
||||
}
|
|
@ -20,7 +20,7 @@ import org.eclipse.core.runtime.IPath;
|
|||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
public class InvocationParameters {
|
||||
public final class InvocationParameters {
|
||||
private final IResource originalFile;
|
||||
private final IResource actualFile;
|
||||
private final String actualFilePath;
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.eclipse.cdt.codan.core.param.MapProblemPreference;
|
|||
*
|
||||
* @author alruiz@google.com (Alex Ruiz)
|
||||
*
|
||||
* @noextend This class is not intended to be extended by clients.
|
||||
* @since 2.1
|
||||
*/
|
||||
public class SingleConfigurationSetting<T> {
|
||||
|
|
|
@ -20,7 +20,7 @@ import java.util.regex.Pattern;
|
|||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
public class SpaceDelimitedArgsSeparator implements IArgsSeparator {
|
||||
public final class SpaceDelimitedArgsSeparator implements IArgsSeparator {
|
||||
private static final String[] NO_ARGS = new String[0];
|
||||
private static final Pattern EMPTY_SPACE_PATTERN = Pattern.compile("\\s+"); //$NON-NLS-1$
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import org.eclipse.cdt.codan.core.CodanCorePlugin;
|
|||
import org.eclipse.cdt.codan.core.externaltool.AbstractOutputParser;
|
||||
import org.eclipse.cdt.codan.core.externaltool.ConfigurationSettings;
|
||||
import org.eclipse.cdt.codan.core.externaltool.IArgsSeparator;
|
||||
import org.eclipse.cdt.codan.core.externaltool.ICommandLauncher;
|
||||
import org.eclipse.cdt.codan.core.externaltool.IConsolePrinterFinder;
|
||||
import org.eclipse.cdt.codan.core.externaltool.IInvocationParametersProvider;
|
||||
import org.eclipse.cdt.codan.core.externaltool.IProblemDisplay;
|
||||
import org.eclipse.cdt.codan.core.externaltool.ISupportedResourceVerifier;
|
||||
|
@ -56,17 +56,18 @@ public abstract class AbstractExternalToolBasedChecker extends AbstractCheckerWi
|
|||
* external tool.
|
||||
* @param argsSeparator separates the arguments to pass to the external tool executable. These
|
||||
* arguments are stored in a single {@code String}.
|
||||
* @param commandLauncher builds and launches the command necessary to invoke the external tool.
|
||||
* @param consolePrinterFinder finds an Eclipse console that uses the name of an external tool
|
||||
* as its own.
|
||||
* @param configurationSettings user-configurable external tool configuration settings.
|
||||
*/
|
||||
public AbstractExternalToolBasedChecker(IInvocationParametersProvider parametersProvider,
|
||||
ISupportedResourceVerifier supportedResourceVerifier, IArgsSeparator argsSeparator,
|
||||
ICommandLauncher commandLauncher, ConfigurationSettings configurationSettings) {
|
||||
IConsolePrinterFinder consolePrinterFinder, ConfigurationSettings configurationSettings) {
|
||||
this.parametersProvider = parametersProvider;
|
||||
this.supportedResourceVerifier = supportedResourceVerifier;
|
||||
this.argsSeparator = argsSeparator;
|
||||
this.configurationSettings = configurationSettings;
|
||||
externalToolInvoker = new ExternalToolInvoker(commandLauncher);
|
||||
externalToolInvoker = new ExternalToolInvoker(consolePrinterFinder);
|
||||
preferences = new SharedRootProblemPreference();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012 Google, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Alex Ruiz - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.codan.internal.core.externaltool;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.codan.core.externaltool.AbstractOutputParser;
|
||||
import org.eclipse.cdt.codan.core.externaltool.IConsolePrinter;
|
||||
import org.eclipse.cdt.codan.core.externaltool.IConsolePrinterFinder;
|
||||
import org.eclipse.cdt.codan.core.externaltool.InvocationFailure;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
|
||||
/**
|
||||
* Invokes an external tool command.
|
||||
*
|
||||
* @author alruiz@google.com (Alex Ruiz)
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
public class CommandLauncher {
|
||||
private ProcessInvoker processInvoker = new ProcessInvoker();
|
||||
private final IConsolePrinterFinder consolePrinterFinder;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param consolePrinter prints the output of an external tool to an Eclipse Console.
|
||||
*/
|
||||
public CommandLauncher(IConsolePrinterFinder consolePrinter) {
|
||||
this.consolePrinterFinder = consolePrinter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds and launches the command necessary to invoke an external tool.
|
||||
* @param externalToolName the name of the external tool.
|
||||
* @param executablePath the path and name of the external tool executable.
|
||||
* @param args the arguments to pass to the external tool executable.
|
||||
* @param workingDirectory the directory where the external tool should be executed.
|
||||
* @param shouldDisplayOutput indicates whether the output of the external tools should be
|
||||
* displayed in an Eclipse console.
|
||||
* @param parsers parse the output of the external tool.
|
||||
* @throws InvocationFailure if the external tool cannot be executed.
|
||||
* @throws Throwable if the external tool cannot be launched.
|
||||
*/
|
||||
public void buildAndLaunchCommand(String externalToolName, IPath executablePath, String[] args,
|
||||
IPath workingDirectory, boolean shouldDisplayOutput, List<AbstractOutputParser> parsers)
|
||||
throws InvocationFailure, Throwable {
|
||||
String command = buildCommand(executablePath, args);
|
||||
Process process = null;
|
||||
IConsolePrinter console =
|
||||
consolePrinterFinder.findConsole(externalToolName, shouldDisplayOutput);
|
||||
try {
|
||||
console.clear();
|
||||
console.println(command);
|
||||
console.println();
|
||||
process = processInvoker.invoke(command, workingDirectory);
|
||||
processStream(process.getInputStream(), parsers, console);
|
||||
processStream(process.getErrorStream(), parsers, console);
|
||||
} finally {
|
||||
if (process != null) {
|
||||
process.destroy();
|
||||
}
|
||||
console.close();
|
||||
}
|
||||
}
|
||||
|
||||
private String buildCommand(IPath executablePath, String[] args) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(executablePath.toOSString());
|
||||
for (String arg : args) {
|
||||
builder.append(" ").append(arg); //$NON-NLS-1$
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private void processStream(InputStream inputStream, List<AbstractOutputParser> parsers,
|
||||
IConsolePrinter console) throws IOException, InvocationFailure {
|
||||
Reader reader = null;
|
||||
try {
|
||||
reader = new InputStreamReader(inputStream);
|
||||
BufferedReader bufferedReader = new BufferedReader(reader);
|
||||
String line = null;
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
console.println(line);
|
||||
for (AbstractOutputParser parser : parsers) {
|
||||
if (parser.parse(line)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (reader != null) {
|
||||
try {
|
||||
reader.close();
|
||||
} catch (IOException ignored) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Visible for testing.
|
||||
void setProcessInvoker(ProcessInvoker newVal) {
|
||||
processInvoker = newVal;
|
||||
}
|
||||
}
|
|
@ -16,10 +16,9 @@ import java.util.List;
|
|||
import org.eclipse.cdt.codan.core.externaltool.AbstractOutputParser;
|
||||
import org.eclipse.cdt.codan.core.externaltool.ConfigurationSettings;
|
||||
import org.eclipse.cdt.codan.core.externaltool.IArgsSeparator;
|
||||
import org.eclipse.cdt.codan.core.externaltool.ICommandLauncher;
|
||||
import org.eclipse.cdt.codan.core.externaltool.IConsolePrinterFinder;
|
||||
import org.eclipse.cdt.codan.core.externaltool.InvocationFailure;
|
||||
import org.eclipse.cdt.codan.core.externaltool.InvocationParameters;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
|
||||
|
@ -31,15 +30,19 @@ import org.eclipse.core.runtime.Path;
|
|||
* @since 2.1
|
||||
*/
|
||||
public class ExternalToolInvoker {
|
||||
private final ICommandLauncher commandLauncher;
|
||||
private final CommandLauncher commandLauncher;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param commandLauncher builds and launches the command necessary to
|
||||
* invoke the external tool.
|
||||
* @param consolePrinterFinder finds an Eclipse console that uses the name of an external tool
|
||||
* as its own.
|
||||
*/
|
||||
public ExternalToolInvoker(ICommandLauncher commandLauncher) {
|
||||
public ExternalToolInvoker(IConsolePrinterFinder consolePrinterFinder) {
|
||||
this(new CommandLauncher(consolePrinterFinder));
|
||||
}
|
||||
|
||||
// Visible for testing.
|
||||
ExternalToolInvoker(CommandLauncher commandLauncher) {
|
||||
this.commandLauncher = commandLauncher;
|
||||
}
|
||||
|
||||
|
@ -48,23 +51,22 @@ public class ExternalToolInvoker {
|
|||
*
|
||||
* @param parameters the parameters to pass to the external tool executable.
|
||||
* @param configurationSettings user-configurable settings.
|
||||
* @param argsSeparator separates the arguments to pass to the external tool
|
||||
* executable. These
|
||||
* @param argsSeparator separates the arguments to pass to the external tool executable. These
|
||||
* arguments are stored in a single {@code String}.
|
||||
* @param parsers parse the output of the external tool.
|
||||
* @throws InvocationFailure if the external tool reports that it cannot be
|
||||
* executed.
|
||||
* @throws InvocationFailure if the external tool reports that it cannot be executed.
|
||||
* @throws Throwable if the external tool cannot be launched.
|
||||
*/
|
||||
public void invoke(InvocationParameters parameters, ConfigurationSettings configurationSettings, IArgsSeparator argsSeparator,
|
||||
public void invoke(InvocationParameters parameters, ConfigurationSettings configurationSettings,
|
||||
IArgsSeparator argsSeparator,
|
||||
List<AbstractOutputParser> parsers) throws InvocationFailure, Throwable {
|
||||
IPath executablePath = executablePath(configurationSettings);
|
||||
String[] args = argsToPass(parameters, configurationSettings, argsSeparator);
|
||||
boolean shouldDisplayOutput = configurationSettings.getShouldDisplayOutput().getValue();
|
||||
IProject project = parameters.getActualFile().getProject();
|
||||
try {
|
||||
commandLauncher.buildAndLaunchCommand(project, configurationSettings.getExternalToolName(), executablePath, args,
|
||||
parameters.getWorkingDirectory(), shouldDisplayOutput, parsers);
|
||||
commandLauncher.buildAndLaunchCommand(configurationSettings.getExternalToolName(),
|
||||
executablePath, args, parameters.getWorkingDirectory(), shouldDisplayOutput,
|
||||
parsers);
|
||||
} finally {
|
||||
reset(parsers);
|
||||
}
|
||||
|
@ -75,13 +77,15 @@ public class ExternalToolInvoker {
|
|||
return new Path(executablePath.toString());
|
||||
}
|
||||
|
||||
private String[] argsToPass(InvocationParameters parameters, ConfigurationSettings configurationSettings, IArgsSeparator argsSeparator) {
|
||||
private String[] argsToPass(InvocationParameters parameters,
|
||||
ConfigurationSettings configurationSettings, IArgsSeparator argsSeparator) {
|
||||
String[] configuredArgs = configuredArgs(configurationSettings, argsSeparator);
|
||||
String actualFilePath = parameters.getActualFilePath();
|
||||
return addFilePathToArgs(actualFilePath, configuredArgs);
|
||||
}
|
||||
|
||||
private String[] configuredArgs(ConfigurationSettings configurationSettings, IArgsSeparator argsSeparator) {
|
||||
private String[] configuredArgs(ConfigurationSettings configurationSettings,
|
||||
IArgsSeparator argsSeparator) {
|
||||
String args = configurationSettings.getArgs().getValue();
|
||||
return argsSeparator.separateArgs(args);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012 Google, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Alex Ruiz - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.codan.internal.core.externaltool;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.cdt.codan.core.externaltool.InvocationFailure;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
|
||||
/**
|
||||
* Executes a command in a separate process.
|
||||
*
|
||||
* @author alruiz@google.com (Alex Ruiz)
|
||||
*/
|
||||
class ProcessInvoker {
|
||||
private static final String[] ENVIRONMENT_VARIABLE_SETTINGS = {};
|
||||
private static final String ERROR_FORMAT = "Unable to invoke command '%s'"; //$NON-NLS-1$
|
||||
|
||||
Process invoke(String command, IPath workingDirectory) throws InvocationFailure {
|
||||
try {
|
||||
Runtime runtime = Runtime.getRuntime();
|
||||
if (workingDirectory == null) {
|
||||
return runtime.exec(command);
|
||||
}
|
||||
return runtime.exec(command, ENVIRONMENT_VARIABLE_SETTINGS, workingDirectory.toFile());
|
||||
} catch (IOException e) {
|
||||
throw new InvocationFailure(String.format(ERROR_FORMAT, command), e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,7 +18,7 @@ import org.eclipse.cdt.codan.core.externaltool.InvocationParametersProvider;
|
|||
import org.eclipse.cdt.codan.core.externaltool.SpaceDelimitedArgsSeparator;
|
||||
import org.eclipse.cdt.codan.core.model.AbstractExternalToolBasedChecker;
|
||||
import org.eclipse.cdt.codan.internal.ui.cxx.externaltool.CxxSupportedResourceVerifier;
|
||||
import org.eclipse.cdt.codan.ui.externaltool.CommandLauncher;
|
||||
import org.eclipse.cdt.codan.ui.externaltool.ConsolePrinterFinder;
|
||||
|
||||
/**
|
||||
* Base class for checkers that invoke external command-line tools to perform code checking
|
||||
|
@ -58,7 +58,7 @@ public abstract class AbstractCxxExternalToolBasedChecker extends AbstractExtern
|
|||
public AbstractCxxExternalToolBasedChecker(IInvocationParametersProvider parametersProvider,
|
||||
ISupportedResourceVerifier supportedResourceVerifier, IArgsSeparator argsSeparator,
|
||||
ConfigurationSettings configurationSettings) {
|
||||
super(parametersProvider, supportedResourceVerifier, argsSeparator, new CommandLauncher(),
|
||||
configurationSettings);
|
||||
super(parametersProvider, supportedResourceVerifier, argsSeparator,
|
||||
new ConsolePrinterFinder(), configurationSettings);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,113 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012 Google, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Alex Ruiz - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.codan.ui.externaltool;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.codan.core.externaltool.ICommandLauncher;
|
||||
import org.eclipse.cdt.codan.core.externaltool.AbstractOutputParser;
|
||||
import org.eclipse.cdt.codan.core.externaltool.InvocationFailure;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
|
||||
/**
|
||||
* Invokes an external tool command.
|
||||
*
|
||||
* @author alruiz@google.com (Alex Ruiz)
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
public class CommandLauncher implements ICommandLauncher {
|
||||
private static final String[] ENVIRONMENT_VARIABLE_SETTINGS = {};
|
||||
|
||||
private ConsolePrinterFactory consolePrinterFactory = new ConsolePrinterFactory();
|
||||
|
||||
@Override
|
||||
public void buildAndLaunchCommand(IProject project, String externalToolName,
|
||||
IPath executablePath, String[] args, IPath workingDirectory, boolean shouldDisplayOutput,
|
||||
List<AbstractOutputParser> parsers) throws InvocationFailure, Throwable {
|
||||
ConsolePrinter consolePrinter = consolePrinter(externalToolName, shouldDisplayOutput);
|
||||
String command = buildCommand(executablePath, args);
|
||||
Process process = null;
|
||||
try {
|
||||
consolePrinter.clear();
|
||||
consolePrinter.println(command);
|
||||
consolePrinter.println();
|
||||
try {
|
||||
process = invoke(command, workingDirectory);
|
||||
} catch (IOException e) {
|
||||
throw new InvocationFailure("Unable to start " + externalToolName, e); //$NON-NLS-1$
|
||||
}
|
||||
processStream(process.getInputStream(), parsers, consolePrinter);
|
||||
processStream(process.getErrorStream(), parsers, consolePrinter);
|
||||
} finally {
|
||||
if (process != null) {
|
||||
process.destroy();
|
||||
}
|
||||
consolePrinter.close();
|
||||
}
|
||||
}
|
||||
|
||||
private ConsolePrinter consolePrinter(String externalToolName, boolean shouldDisplayOutput) {
|
||||
return consolePrinterFactory.createConsolePrinter(externalToolName, shouldDisplayOutput);
|
||||
}
|
||||
|
||||
private String buildCommand(IPath executablePath, String[] args) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(executablePath.toOSString());
|
||||
for (String arg : args) {
|
||||
builder.append(" ").append(arg); //$NON-NLS-1$
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private Process invoke(String command, IPath workingDirectory) throws IOException {
|
||||
Runtime runtime = Runtime.getRuntime();
|
||||
if (workingDirectory == null) {
|
||||
return runtime.exec(command);
|
||||
}
|
||||
return runtime.exec(command, ENVIRONMENT_VARIABLE_SETTINGS, workingDirectory.toFile());
|
||||
}
|
||||
|
||||
private void processStream(InputStream inputStream, List<AbstractOutputParser> parsers,
|
||||
ConsolePrinter consolePrinter) throws IOException, InvocationFailure {
|
||||
Reader reader = null;
|
||||
try {
|
||||
reader = new InputStreamReader(inputStream);
|
||||
BufferedReader bufferedReader = new BufferedReader(reader);
|
||||
String line = null;
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
consolePrinter.println(line);
|
||||
for (AbstractOutputParser parser : parsers) {
|
||||
if (parser.parse(line)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (reader != null) {
|
||||
try {
|
||||
reader.close();
|
||||
} catch (IOException ignored) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Visible for testing.
|
||||
void setConsolePrinterFactory(ConsolePrinterFactory newVal) {
|
||||
this.consolePrinterFactory = newVal;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012 Google, Inc.
|
||||
* Copyright (c) 2012 Google, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
@ -10,45 +10,43 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.codan.ui.externaltool;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.cdt.codan.core.externaltool.IConsolePrinter;
|
||||
import org.eclipse.ui.console.MessageConsole;
|
||||
import org.eclipse.ui.console.MessageConsoleStream;
|
||||
|
||||
/**
|
||||
* Prints the output of an external tool to an Eclipse console. It uses the name of the external
|
||||
* tool as the console ID.
|
||||
*
|
||||
* Default implementation of <code>{@link IConsolePrinter}</code>.
|
||||
*
|
||||
* @author alruiz@google.com (Alex Ruiz)
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
interface ConsolePrinter {
|
||||
ConsolePrinter NullImpl = new ConsolePrinter() {
|
||||
@Override
|
||||
public void clear() {}
|
||||
class ConsolePrinter implements IConsolePrinter {
|
||||
private final MessageConsole console;
|
||||
private final MessageConsoleStream out;
|
||||
|
||||
@Override
|
||||
public void println(String message) {}
|
||||
|
||||
@Override
|
||||
public void println() {}
|
||||
ConsolePrinter(MessageConsole console) {
|
||||
this.console = console;
|
||||
out = console.newMessageStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {}
|
||||
};
|
||||
public void clear() {
|
||||
console.clearConsole();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the contents of the console.
|
||||
*/
|
||||
void clear();
|
||||
public void println(String s) {
|
||||
out.println(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the specified message to the console, followed by a line separator string.
|
||||
* @param message the message to print.
|
||||
*/
|
||||
void println(String message);
|
||||
|
||||
/**
|
||||
* Prints a line separator to the console.
|
||||
*/
|
||||
void println();
|
||||
|
||||
/**
|
||||
* Closes the output stream of the console.
|
||||
*/
|
||||
void close();
|
||||
public void println() {
|
||||
out.println();
|
||||
}
|
||||
|
||||
public void close() {
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException ignored) {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012 Google, Inc.
|
||||
* Copyright (c) 2012 Google, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
@ -12,8 +12,9 @@ package org.eclipse.cdt.codan.ui.externaltool;
|
|||
|
||||
import static org.eclipse.ui.console.IConsoleConstants.ID_CONSOLE_VIEW;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.cdt.codan.core.externaltool.IConsolePrinter;
|
||||
import org.eclipse.cdt.codan.core.externaltool.IConsolePrinterFinder;
|
||||
import org.eclipse.cdt.codan.internal.ui.CodanUIActivator;
|
||||
import org.eclipse.cdt.codan.ui.CodanEditorUtility;
|
||||
import org.eclipse.ui.IWorkbenchPage;
|
||||
import org.eclipse.ui.PartInitException;
|
||||
|
@ -22,26 +23,38 @@ import org.eclipse.ui.console.IConsole;
|
|||
import org.eclipse.ui.console.IConsoleManager;
|
||||
import org.eclipse.ui.console.IConsoleView;
|
||||
import org.eclipse.ui.console.MessageConsole;
|
||||
import org.eclipse.ui.console.MessageConsoleStream;
|
||||
|
||||
/**
|
||||
* Default implementation of <code>{@link ConsolePrinter}</code>.
|
||||
*
|
||||
* Default implementation of <code>{@link IConsolePrinterFinder}</code>.
|
||||
*
|
||||
* @author alruiz@google.com (Alex Ruiz)
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
class ConsolePrinterImpl implements ConsolePrinter {
|
||||
private final MessageConsole console;
|
||||
private final MessageConsoleStream out;
|
||||
public class ConsolePrinterFinder implements IConsolePrinterFinder {
|
||||
private static final NullConsolePrinter NULL_CONSOLE = new NullConsolePrinter();
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public IConsolePrinter findConsole(String externalToolName, boolean shouldDisplayOutput) {
|
||||
if (shouldDisplayOutput) {
|
||||
try {
|
||||
return createOrFindConsole(externalToolName);
|
||||
} catch (Throwable e) {
|
||||
CodanUIActivator.log("Unable to create/find console", e); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
return NULL_CONSOLE;
|
||||
}
|
||||
|
||||
static ConsolePrinter createOrFindConsole(String externalToolName)
|
||||
throws PartInitException {
|
||||
private IConsolePrinter createOrFindConsole(String externalToolName) throws PartInitException {
|
||||
MessageConsole console = findConsole(externalToolName);
|
||||
IWorkbenchPage page = CodanEditorUtility.getActivePage();
|
||||
if (page != null) {
|
||||
IConsoleView view = (IConsoleView) page.showView(ID_CONSOLE_VIEW);
|
||||
view.display(console);
|
||||
}
|
||||
return new ConsolePrinterImpl(console);
|
||||
return new ConsolePrinter(console);
|
||||
}
|
||||
|
||||
private static MessageConsole findConsole(String externalToolName) {
|
||||
|
@ -55,27 +68,4 @@ class ConsolePrinterImpl implements ConsolePrinter {
|
|||
consoleManager.addConsoles(new IConsole[] { console });
|
||||
return console;
|
||||
}
|
||||
|
||||
private ConsolePrinterImpl(MessageConsole console) {
|
||||
this.console = console;
|
||||
out = console.newMessageStream();
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
console.clearConsole();
|
||||
}
|
||||
|
||||
public void println(String s) {
|
||||
out.println(s);
|
||||
}
|
||||
|
||||
public void println() {
|
||||
out.println();
|
||||
}
|
||||
|
||||
public void close() {
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException ignored) {}
|
||||
}
|
||||
}
|
|
@ -10,21 +10,23 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.codan.ui.externaltool;
|
||||
|
||||
import org.eclipse.cdt.codan.internal.ui.CodanUIActivator;
|
||||
import org.eclipse.ui.PartInitException;
|
||||
import org.eclipse.cdt.codan.core.externaltool.IConsolePrinter;
|
||||
|
||||
/**
|
||||
* No-op implementation of <code>{@link IConsolePrinter}</code>.
|
||||
*
|
||||
* @author alruiz@google.com (Alex Ruiz)
|
||||
*/
|
||||
class ConsolePrinterFactory {
|
||||
ConsolePrinter createConsolePrinter(String externalToolName, boolean shouldDisplayOutput) {
|
||||
if (shouldDisplayOutput) {
|
||||
try {
|
||||
return ConsolePrinterImpl.createOrFindConsole(externalToolName);
|
||||
} catch (PartInitException e) {
|
||||
CodanUIActivator.log("Unable to create/find console", e); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
return ConsolePrinter.NullImpl;
|
||||
}
|
||||
class NullConsolePrinter implements IConsolePrinter {
|
||||
@Override
|
||||
public void clear() {}
|
||||
|
||||
@Override
|
||||
public void println(String message) {}
|
||||
|
||||
@Override
|
||||
public void println() {}
|
||||
|
||||
@Override
|
||||
public void close() {}
|
||||
}
|
Loading…
Add table
Reference in a new issue