fail_ = new HashSet<>();
+ private boolean failOnExit_ = true;
private BaseProject project_;
private int timeout = 30;
private String workDir_;
@@ -80,8 +81,6 @@ public void execute() throws Exception {
LOGGER.severe("A project must be specified.");
}
- var errorMessage = new StringBuilder(27);
-
final File workDir;
if (workDir_ == null || workDir_.isBlank()) {
workDir = new File(project_.workDirectory().getAbsolutePath());
@@ -91,6 +90,7 @@ public void execute() throws Exception {
if (workDir.isDirectory()) {
var pb = new ProcessBuilder();
+ pb.inheritIO();
pb.command(args_);
pb.directory(workDir);
@@ -100,63 +100,28 @@ public void execute() throws Exception {
var proc = pb.start();
var err = proc.waitFor(timeout, TimeUnit.SECONDS);
- var stdout = readStream(proc.getInputStream());
- var stderr = readStream(proc.getErrorStream());
if (!err) {
- errorMessage.append("TIMEOUT");
- } else if (!fail_.contains(ExecFail.NONE)) {
- var all = fail_.contains(ExecFail.ALL);
- var output = fail_.contains(ExecFail.OUTPUT);
- if ((all || fail_.contains(ExecFail.EXIT) || fail_.contains(ExecFail.NORMAL)) && proc.exitValue() > 0) {
- errorMessage.append("EXIT ").append(proc.exitValue());
- if (!stderr.isEmpty()) {
- errorMessage.append(", STDERR -> ").append(stderr.get(0));
- } else if (!stdout.isEmpty()) {
- errorMessage.append(", STDOUT -> ").append(stdout.get(0));
- }
- } else if ((all || output || fail_.contains(ExecFail.STDERR) || fail_.contains(ExecFail.NORMAL))
- && !stderr.isEmpty()) {
- errorMessage.append("STDERR -> ").append(stderr.get(0));
- } else if ((all || output || fail_.contains(ExecFail.STDOUT)) && !stdout.isEmpty()) {
- errorMessage.append("STDOUT -> ").append(stdout.get(0));
- }
- }
-
- if (LOGGER.isLoggable(Level.INFO) && errorMessage.isEmpty() && !stdout.isEmpty()) {
- for (var l : stdout) {
- LOGGER.info(l);
- }
+ proc.destroy();
+ throw new IOException("The command timed out.");
+ } else if (proc.exitValue() != 0 && failOnExit_) {
+ throw new IOException("The command exit status is: " + proc.exitValue());
}
} else {
- errorMessage.append("Invalid working directory: ").append(workDir.getCanonicalPath());
- }
-
- if (!errorMessage.isEmpty()) {
- throw new IOException(errorMessage.toString());
+ throw new IOException("Invalid work directory: " + workDir);
}
}
/**
- * Configure the failure mode.
+ * Configures whether the operation should fail if the command exit status is not 0.
*
- * The failure modes are:
- *
- * - {@link ExecFail#EXIT}
Exit value > 0
- * - {@link ExecFail#NORMAL}
Exit value > 0 or any data to the standard error stream (stderr)
- * - {@link ExecFail#OUTPUT}
Any data to the standard output stream (stdout) or stderr
- * - {@link ExecFail#STDERR}
Any data to stderr
- * - {@link ExecFail#STDOUT}
Any data to stdout
- * - {@link ExecFail#ALL}
Any of the conditions above
- * - {@link ExecFail#NONE}
Never fails
- *
+ * Default is {@code TRUE}
*
- * @param fail one or more failure modes
- * @return this operation instance
- * @see ExecFail
+ * @param failOnExit The fail on exit toggle
+ * @return this operation instance.
*/
- public ExecOperation fail(ExecFail... fail) {
- fail_.addAll(Set.of(fail));
+ public ExecOperation failOnExit(boolean failOnExit) {
+ failOnExit_ = failOnExit;
return this;
}
@@ -171,16 +136,6 @@ public ExecOperation fromProject(BaseProject project) {
return this;
}
- private List readStream(InputStream stream) {
- var lines = new ArrayList();
- try (var scanner = new Scanner(stream)) {
- while (scanner.hasNextLine()) {
- lines.add(scanner.nextLine());
- }
- }
- return lines;
- }
-
/**
* Configure the command timeout.
*
@@ -193,7 +148,7 @@ public ExecOperation timeout(int timeout) {
}
/**
- * Configures the working directory.
+ * Configures the work directory.
*
* @param dir the directory path
* @return this operation instance
diff --git a/src/test/java/rife/bld/extension/ExecOperationTest.java b/src/test/java/rife/bld/extension/ExecOperationTest.java
index 207caf9..e0b584c 100644
--- a/src/test/java/rife/bld/extension/ExecOperationTest.java
+++ b/src/test/java/rife/bld/extension/ExecOperationTest.java
@@ -19,10 +19,8 @@
import org.junit.jupiter.api.Test;
import rife.bld.BaseProject;
import rife.bld.Project;
-import rife.bld.WebProject;
import java.io.File;
-import java.io.IOException;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
@@ -31,18 +29,6 @@
class ExecOperationTest {
private static final String FOO = "foo";
- private static final String HELLO = "Hello";
-
- @Test
- void testAll() {
- assertThatCode(() ->
- new ExecOperation()
- .fromProject(new Project())
- .command("date")
- .fail(ExecFail.ALL)
- .execute()
- ).isInstanceOf(IOException.class);
- }
@Test
void testCat() throws Exception {
@@ -52,22 +38,11 @@ void testCat() throws Exception {
.fromProject(new Project())
.timeout(10)
.command("touch", tmpFile.getName())
- .fail(ExecFail.NORMAL)
.execute();
assertThat(tmpFile).exists();
}
- @Test
- void testCommandList() {
- assertThatCode(() ->
- new ExecOperation()
- .fromProject(new BaseProject())
- .command(List.of("logger", "-s", HELLO))
- .fail(ExecFail.STDERR)
- .execute()).message().startsWith("STDERR -> ").endsWith(HELLO);
- }
-
@Test
void testException() {
assertThatCode(() ->
@@ -78,54 +53,32 @@ void testException() {
}
@Test
- void testExit() {
+ void testExitStatus() {
assertThatCode(() ->
new ExecOperation()
.fromProject(new BaseProject())
- .command("tail", FOO)
- .fail(ExecFail.EXIT)
- .execute()).message().startsWith("EXIT ");
- }
-
- @Test
- void testNone() {
- assertThatCode(() ->
- new ExecOperation()
- .fromProject(new WebProject())
- .command("cat", FOO)
- .fail(ExecFail.NONE)
- .execute()).doesNotThrowAnyException();
- }
-
- @Test
- void testOutput() {
- assertThatCode(() ->
- new ExecOperation()
- .fromProject(new WebProject())
- .command("echo")
- .fail(ExecFail.OUTPUT)
- .execute()
- ).message().isEqualTo("STDOUT -> ");
+ .command(List.of("cat", FOO))
+ .execute()).message().contains("exit status");
}
@Test
- void testStdErr() {
+ void testFailOnExit() {
assertThatCode(() ->
new ExecOperation()
.fromProject(new BaseProject())
- .command("logger", "-s", HELLO)
- .fail(ExecFail.STDERR)
- .execute()).message().startsWith("STDERR -> ").endsWith(HELLO);
+ .command(List.of("cat", FOO))
+ .failOnExit(false)
+ .execute()).doesNotThrowAnyException();
}
@Test
- void testStdOut() {
+ void testTimeout() {
assertThatCode(() ->
new ExecOperation()
.fromProject(new BaseProject())
- .command("echo", HELLO)
- .fail(ExecFail.STDOUT)
- .execute()).message().isEqualTo("STDOUT -> Hello");
+ .timeout(5)
+ .command(List.of("sleep", "10"))
+ .execute()).message().contains("timed out");
}
@Test
@@ -135,7 +88,6 @@ void testWorkDir() {
.fromProject(new BaseProject())
.command("echo")
.workDir(FOO)
- .fail(ExecFail.NORMAL)
- .execute()).message().startsWith("Invalid working directory: ").endsWith(FOO);
+ .execute()).message().startsWith("Invalid work directory: ").endsWith(FOO);
}
}