import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
+import java.util.concurrent.*;
/**
* Synchronously execute a native command line. It's much more limited than the Apache Commons Exec library.
}
}
- /**
- * Execute command and display error and output streams in log.
- * Method {@link #execute(Command, StreamConsumer, StreamConsumer, long)} is preferable,
- * when fine-grained control of output of command required.
- */
- int execute(Command command, long timeoutMilliseconds) {
- return execute(command, new DefaultConsumer(), new DefaultConsumer(), timeoutMilliseconds);
- }
-
private void closeStreams(Process process) {
if (process != null) {
IOUtils.closeQuietly(process.getInputStream());
return exception;
}
}
-
-
- interface StreamConsumer {
- void consumeLine(String line);
- }
-
- private static class DefaultConsumer implements StreamConsumer {
- public void consumeLine(String line) {
- System.out.println(line);
- }
- }
}
private final Map<String, String> jvmEnvVariables = new HashMap<String, String>();
private final List<String> jvmArguments = new ArrayList<String>();
private String javaCommand;
-
+ private StreamConsumer stdOut = null, stdErr = null;
private final JarExtractor jarExtractor;
ForkedRunner(JarExtractor jarExtractor) {
return this;
}
+ /**
+ * Subscribe to the standard output. By default output is {@link System.out}
+ */
+ public ForkedRunner setStdOut(@Nullable StreamConsumer stream) {
+ this.stdOut = stream;
+ return this;
+ }
+
+ /**
+ * Subscribe to the error output. By default output is {@link System.err}
+ */
+ public ForkedRunner setStdErr(@Nullable StreamConsumer stream) {
+ this.stdErr = stream;
+ return this;
+ }
+
@Override
protected void doExecute() {
fork(createCommand());
}
private void fork(Command command) {
- int status = CommandExecutor.create().execute(command, ONE_DAY_IN_MILLISECONDS);
+ if (stdOut == null) {
+ stdOut = new PrintStreamConsumer(System.out);
+ }
+ if (stdErr == null) {
+ stdErr = new PrintStreamConsumer(System.err);
+ }
+ int status = CommandExecutor.create().execute(command, stdOut, stdErr, ONE_DAY_IN_MILLISECONDS);
if (status != 0) {
throw new IllegalStateException("TODO");
}
}
+
}
--- /dev/null
+/*
+ * Sonar Runner - API
+ * Copyright (C) 2011 SonarSource
+ * dev@sonar.codehaus.org
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.runner.api;
+
+import java.io.PrintStream;
+
+public class PrintStreamConsumer implements StreamConsumer {
+ private final PrintStream output;
+
+ public PrintStreamConsumer(PrintStream output) {
+ this.output = output;
+ }
+
+ public void consumeLine(String line) {
+ output.println(line);
+ }
+}
--- /dev/null
+/*
+ * Sonar Runner - API
+ * Copyright (C) 2011 SonarSource
+ * dev@sonar.codehaus.org
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.runner.api;
+
+public interface StreamConsumer {
+ void consumeLine(String line);
+}
@Rule
public ExpectedException thrown = ExpectedException.none();
- private File workDir;
+ PrintStreamConsumer stdout = new PrintStreamConsumer(System.out);
+ PrintStreamConsumer stderr = new PrintStreamConsumer(System.err);
+ File workDir;
@Before
public void setUp() throws IOException {
@Test
public void should_consume_StdOut_and_StdErr() throws Exception {
final StringBuilder stdOutBuilder = new StringBuilder();
- CommandExecutor.StreamConsumer stdOutConsumer = new CommandExecutor.StreamConsumer() {
+ StreamConsumer stdOutConsumer = new StreamConsumer() {
public void consumeLine(String line) {
stdOutBuilder.append(line).append(System.getProperty("line.separator"));
}
};
final StringBuilder stdErrBuilder = new StringBuilder();
- CommandExecutor.StreamConsumer stdErrConsumer = new CommandExecutor.StreamConsumer() {
+ StreamConsumer stdErrConsumer = new StreamConsumer() {
public void consumeLine(String line) {
stdErrBuilder.append(line).append(System.getProperty("line.separator"));
}
CommandExecutor.create().execute(command, NOP_CONSUMER, BAD_CONSUMER, 1000L);
}
- private static final CommandExecutor.StreamConsumer NOP_CONSUMER = new CommandExecutor.StreamConsumer() {
+ private static final StreamConsumer NOP_CONSUMER = new StreamConsumer() {
public void consumeLine(String line) {
// nop
}
};
- private static final CommandExecutor.StreamConsumer BAD_CONSUMER = new CommandExecutor.StreamConsumer() {
+ private static final StreamConsumer BAD_CONSUMER = new StreamConsumer() {
public void consumeLine(String line) {
throw new RuntimeException();
}
.addArguments("1")
.setEnvVariable("ENVVAR", "2")
.build();
- int exitCode = CommandExecutor.create().execute(command, 1000L);
+ int exitCode = CommandExecutor.create().execute(command, stdout, stderr, 1000L);
assertThat(exitCode).isEqualTo(0);
File logFile = new File(workDir, "echo.log");
assertThat(logFile).exists();
String executable = getScript("forever");
long start = System.currentTimeMillis();
try {
- CommandExecutor.create().execute(Command.builder().setExecutable(executable).setDirectory(workDir).build(), 300L);
+ Command command = Command.builder().setExecutable(executable).setDirectory(workDir).build();
+ CommandExecutor.create().execute(command, stdout, stderr, 300L);
fail();
} catch (CommandException e) {
long duration = System.currentTimeMillis() - start;
@Test
public void should_fail_if_script_not_found() {
thrown.expect(CommandException.class);
- CommandExecutor.create().execute(Command.builder().setExecutable("notfound").setDirectory(workDir).build(), 1000L);
+ Command command = Command.builder().setExecutable("notfound").setDirectory(workDir).build();
+ CommandExecutor.create().execute(command, stdout, stderr, 1000L);
}
private static String getScript(String name) throws IOException {