From c0574fe680a45a27ca2d278ecb0cc1a1bfd3a440 Mon Sep 17 00:00:00 2001 From: Guillaume Nodet Date: Tue, 28 Jan 2014 10:19:59 +0100 Subject: [PATCH] Add an input stream and an error stream to TextBuiltin base class Leverage these streams to remove calls to System.in and System.err Bug: 413522 Change-Id: I8396f3e273c93e23861e8bcfb2ab8182fb09220d Signed-off-by: Guillaume Nodet Signed-off-by: Matthias Sohn --- .../jgit/pgm/AbstractFetchCommand.java | 7 +- .../org/eclipse/jgit/pgm/AmazonS3Client.java | 2 +- .../src/org/eclipse/jgit/pgm/IndexPack.java | 2 +- .../src/org/eclipse/jgit/pgm/Push.java | 2 +- .../src/org/eclipse/jgit/pgm/ReceivePack.java | 2 +- .../eclipse/jgit/pgm/RevWalkTextBuiltin.java | 7 +- .../src/org/eclipse/jgit/pgm/TextBuiltin.java | 78 ++++++++++++++----- .../src/org/eclipse/jgit/pgm/UploadPack.java | 2 +- .../jgit/pgm/debug/RebuildCommitGraph.java | 4 +- .../eclipse/jgit/pgm/debug/ShowCommands.java | 34 ++++---- 10 files changed, 88 insertions(+), 52 deletions(-) diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/AbstractFetchCommand.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/AbstractFetchCommand.java index 1fe39da8a..d226df21b 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/AbstractFetchCommand.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/AbstractFetchCommand.java @@ -50,7 +50,6 @@ package org.eclipse.jgit.pgm; import static java.lang.Character.valueOf; import java.io.IOException; -import java.io.PrintWriter; import java.text.MessageFormat; import org.eclipse.jgit.lib.Constants; @@ -60,6 +59,7 @@ import org.eclipse.jgit.lib.RefUpdate; import org.eclipse.jgit.pgm.internal.CLIText; import org.eclipse.jgit.transport.FetchResult; import org.eclipse.jgit.transport.TrackingRefUpdate; +import org.eclipse.jgit.util.io.ThrowingPrintWriter; import org.kohsuke.args4j.Option; abstract class AbstractFetchCommand extends TextBuiltin { @@ -92,11 +92,10 @@ abstract class AbstractFetchCommand extends TextBuiltin { } finally { reader.release(); } - showRemoteMessages(r.getMessages()); + showRemoteMessages(errw, r.getMessages()); } - static void showRemoteMessages(String pkt) { - PrintWriter writer = new PrintWriter(System.err); + static void showRemoteMessages(ThrowingPrintWriter writer, String pkt) throws IOException { while (0 < pkt.length()) { final int lf = pkt.indexOf('\n'); final int cr = pkt.indexOf('\r'); diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/AmazonS3Client.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/AmazonS3Client.java index 5e66c3601..e0a9244a8 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/AmazonS3Client.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/AmazonS3Client.java @@ -116,7 +116,7 @@ class AmazonS3Client extends TextBuiltin { final OutputStream os = s3.beginPut(bucket, key, null, null); final byte[] tmp = new byte[2048]; int n; - while ((n = System.in.read(tmp)) > 0) + while ((n = ins.read(tmp)) > 0) os.write(tmp, 0, n); os.close(); diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/IndexPack.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/IndexPack.java index 9fc588242..42114062b 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/IndexPack.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/IndexPack.java @@ -62,7 +62,7 @@ class IndexPack extends TextBuiltin { @Override protected void run() throws Exception { - BufferedInputStream in = new BufferedInputStream(System.in); + BufferedInputStream in = new BufferedInputStream(ins); ObjectInserter inserter = db.newObjectInserter(); try { PackParser p = inserter.newPackParser(in); diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Push.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Push.java index b252de8e6..c7c27b4c4 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Push.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Push.java @@ -161,7 +161,7 @@ class Push extends TextBuiltin { printRefUpdateResult(reader, uri, result, rru); } - AbstractFetchCommand.showRemoteMessages(result.getMessages()); + AbstractFetchCommand.showRemoteMessages(errw, result.getMessages()); if (everythingUpToDate) outw.println(CLIText.get().everythingUpToDate); } diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ReceivePack.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ReceivePack.java index bc8f49716..d7f895a30 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ReceivePack.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ReceivePack.java @@ -76,6 +76,6 @@ class ReceivePack extends TextBuiltin { } rp = new org.eclipse.jgit.transport.ReceivePack(db); - rp.receive(System.in, outs, System.err); + rp.receive(ins, outs, errs); } } diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevWalkTextBuiltin.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevWalkTextBuiltin.java index 847bf7fc1..e23fb356a 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevWalkTextBuiltin.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevWalkTextBuiltin.java @@ -199,10 +199,9 @@ abstract class RevWalkTextBuiltin extends TextBuiltin { final int n = walkLoop(); if (count) { final long end = System.currentTimeMillis(); - System.err.print(n); - System.err.print(' '); - System.err - .println(MessageFormat.format( + errw.print(n); + errw.print(' '); + errw.println(MessageFormat.format( CLIText.get().timeInMilliSeconds, Long.valueOf(end - start))); } diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/TextBuiltin.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/TextBuiltin.java index 7f7ef8d4d..3308fda0e 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/TextBuiltin.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/TextBuiltin.java @@ -50,8 +50,10 @@ import static org.eclipse.jgit.lib.Constants.R_TAGS; import java.io.BufferedWriter; import java.io.FileDescriptor; +import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; @@ -84,6 +86,13 @@ public abstract class TextBuiltin { @Option(name = "--help", usage = "usage_displayThisHelpText", aliases = { "-h" }) private boolean help; + /** + * Input stream, typically this is standard input. + * + * @since 3.4 + */ + protected InputStream ins; + /** * Writer to output to, typically this is standard output. * @@ -106,6 +115,20 @@ public abstract class TextBuiltin { @Deprecated protected PrintWriter out; + /** + * Error writer, typically this is standard error. + * + * @since 3.4 + */ + protected ThrowingPrintWriter errw; + + /** + * Error output stream, typically this is standard error. + * + * @since 3.4 + */ + protected OutputStream errs; + /** Git repository the command was invoked within. */ protected Repository db; @@ -137,16 +160,27 @@ public abstract class TextBuiltin { try { final String outputEncoding = repository != null ? repository .getConfig().getString("i18n", null, "logOutputEncoding") : null; //$NON-NLS-1$ //$NON-NLS-2$ + if (ins == null) + ins = new FileInputStream(FileDescriptor.in); if (outs == null) outs = new FileOutputStream(FileDescriptor.out); - BufferedWriter bufw; + if (errs == null) + errs = new FileOutputStream(FileDescriptor.err); + BufferedWriter outbufw; + if (outputEncoding != null) + outbufw = new BufferedWriter(new OutputStreamWriter(outs, + outputEncoding)); + else + outbufw = new BufferedWriter(new OutputStreamWriter(outs)); + out = new PrintWriter(outbufw); + outw = new ThrowingPrintWriter(outbufw); + BufferedWriter errbufw; if (outputEncoding != null) - bufw = new BufferedWriter(new OutputStreamWriter(outs, + errbufw = new BufferedWriter(new OutputStreamWriter(errs, outputEncoding)); else - bufw = new BufferedWriter(new OutputStreamWriter(outs)); - out = new PrintWriter(bufw); - outw = new ThrowingPrintWriter(bufw); + errbufw = new BufferedWriter(new OutputStreamWriter(errs)); + errw = new ThrowingPrintWriter(errbufw); } catch (IOException e) { throw die(CLIText.get().cannotCreateOutputStream); } @@ -184,14 +218,15 @@ public abstract class TextBuiltin { * * @param args * the arguments supplied on the command line, if any. + * @throws IOException */ - protected void parseArguments(final String[] args) { + protected void parseArguments(final String[] args) throws IOException { final CmdLineParser clp = new CmdLineParser(this); try { clp.parseArgument(args); } catch (CmdLineException err) { if (!help) { - System.err.println(MessageFormat.format(CLIText.get().fatalError, err.getMessage())); + this.errw.println(MessageFormat.format(CLIText.get().fatalError, err.getMessage())); System.exit(1); } } @@ -207,8 +242,9 @@ public abstract class TextBuiltin { * Print the usage line * * @param clp + * @throws IOException */ - public void printUsageAndExit(final CmdLineParser clp) { + public void printUsageAndExit(final CmdLineParser clp) throws IOException { printUsageAndExit("", clp); //$NON-NLS-1$ } @@ -217,20 +253,20 @@ public abstract class TextBuiltin { * * @param message * @param clp + * @throws IOException */ - public void printUsageAndExit(final String message, final CmdLineParser clp) { - PrintWriter writer = new PrintWriter(System.err); - writer.println(message); - writer.print("jgit "); //$NON-NLS-1$ - writer.print(commandName); - clp.printSingleLineUsage(writer, getResourceBundle()); - writer.println(); - - writer.println(); - clp.printUsage(writer, getResourceBundle()); - writer.println(); - - writer.flush(); + public void printUsageAndExit(final String message, final CmdLineParser clp) throws IOException { + errw.println(message); + errw.print("jgit "); //$NON-NLS-1$ + errw.print(commandName); + clp.printSingleLineUsage(errw, getResourceBundle()); + errw.println(); + + errw.println(); + clp.printUsage(errw, getResourceBundle()); + errw.println(); + + errw.flush(); System.exit(1); } diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/UploadPack.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/UploadPack.java index 4ace0aacd..447374d69 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/UploadPack.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/UploadPack.java @@ -82,6 +82,6 @@ class UploadPack extends TextBuiltin { up = new org.eclipse.jgit.transport.UploadPack(db); if (0 <= timeout) up.setTimeout(timeout); - up.upload(System.in, outs, System.err); + up.upload(ins, outs, errs); } } diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/RebuildCommitGraph.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/RebuildCommitGraph.java index cd0236cc0..214093983 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/RebuildCommitGraph.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/RebuildCommitGraph.java @@ -117,7 +117,7 @@ class RebuildCommitGraph extends TextBuiltin { @Override protected void run() throws Exception { if (!really && !db.getRefDatabase().getRefs(ALL).isEmpty()) { - System.err.println( + errw.println( MessageFormat.format(CLIText.get().fatalThisProgramWillDestroyTheRepository , db.getDirectory().getAbsolutePath(), REALLY)); throw die(CLIText.get().needApprovalToDestroyCurrentRepository); @@ -294,7 +294,7 @@ class RebuildCommitGraph extends TextBuiltin { rw.parseAny(id); } catch (MissingObjectException mue) { if (!Constants.TYPE_COMMIT.equals(type)) { - System.err.println(MessageFormat.format(CLIText.get().skippingObject, type, name)); + errw.println(MessageFormat.format(CLIText.get().skippingObject, type, name)); continue; } throw new MissingObjectException(id, type); diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowCommands.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowCommands.java index 4f6d1503b..aa258073b 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowCommands.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowCommands.java @@ -43,14 +43,16 @@ package org.eclipse.jgit.pgm.debug; +import java.io.IOException; import java.net.URL; -import org.kohsuke.args4j.Option; import org.eclipse.jgit.pgm.Command; import org.eclipse.jgit.pgm.CommandCatalog; import org.eclipse.jgit.pgm.CommandRef; import org.eclipse.jgit.pgm.TextBuiltin; import org.eclipse.jgit.pgm.internal.CLIText; +import org.eclipse.jgit.util.io.ThrowingPrintWriter; +import org.kohsuke.args4j.Option; @Command(usage = "usage_displayAListOfAllRegisteredJgitCommands") class ShowCommands extends TextBuiltin { @@ -67,39 +69,39 @@ class ShowCommands extends TextBuiltin { width += 2; for (final CommandRef c : list) { - System.err.print(c.isCommon() ? '*' : ' '); - System.err.print(' '); + errw.print(c.isCommon() ? '*' : ' '); + errw.print(' '); - System.err.print(c.getName()); + errw.print(c.getName()); for (int i = c.getName().length(); i < width; i++) - System.err.print(' '); + errw.print(' '); - pretty.print(c); - System.err.println(); + pretty.print(errw, c); + errw.println(); } - System.err.println(); + errw.println(); } static enum Format { /** */ USAGE { - void print(final CommandRef c) { + void print(ThrowingPrintWriter err, final CommandRef c) throws IOException { String usage = c.getUsage(); if (usage != null && usage.length() > 0) - System.err.print(CLIText.get().resourceBundle().getString(usage)); + err.print(CLIText.get().resourceBundle().getString(usage)); } }, /** */ CLASSES { - void print(final CommandRef c) { - System.err.print(c.getImplementationClassName()); + void print(ThrowingPrintWriter err, final CommandRef c) throws IOException { + err.print(c.getImplementationClassName()); } }, /** */ URLS { - void print(final CommandRef c) { + void print(ThrowingPrintWriter err, final CommandRef c) throws IOException { final ClassLoader ldr = c.getImplementationClassLoader(); String cn = c.getImplementationClassName(); @@ -107,7 +109,7 @@ class ShowCommands extends TextBuiltin { final URL url = ldr.getResource(cn); if (url == null) { - System.err.print(CLIText.get().notFound); + err.print(CLIText.get().notFound); return; } @@ -115,10 +117,10 @@ class ShowCommands extends TextBuiltin { if (rn.endsWith(cn)) rn = rn.substring(0, rn.length() - cn.length()); - System.err.print(rn); + err.print(rn); } }; - abstract void print(CommandRef c); + abstract void print(ThrowingPrintWriter err, CommandRef c) throws IOException; } }