From abdd432258ca6233e28604ff39847677e859b3d3 Mon Sep 17 00:00:00 2001 From: mattirn Date: Tue, 4 Feb 2020 18:52:01 +0100 Subject: [PATCH] Command output redirection to file --- .../org/jline/builtins/ConsoleEngine.java | 5 ++ .../org/jline/builtins/ConsoleEngineImpl.java | 13 ++- .../org/jline/builtins/SystemRegistry.java | 4 + .../jline/builtins/SystemRegistryImpl.java | 89 ++++++++++++++++--- demo/src/main/java/org/jline/demo/Repl.java | 2 +- 5 files changed, 96 insertions(+), 17 deletions(-) diff --git a/builtins/src/main/java/org/jline/builtins/ConsoleEngine.java b/builtins/src/main/java/org/jline/builtins/ConsoleEngine.java index a563eebd3..f7fc86677 100644 --- a/builtins/src/main/java/org/jline/builtins/ConsoleEngine.java +++ b/builtins/src/main/java/org/jline/builtins/ConsoleEngine.java @@ -146,6 +146,11 @@ default Object execute(File script) throws Exception { */ Object getVariable(String name); + /** + * Delete temporary console variables + */ + void purge(); + /** * Execute widget function * @param function to execute diff --git a/builtins/src/main/java/org/jline/builtins/ConsoleEngineImpl.java b/builtins/src/main/java/org/jline/builtins/ConsoleEngineImpl.java index 05c62de7e..64f950d1b 100644 --- a/builtins/src/main/java/org/jline/builtins/ConsoleEngineImpl.java +++ b/builtins/src/main/java/org/jline/builtins/ConsoleEngineImpl.java @@ -111,7 +111,7 @@ private Parser parser() { private Terminal terminal() { return systemRegistry.terminal(); } - + public boolean isExecuting() { return executing; } @@ -585,6 +585,11 @@ public Object execute(ParsedLine pl) throws Exception { } return out; } + + @Override + public void purge() { + engine.del("_*"); + } @Override public Object getVariable(String name) { @@ -624,10 +629,10 @@ public Object postProcess(String line, Object result, String output) { engine.put(Parser.getVariable(line), output); } out = null; - } + } return out; } - + private Object postProcess(String line, Object result) { Object out = result instanceof String && ((String)result).trim().length() == 0 ? null : result; if (Parser.getVariable(line) != null) { @@ -676,7 +681,7 @@ private Map defaultPrntOptions() { @Override public void println(Object object) { Map options = defaultPrntOptions(); - options.putIfAbsent("exception", "stack"); + options.putIfAbsent("exception", "message"); println(options, object); } diff --git a/builtins/src/main/java/org/jline/builtins/SystemRegistry.java b/builtins/src/main/java/org/jline/builtins/SystemRegistry.java index 27846acc7..f59484374 100644 --- a/builtins/src/main/java/org/jline/builtins/SystemRegistry.java +++ b/builtins/src/main/java/org/jline/builtins/SystemRegistry.java @@ -58,6 +58,10 @@ public interface SystemRegistry extends CommandRegistry { */ Object execute(String line) throws Exception; + /** + * Delete temporary console variables and reset output streams + */ + void cleanUp(); /** * * @return terminal diff --git a/builtins/src/main/java/org/jline/builtins/SystemRegistryImpl.java b/builtins/src/main/java/org/jline/builtins/SystemRegistryImpl.java index e49c1eaa5..f7093964c 100644 --- a/builtins/src/main/java/org/jline/builtins/SystemRegistryImpl.java +++ b/builtins/src/main/java/org/jline/builtins/SystemRegistryImpl.java @@ -8,10 +8,13 @@ */ package org.jline.builtins; +import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.File; +import java.io.InputStream; import java.io.OutputStream; +import java.io.File; +import java.io.FileOutputStream; import java.io.PrintStream; import java.util.*; import java.util.stream.Collectors; @@ -35,8 +38,6 @@ import org.jline.terminal.Terminal; import org.jline.terminal.TerminalBuilder; import org.jline.utils.AttributedStringBuilder; -import org.jline.utils.AttributedStyle; -import org.jline.utils.InfoCmp.Capability; /** * Aggregate command registeries. @@ -312,7 +313,9 @@ private static class CommandOutputStream { private PrintStream origErr; private Terminal origTerminal; private ByteArrayOutputStream byteOutputStream; + private FileOutputStream fileOutputStream; private PrintStream out; + private InputStream in; private Terminal terminal; private String output; private CommandRegistry.CommandSession commandSession; @@ -327,27 +330,64 @@ public CommandOutputStream(Terminal terminal) { this.commandSession = new CommandRegistry.CommandSession(terminal, terminal.input(), ps, ps); } - public void redirect(String var) throws IOException { + public void redirect() throws IOException { byteOutputStream = new ByteArrayOutputStream(); - out = new PrintStream(byteOutputStream); + doTerminal(byteOutputStream); + } + + public void redirect(File file, boolean append) throws IOException { + if (!file.exists()){ + try { + file.createNewFile(); + } catch(IOException e){ + (new File(file.getParent())).mkdirs(); + file.createNewFile(); + } + } + fileOutputStream = new FileOutputStream(file, append); + doTerminal(fileOutputStream); + } + + void doTerminal(OutputStream outputStream) throws IOException { + out = new PrintStream(outputStream); System.setOut(out); System.setErr(out); - terminal = TerminalBuilder.builder().streams(System.in, out).type(Terminal.TYPE_DUMB).build(); + in = new ByteArrayInputStream( "".getBytes() ); + terminal = TerminalBuilder.builder().streams(in, outputStream).type(Terminal.TYPE_DUMB).build(); this.commandSession = new CommandRegistry.CommandSession(terminal, terminal.input(), out, out); redirecting = true; } - + public void flush() { if (out == null) { return; } try { out.flush(); - if (out instanceof PrintStream && byteOutputStream != null) { + if (byteOutputStream != null) { byteOutputStream.flush(); output = byteOutputStream.toString(); + } else if (fileOutputStream != null) { + fileOutputStream.flush(); + } + } catch (Exception e) { + + } + } + + public void close() { + if (out == null) { + return; + } + try { + in.close(); + flush(); + if (byteOutputStream != null) { byteOutputStream.close(); byteOutputStream = null; + } else if (fileOutputStream != null) { + fileOutputStream.close(); + fileOutputStream = null; } out.close(); out = null; @@ -368,6 +408,7 @@ public void reset() { if (redirecting) { out = null; byteOutputStream = null; + fileOutputStream = null; output = null; System.setOut(origOut); System.setErr(origErr); @@ -391,12 +432,28 @@ public Object execute(String line) throws Exception { pl = parser.parse(line.replaceFirst(cmd, consoleEngine().getAlias(cmd)), 0, ParseContext.ACCEPT_LINE); cmd = ConsoleEngine.plainCommand(Parser.getCommand(pl.word())); } - String[] argv = pl.words().subList(1, pl.words().size()).toArray(new String[0]); + File toFile = null; + boolean append = false; + List words = pl.words(); + int lastArg = words.size(); + for (int i = 1; i < words.size() - 1; i++) { + if (words.get(i).equals(">") || words.get(i).equals(">>")) { + lastArg = i; + append = words.get(i).equals(">>"); + toFile = new File(words.get(i + 1)); + break; + } + } + String[] argv = words.subList(1, lastArg).toArray(new String[0]); Object out = null; exception = null; try { - if (var != null && consoleId != null && !consoleEngine().isExecuting()) { - outputStream.redirect(var); + if ((var != null || toFile != null) && consoleId != null && !consoleEngine().isExecuting()) { + if (toFile != null) { + outputStream.redirect(toFile, append); + } else { + outputStream.redirect(); + } } if (isLocalCommand(cmd)) { out = localExecute(cmd, argv); @@ -419,11 +476,19 @@ public Object execute(String line) throws Exception { if (consoleId != null && !consoleEngine().isExecuting()) { outputStream.flush(); out = consoleEngine().postProcess(pl.line(), out, outputStream.getOutput()); - outputStream.reset(); } } return out; } + + public void cleanUp() { + if (consoleId == null) { + return; + } + outputStream.close(); + outputStream.reset(); + consoleEngine().purge(); + } private void println(Exception exception) { if (consoleId != null) { diff --git a/demo/src/main/java/org/jline/demo/Repl.java b/demo/src/main/java/org/jline/demo/Repl.java index be67d4108..bb063fba6 100644 --- a/demo/src/main/java/org/jline/demo/Repl.java +++ b/demo/src/main/java/org/jline/demo/Repl.java @@ -296,7 +296,7 @@ public static void main(String[] args) { consoleEngine.println(terminal.getName()+": "+terminal.getType()); while (true) { try { - scriptEngine.del("_*"); // delete temporary variables + systemRegistry.cleanUp(); // delete temporary variables and reset output streams String line = reader.readLine("groovy-repl> "); Object result = systemRegistry.execute(line); consoleEngine.println(result);