package uk.co.nickthecoder.feather.runtime.command;
import java.io.File;
import java.io.IOException;
import java.util.Map;
/**
* The base interface for Command, Pipe and Redirect.
* <p>
* Ideally, this would be sealed, but that feature is only available from Java 17 onwards,
* and I want to support earlier versions too.
* Do NOT create additional implementations!
* </p>
*/
public abstract class CommandBase implements Commandable {
/**
* Redirects stdout to a file. The file is cleared (if it exists).
*/
public Redirect redirect(File file) {
return redirect(file, false);
}
public Redirect redirect(String filename) {
return redirect(new File(filename));
}
/**
* Redirects stdout to a file.
*/
public Redirect redirect(File file, boolean append) {
return new Redirect(this, file, append, null, false, null);
}
public Redirect redirect(String filename, boolean append) {
return redirect(new File(filename), append);
}
/**
* Redirects stdout to a file. The file is cleared (if it exists).
*/
public Redirect redirectOutAndErr(File file) {
return redirectOutAndErr(file, false);
}
public Redirect redirectOutAndErr(String filename) {
return redirectOutAndErr(new File(filename));
}
/**
* Redirects stdout and stderr to a file.
*/
public Redirect redirectOutAndErr(File file, boolean append) {
return new Redirect(this, file, append, file, append, null);
}
public Redirect redirectOutAndErr(String filename, boolean append) {
return redirectOutAndErr(new File(filename), append);
}
/**
* Redirects stderr to a file. The file is cleared (if it exists).
*/
public Redirect redirectErr(File file) {
return redirectErr(file, false);
}
public Redirect redirectErr(String filename) {
return redirectErr(new File(filename));
}
/**
* Redirects stderr to a file. The file is cleared (if it exists).
*/
public Redirect redirectErr(File file, boolean append) {
return new Redirect(this, null, false, file, append, null);
}
public Redirect redirectErr(String filename, boolean append) {
return redirectErr(new File(filename), append);
}
/**
* Redirects standard input from a file.
*/
public Redirect redirectIn(File file) {
return new Redirect(this, null, false, null, false, file);
}
public Redirect redirectIn(String filename) {
return redirectIn(new File(filename));
}
/**
* Pipes the stdout from this command to the input of `consumer`.
* <p>
* NOTE. Piping stderr is NOT supported.
* </p>
*/
public Pipe pipe(CommandBase consumer) {
return new Pipe(this, consumer);
}
@Override
public CommandRunner dir(File dir) {
return new CommandRunner(this).dir(dir);
}
@Override
public CommandRunner dir(String directoryName) {
return dir(new File(directoryName));
}
@Override
public CommandRunner env(Map<String, String> env) {
return new CommandRunner(this).env(env);
}
@Override
public CommandRunner shell(Shell shell) {
return new CommandRunner(this).shell(shell);
}
@Override
public Process runAsync() throws IOException {
return runAsync(null, null);
}
@Override
public Process runAsync(Consumer stdout, Consumer stderr) throws IOException {
return new CommandRunner(this).runAsync();
}
@Override
public CommandResult run() {
return new CommandRunner(this).run();
}
@Override
public CommandResult run(Consumer stdout, Consumer stderr) {
return new CommandRunner(this).run(stdout, stderr);
}
@Override
public CommandResult collect() {
return new CommandRunner(this).collect();
}
@Override
public String eval() {
return collect().out;
}
@Override
public String evalOk() {
CommandResult result = collect();
if (result.ok()) {
return result.out;
} else {
return null;
}
}
/**
* Prints the command (using the default shell).
*/
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
boolean first = true;
for (String arg : CommandRunner.defaultShell.buildShell(this)) {
if (first) {
first = false;
} else {
sb.append(" ");
}
sb.append(arg);
}
return sb.toString();
}
}