Introduce FS.execute() to execute a command defined by a ProcessBuilder
Change-Id: I2ad2c71ad30b969455bdea89637b8e996b1dad8c Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
This commit is contained in:
parent
6389948a81
commit
69cd6f5864
|
@ -52,6 +52,7 @@
|
|||
import java.io.InputStream;
|
||||
|
||||
import org.eclipse.jgit.junit.JGitTestUtil;
|
||||
import org.eclipse.jgit.util.FS.ExecutionResult;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -163,6 +164,45 @@ public void testWrongScript() throws IOException, InterruptedException {
|
|||
assertEquals(127, rc);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCopyStdInExecute()
|
||||
throws IOException, InterruptedException {
|
||||
String inputStr = "a\nb\rc\r\nd";
|
||||
File script = writeTempFile("cat -");
|
||||
ProcessBuilder pb = new ProcessBuilder("/bin/sh", script.getPath());
|
||||
ExecutionResult res = FS.DETECTED.execute(pb,
|
||||
new ByteArrayInputStream(inputStr.getBytes()));
|
||||
assertEquals(0, res.getRc());
|
||||
assertEquals(inputStr, new String(res.getStdout().toByteArray()));
|
||||
assertEquals("", new String(res.getStderr().toByteArray()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStdErrExecute() throws IOException, InterruptedException {
|
||||
File script = writeTempFile("echo hi >&2");
|
||||
ProcessBuilder pb = new ProcessBuilder("/bin/sh", script.getPath());
|
||||
ExecutionResult res = FS.DETECTED.execute(pb, null);
|
||||
assertEquals(0, res.getRc());
|
||||
assertEquals("", new String(res.getStdout().toByteArray()));
|
||||
assertEquals("hi" + sep, new String(res.getStderr().toByteArray()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllTogetherBinExecute()
|
||||
throws IOException, InterruptedException {
|
||||
String inputStr = "a\nb\rc\r\nd";
|
||||
File script = writeTempFile(
|
||||
"echo $#,$1,$2,$3,$4,$5,$6 >&2 ; cat -; exit 5");
|
||||
ProcessBuilder pb = new ProcessBuilder("/bin/sh", script.getPath(), "a",
|
||||
"b", "c");
|
||||
ExecutionResult res = FS.DETECTED.execute(pb,
|
||||
new ByteArrayInputStream(inputStr.getBytes()));
|
||||
assertEquals(5, res.getRc());
|
||||
assertEquals(inputStr, new String(res.getStdout().toByteArray()));
|
||||
assertEquals("3,a,b,c,,," + sep,
|
||||
new String(res.getStderr().toByteArray()));
|
||||
}
|
||||
|
||||
private File writeTempFile(String body) throws IOException {
|
||||
File f = File.createTempFile("RunProcessTestScript_", "");
|
||||
JGitTestUtil.write(f, body);
|
||||
|
|
|
@ -110,7 +110,54 @@ public FS detect(Boolean cygwinUsed) {
|
|||
}
|
||||
}
|
||||
|
||||
final static Logger LOG = LoggerFactory.getLogger(FS.class);
|
||||
/**
|
||||
* Result of an executed process. The caller is responsible to close the
|
||||
* contained {@link TemporaryBuffer}s
|
||||
*
|
||||
* @since 4.2
|
||||
*/
|
||||
public static class ExecutionResult {
|
||||
private TemporaryBuffer stdout;
|
||||
|
||||
private TemporaryBuffer stderr;
|
||||
|
||||
private int rc;
|
||||
|
||||
/**
|
||||
* @param stdout
|
||||
* @param stderr
|
||||
* @param rc
|
||||
*/
|
||||
public ExecutionResult(TemporaryBuffer stdout, TemporaryBuffer stderr,
|
||||
int rc) {
|
||||
this.stdout = stdout;
|
||||
this.stderr = stderr;
|
||||
this.rc = rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return buffered standard output stream
|
||||
*/
|
||||
public TemporaryBuffer getStdout() {
|
||||
return stdout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return buffered standard error stream
|
||||
*/
|
||||
public TemporaryBuffer getStderr() {
|
||||
return stderr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the return code of the process
|
||||
*/
|
||||
public int getRc() {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
private final static Logger LOG = LoggerFactory.getLogger(FS.class);
|
||||
|
||||
/** The auto-detected implementation selected for this operating system and JRE. */
|
||||
public static final FS DETECTED = detect();
|
||||
|
@ -1004,10 +1051,10 @@ private static boolean shutdownAndAwaitTermination(ExecutorService pool) {
|
|||
pool.shutdown(); // Disable new tasks from being submitted
|
||||
try {
|
||||
// Wait a while for existing tasks to terminate
|
||||
if (!pool.awaitTermination(5, TimeUnit.SECONDS)) {
|
||||
if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
|
||||
pool.shutdownNow(); // Cancel currently executing tasks
|
||||
// Wait a while for tasks to respond to being canceled
|
||||
if (!pool.awaitTermination(5, TimeUnit.SECONDS))
|
||||
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
|
||||
hasShutdown = false;
|
||||
}
|
||||
} catch (InterruptedException ie) {
|
||||
|
@ -1034,6 +1081,31 @@ private static boolean shutdownAndAwaitTermination(ExecutorService pool) {
|
|||
*/
|
||||
public abstract ProcessBuilder runInShell(String cmd, String[] args);
|
||||
|
||||
/**
|
||||
* Execute a command defined by a {@link ProcessBuilder}.
|
||||
*
|
||||
* @param pb
|
||||
* The command to be executed
|
||||
* @param in
|
||||
* The standard input stream passed to the process
|
||||
* @return The result of the executed command
|
||||
* @throws InterruptedException
|
||||
* @throws IOException
|
||||
* @since 4.2
|
||||
*/
|
||||
public ExecutionResult execute(ProcessBuilder pb, InputStream in)
|
||||
throws IOException, InterruptedException {
|
||||
TemporaryBuffer stdout = new TemporaryBuffer.LocalFile(null);
|
||||
TemporaryBuffer stderr = new TemporaryBuffer.Heap(1024, 1024 * 1024);
|
||||
try {
|
||||
int rc = runProcess(pb, stdout, stderr, in);
|
||||
return new ExecutionResult(stdout, stderr, rc);
|
||||
} finally {
|
||||
stdout.close();
|
||||
stderr.close();
|
||||
}
|
||||
}
|
||||
|
||||
private static class Holder<V> {
|
||||
final V value;
|
||||
|
||||
|
|
Loading…
Reference in New Issue