diff --git a/internal/util/src/main/java/one/jpro/platform/internal/util/CommandRunner.java b/internal/util/src/main/java/one/jpro/platform/internal/util/CommandRunner.java index 8585ee76..c218d212 100644 --- a/internal/util/src/main/java/one/jpro/platform/internal/util/CommandRunner.java +++ b/internal/util/src/main/java/one/jpro/platform/internal/util/CommandRunner.java @@ -1,5 +1,7 @@ package one.jpro.platform.internal.util; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,7 +40,7 @@ public CommandRunner(String... args) { * @param logger Logger instance for logging process activities. * @param args Command line arguments to be executed by the process. */ - public CommandRunner(Logger logger, String... args) { + public CommandRunner(Logger logger, @NotNull String... args) { this.logger = logger; Collections.addAll(this.args, args); } @@ -69,7 +71,7 @@ public void setPrintToConsole(boolean printToConsole) { * * @param arg a string passed to the command line arguments */ - public void addArg(String arg) { + public void addArg(@NotNull String arg) { args.add(arg); } @@ -80,7 +82,7 @@ public void addArg(String arg) { * * @param arg a string passed to the command line arguments */ - public void addSecretArg(String arg) { + public void addSecretArg(@Nullable String arg) { secretArgs.add(arg); args.add(arg); } @@ -91,7 +93,7 @@ public void addSecretArg(String arg) { * * @param args varargs list of arguments */ - public void addArgs(String... args) { + public void addArgs(@NotNull String... args) { this.args.addAll(Arrays.asList(args)); } @@ -101,7 +103,7 @@ public void addArgs(String... args) { * * @param args a collection of arguments */ - public void addArgs(Collection args) { + public void addArgs(@NotNull Collection args) { this.args.addAll(args); } @@ -125,7 +127,7 @@ public List getCmdList() { * @param key a string with the environmental variable name * @param value a string with the environmental variable value */ - public void addToEnv(String key, String value) { + public void addToEnv(@NotNull String key, @NotNull String value) { envVars.put(key, value); } @@ -137,7 +139,7 @@ public void addToEnv(String key, String value) { * @throws IOException if an I/O error occurs * @throws InterruptedException if the current thread is interrupted by another thread while it is waiting */ - public int run(String processName) throws IOException, InterruptedException { + public int run(@Nullable String processName) throws IOException, InterruptedException { return run(processName, null); } @@ -150,7 +152,8 @@ public int run(String processName) throws IOException, InterruptedException { * @throws IOException if an I/O error occurs * @throws InterruptedException if the current thread is interrupted by another thread while it is waiting */ - public int run(String processName, File workingDirectory) throws IOException, InterruptedException { + public int run(@Nullable String processName, + @Nullable File workingDirectory) throws IOException, InterruptedException { Process process = setupProcess(processName, workingDirectory); Thread mergeOutputThread = mergeProcessOutput(process.getInputStream()); int result = process.waitFor(); @@ -168,7 +171,7 @@ public int run(String processName, File workingDirectory) throws IOException, In * @return the {@link Process} object * @throws IOException if an I/O error occurs */ - public Process runAsync(String processName) throws IOException { + public Process runAsync(@Nullable String processName) throws IOException { return runAsync(processName, null, true); } @@ -181,7 +184,8 @@ public Process runAsync(String processName) throws IOException { * @return the {@link Process} object * @throws IOException if an I/O error occurs */ - public Process runAsync(String processName, File workingDirectory) throws IOException { + public Process runAsync(@Nullable String processName, + @Nullable File workingDirectory) throws IOException { return runAsync(processName, workingDirectory, true); } @@ -195,7 +199,9 @@ public Process runAsync(String processName, File workingDirectory) throws IOExce * @return the {@link Process} object * @throws IOException if an I/O error occurs */ - public Process runAsync(String processName, File workingDirectory, boolean mergeOutput) throws IOException { + public Process runAsync(@Nullable String processName, + @Nullable File workingDirectory, + boolean mergeOutput) throws IOException { Process process = setupProcess(processName, workingDirectory); if (mergeOutput) mergeProcessOutput(process.getInputStream()); return process; @@ -210,7 +216,7 @@ public Process runAsync(String processName, File workingDirectory, boolean merge * @throws IOException if an I/O error occurs * @throws InterruptedException if the current thread is interrupted by another thread while it is waiting */ - public boolean runTimed(String processName, long timeout) throws IOException, InterruptedException { + public boolean runTimed(@Nullable String processName, long timeout) throws IOException, InterruptedException { return runTimed(processName, null, timeout); } @@ -225,7 +231,8 @@ public boolean runTimed(String processName, long timeout) throws IOException, In * @throws IOException if an I/O error occurs * @throws InterruptedException if the current thread is interrupted by another thread while it is waiting */ - public boolean runTimed(String processName, File workingDirectory, long timeout) + public boolean runTimed(@Nullable String processName, + @Nullable File workingDirectory, long timeout) throws IOException, InterruptedException { Process process = setupProcess(processName, workingDirectory); Thread logThread = mergeProcessOutput(process.getInputStream()); @@ -241,6 +248,7 @@ public boolean runTimed(String processName, File workingDirectory, long timeout) * * @return a single string with the whole output of the process */ + @Nullable public String getResponse() { return processOutput.length() > 0 ? processOutput.toString().replaceAll("\n", "") : null; @@ -251,6 +259,7 @@ public String getResponse() { * * @return a list with all the lines of the output */ + @NotNull public List getResponses() { return processOutput.length() > 0 ? Arrays.asList(processOutput.toString().split("\n")) : Collections.emptyList(); @@ -274,7 +283,11 @@ public String getLastResponse() { * @return the process object * @throws IOException if an I/O error occurs */ - private Process setupProcess(String processName, File directory) throws IOException { + private Process setupProcess(final String processName, final File directory) throws IOException { + if (args.isEmpty()) { + throw new IllegalArgumentException("No command line arguments provided"); + } + ProcessBuilder pb = new ProcessBuilder(args).redirectErrorStream(true); if (interactive) pb.inheritIO(); if (directory != null) pb.directory(directory); diff --git a/internal/util/src/test/java/one/jpro/platform/internal/util/CommandRunnerTests.java b/internal/util/src/test/java/one/jpro/platform/internal/util/CommandRunnerTests.java index 20e95d61..7bf12dd4 100644 --- a/internal/util/src/test/java/one/jpro/platform/internal/util/CommandRunnerTests.java +++ b/internal/util/src/test/java/one/jpro/platform/internal/util/CommandRunnerTests.java @@ -106,7 +106,13 @@ public void runAsyncWithDirectoryAndOutput() throws IOException, InterruptedExce } @Test - public void processTest() throws IOException, InterruptedException { + public void runWithoutArgs() { + assertThatThrownBy(() -> commandRunner.run("dir")) + .hasMessage("No command line arguments provided"); + } + + @Test + public void runWithResult() throws IOException, InterruptedException { if (PlatformUtils.isWindows()) { commandRunner.addArgs("cmd", "/c", "dir", "/b", "build.gradle"); } else { @@ -118,7 +124,7 @@ public void processTest() throws IOException, InterruptedException { } @Test - public void processLogTest() throws IOException, InterruptedException { + public void runWithDirectoryAndResult() throws IOException, InterruptedException { Path tempDir = Files.createTempDirectory("command-runner-tests"); String output; if (PlatformUtils.isWindows()) {