package org.testcontainers.utility;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.zeroturnaround.exec.InvalidExitValueException;
import org.zeroturnaround.exec.ProcessExecutor;
import org.zeroturnaround.exec.ProcessResult;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.TimeoutException;
import java.util.regex.Pattern;
import static org.slf4j.LoggerFactory.getLogger;
/**
* Process execution utility methods.
*/
public class CommandLine {
private static final Logger LOGGER = getLogger(CommandLine.class);
/**
* Run a shell command synchronously.
*
* @param command command to run and arguments
* @return the stdout output of the command
*/
public static String runShellCommand(String... command) {
String joinedCommand = String.join(" ", command);
LOGGER.debug("Executing shell command: `{}`", joinedCommand);
try {
ProcessResult result;
result = new ProcessExecutor()
.command(command)
.readOutput(true)
.exitValueNormal()
.execute();
return result.outputUTF8().trim();
} catch (IOException | InterruptedException | TimeoutException | InvalidExitValueException e) {
throw new ShellCommandException("Exception when executing " + joinedCommand, e);
}
}
/**
* Check whether an executable exists, either at a specific path (if a full path is given) or
* on the PATH.
*
* @param executable the name of an executable on the PATH or a complete path to an executable that may/may not exist
* @return whether the executable exists and is executable
*/
public static boolean executableExists(String executable) {
// First check if we've been given the full path already
File directFile = new File(executable);
if (directFile.exists() && directFile.canExecute()) {
return true;
}
for (String pathString : getSystemPath()) {
Path path = Paths.get(pathString);
if (Files.exists(path.resolve(executable)) && Files.isExecutable(path.resolve(executable))) {
return true;
}
}
return false;
}
@NotNull
public static String[] getSystemPath() {
return System.getenv("PATH").split(Pattern.quote(File.pathSeparator));
}
private static class ShellCommandException extends RuntimeException {
public ShellCommandException(String message, Exception e) {
super(message, e);
}
}
}