I/O Streams
Inject stdin, stdout, and stderr into Crest commands using @In, @Out, and @Err annotations.
Crest commands can receive the standard I/O streams – stdin, stdout, and stderr – as injected parameters. This gives commands direct control over input and output when return types alone are not sufficient.
@Out
Injects a PrintStream connected to stdout. Use it when a command needs to write output incrementally rather than returning a single value.
@Command
public void deploy(@Out final PrintStream out,
@Option("target") final String target) {
out.println("Deploying to " + target);
performDeploy(target);
out.println("Deployment complete");
}
@Err
Injects a PrintStream connected to stderr. Use it for error messages, warnings, and diagnostic output that should not mix with normal stdout content.
@Command
public void process(@Out final PrintStream out,
@Err final PrintStream err,
@Option("input") final File input) {
if (!input.exists()) {
err.println("Warning: input file not found, using defaults");
}
out.println("Processing...");
}
@In
Injects an InputStream connected to stdin. Use it when a command needs to read interactive input or piped data.
@Command
public void load(@In final InputStream in,
@Out final PrintStream out) throws IOException {
final BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = reader.readLine()) != null) {
out.println("Read: " + line);
}
}
Combining I/O Annotations
A single command can use any combination of @In, @Out, and @Err alongside regular options and arguments:
@Command
public void transform(@In final InputStream in,
@Out final PrintStream out,
@Err final PrintStream err,
@Option("format") @Default("json") final String format,
@Option("verbose") @Default("false") final boolean verbose) {
if (verbose) {
err.println("Reading from stdin, output format: " + format);
}
// Read from in, transform, write to out
}
Hidden from Help
I/O stream parameters annotated with @In, @Out, and @Err are automatically hidden from help output. They do not appear in the command’s option list or synopsis, since they are not user-facing options.
@Command(description = "Process input data")
public void process(@Out final PrintStream out,
@Err final PrintStream err,
@Option("format") final String format) { ... }
Running help process shows only the --format option. The @Out and @Err parameters are invisible to the user.
Testing with I/O Streams
The injected streams make commands easy to test. Use Main.builder() to redirect I/O:
@Test
public void testOutput() {
final PrintString out = new PrintString();
final Main main = Main.builder()
.command(MyCommands.class)
.out(out)
.build();
main.run("deploy", "--target", "staging");
assertTrue(out.toString().contains("Deploying to staging"));
}