Currently execution of tests in pgm uses CLIGitCommand which re-implements few things from Main. Unfortunately this can results in a different test behavior compared to the real CLI runtime. The change let CLIGitCommand extend Main and only slightly modifies the runtime (stream redirection and undesired exit() termination). Change-Id: I87b7b61d1c84a89e5917610d84409f01be90b70b Signed-off-by: Andrey Loskutov <loskutov@gmx.de>tags/v4.2.0.201601211800-r
@@ -54,7 +54,8 @@ import java.util.List; | |||
import org.eclipse.jgit.junit.JGitTestUtil; | |||
import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase; | |||
import org.eclipse.jgit.pgm.CLIGitCommand; | |||
import org.eclipse.jgit.pgm.Die; | |||
import org.eclipse.jgit.pgm.CLIGitCommand.Result; | |||
import org.eclipse.jgit.pgm.TextBuiltin.TerminatedByHelpException; | |||
import org.junit.Before; | |||
public class CLIRepositoryTestCase extends LocalDiskRepositoryTestCase { | |||
@@ -84,7 +85,7 @@ public class CLIRepositoryTestCase extends LocalDiskRepositoryTestCase { | |||
protected String[] executeUnchecked(String... cmds) throws Exception { | |||
List<String> result = new ArrayList<String>(cmds.length); | |||
for (String cmd : cmds) { | |||
result.addAll(CLIGitCommand.execute(cmd, db)); | |||
result.addAll(CLIGitCommand.executeUnchecked(cmd, db)); | |||
} | |||
return result.toArray(new String[0]); | |||
} | |||
@@ -102,11 +103,13 @@ public class CLIRepositoryTestCase extends LocalDiskRepositoryTestCase { | |||
protected String[] execute(String... cmds) throws Exception { | |||
List<String> result = new ArrayList<String>(cmds.length); | |||
for (String cmd : cmds) { | |||
List<String> out = CLIGitCommand.execute(cmd, db); | |||
if (contains(out, "fatal: ")) { | |||
throw new Die(toString(out)); | |||
Result r = CLIGitCommand.executeRaw(cmd, db); | |||
if (r.ex instanceof TerminatedByHelpException) { | |||
result.addAll(r.errLines()); | |||
} else if (r.ex != null) { | |||
throw r.ex; | |||
} | |||
result.addAll(out); | |||
result.addAll(r.outLines()); | |||
} | |||
return result.toArray(new String[0]); | |||
} |
@@ -42,33 +42,31 @@ | |||
*/ | |||
package org.eclipse.jgit.pgm; | |||
import static org.junit.Assert.assertNull; | |||
import java.io.ByteArrayOutputStream; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.io.PrintWriter; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import org.eclipse.jgit.internal.storage.file.FileRepository; | |||
import org.eclipse.jgit.lib.Repository; | |||
import org.eclipse.jgit.pgm.TextBuiltin.TerminatedByHelpException; | |||
import org.eclipse.jgit.pgm.internal.CLIText; | |||
import org.eclipse.jgit.pgm.opt.CmdLineParser; | |||
import org.eclipse.jgit.pgm.opt.SubcommandHandler; | |||
import org.eclipse.jgit.util.IO; | |||
import org.kohsuke.args4j.Argument; | |||
public class CLIGitCommand { | |||
@Argument(index = 0, metaVar = "metaVar_command", required = true, handler = SubcommandHandler.class) | |||
private TextBuiltin subcommand; | |||
public class CLIGitCommand extends Main { | |||
@Argument(index = 1, metaVar = "metaVar_arg") | |||
private List<String> arguments = new ArrayList<String>(); | |||
private final Result result; | |||
public TextBuiltin getSubcommand() { | |||
return subcommand; | |||
} | |||
private final Repository db; | |||
public List<String> getArguments() { | |||
return arguments; | |||
public CLIGitCommand(Repository db) { | |||
super(); | |||
this.db = db; | |||
result = new Result(); | |||
} | |||
/** | |||
@@ -102,57 +100,82 @@ public class CLIGitCommand { | |||
public static List<String> execute(String str, Repository db) | |||
throws Exception { | |||
Result result = executeRaw(str, db); | |||
return getOutput(result); | |||
} | |||
public static Result executeRaw(String str, Repository db) | |||
throws Exception { | |||
CLIGitCommand cmd = new CLIGitCommand(db); | |||
cmd.run(str); | |||
return cmd.result; | |||
} | |||
public static List<String> executeUnchecked(String str, Repository db) | |||
throws Exception { | |||
CLIGitCommand cmd = new CLIGitCommand(db); | |||
try { | |||
cmd.run(str); | |||
return getOutput(cmd.result); | |||
} catch (Throwable e) { | |||
return cmd.result.errLines(); | |||
} | |||
} | |||
private static List<String> getOutput(Result result) { | |||
if (result.ex instanceof TerminatedByHelpException) { | |||
return result.errLines(); | |||
} | |||
return result.outLines(); | |||
} | |||
private void run(String commandLine) throws Exception { | |||
String[] argv = convertToMainArgs(commandLine); | |||
try { | |||
return IO.readLines(new String(rawExecute(str, db))); | |||
} catch (Die e) { | |||
return IO.readLines(CLIText.fatalError(e.getMessage())); | |||
super.run(argv); | |||
} catch (TerminatedByHelpException e) { | |||
// this is not a failure, super called exit() on help | |||
} finally { | |||
writer.flush(); | |||
} | |||
} | |||
public static byte[] rawExecute(String str, Repository db) | |||
private static String[] convertToMainArgs(String str) | |||
throws Exception { | |||
String[] args = split(str); | |||
if (!args[0].equalsIgnoreCase("git") || args.length < 2) | |||
if (!args[0].equalsIgnoreCase("git") || args.length < 2) { | |||
throw new IllegalArgumentException( | |||
"Expected 'git <command> [<args>]', was:" + str); | |||
} | |||
String[] argv = new String[args.length - 1]; | |||
System.arraycopy(args, 1, argv, 0, args.length - 1); | |||
return argv; | |||
} | |||
CLIGitCommand bean = new CLIGitCommand(); | |||
final CmdLineParser clp = new TestCmdLineParser(bean); | |||
clp.parseArgument(argv); | |||
final TextBuiltin cmd = bean.getSubcommand(); | |||
ByteArrayOutputStream baos = new ByteArrayOutputStream(); | |||
cmd.outs = baos; | |||
ByteArrayOutputStream errs = new ByteArrayOutputStream(); | |||
cmd.errs = errs; | |||
boolean seenHelp = TextBuiltin.containsHelp(argv); | |||
if (cmd.requiresRepository()) | |||
cmd.init(db, null); | |||
else | |||
cmd.init(null, null); | |||
try { | |||
cmd.execute(bean.getArguments().toArray( | |||
new String[bean.getArguments().size()])); | |||
} catch (TerminatedByHelpException e) { | |||
seenHelp = true; | |||
// this is not a failure, command execution should just not happen | |||
} finally { | |||
if (cmd.outw != null) { | |||
cmd.outw.flush(); | |||
} | |||
if (cmd.errw != null) { | |||
cmd.errw.flush(); | |||
} | |||
if (seenHelp) { | |||
return errs.toByteArray(); | |||
} else if (errs.size() > 0) { | |||
// forward the errors to the standard err | |||
System.err.print(errs.toString()); | |||
} | |||
@Override | |||
PrintWriter createErrorWriter() { | |||
return new PrintWriter(result.err); | |||
} | |||
void init(final TextBuiltin cmd) throws IOException { | |||
cmd.outs = result.out; | |||
cmd.errs = result.err; | |||
super.init(cmd); | |||
} | |||
@Override | |||
protected Repository openGitDir(String aGitdir) throws IOException { | |||
assertNull(aGitdir); | |||
return db; | |||
} | |||
@Override | |||
void exit(int status, Exception t) throws Exception { | |||
if (t == null) { | |||
t = new IllegalStateException(Integer.toString(status)); | |||
} | |||
return baos.toByteArray(); | |||
result.ex = t; | |||
throw t; | |||
} | |||
/** | |||
@@ -210,14 +233,36 @@ public class CLIGitCommand { | |||
return list.toArray(new String[list.size()]); | |||
} | |||
static class TestCmdLineParser extends CmdLineParser { | |||
public TestCmdLineParser(Object bean) { | |||
super(bean); | |||
public static class Result { | |||
public final ByteArrayOutputStream out = new ByteArrayOutputStream(); | |||
public final ByteArrayOutputStream err = new ByteArrayOutputStream(); | |||
public Exception ex; | |||
public byte[] outBytes() { | |||
return out.toByteArray(); | |||
} | |||
public byte[] errBytes() { | |||
return err.toByteArray(); | |||
} | |||
public String outString() { | |||
return out.toString(); | |||
} | |||
@Override | |||
protected boolean containsHelp(String... args) { | |||
return false; | |||
public List<String> outLines() { | |||
return IO.readLines(out.toString()); | |||
} | |||
public String errString() { | |||
return err.toString(); | |||
} | |||
public List<String> errLines() { | |||
return IO.readLines(err.toString()); | |||
} | |||
} | |||
} |
@@ -87,21 +87,22 @@ public class ArchiveTest extends CLIRepositoryTestCase { | |||
@Test | |||
public void testEmptyArchive() throws Exception { | |||
byte[] result = CLIGitCommand.rawExecute( | |||
"git archive --format=zip " + emptyTree, db); | |||
byte[] result = CLIGitCommand.executeRaw( | |||
"git archive --format=zip " + emptyTree, db).outBytes(); | |||
assertArrayEquals(new String[0], listZipEntries(result)); | |||
} | |||
@Test | |||
public void testEmptyTar() throws Exception { | |||
byte[] result = CLIGitCommand.rawExecute( | |||
"git archive --format=tar " + emptyTree, db); | |||
byte[] result = CLIGitCommand.executeRaw( | |||
"git archive --format=tar " + emptyTree, db).outBytes(); | |||
assertArrayEquals(new String[0], listTarEntries(result)); | |||
} | |||
@Test | |||
public void testUnrecognizedFormat() throws Exception { | |||
String[] expect = new String[] { "fatal: Unknown archive format 'nonsense'" }; | |||
String[] expect = new String[] { | |||
"fatal: Unknown archive format 'nonsense'", "" }; | |||
String[] actual = executeUnchecked( | |||
"git archive --format=nonsense " + emptyTree); | |||
assertArrayEquals(expect, actual); | |||
@@ -116,8 +117,8 @@ public class ArchiveTest extends CLIRepositoryTestCase { | |||
git.add().addFilepattern("c").call(); | |||
git.commit().setMessage("populate toplevel").call(); | |||
byte[] result = CLIGitCommand.rawExecute( | |||
"git archive --format=zip HEAD", db); | |||
byte[] result = CLIGitCommand.executeRaw( | |||
"git archive --format=zip HEAD", db).outBytes(); | |||
assertArrayEquals(new String[] { "a", "c" }, | |||
listZipEntries(result)); | |||
} | |||
@@ -131,8 +132,8 @@ public class ArchiveTest extends CLIRepositoryTestCase { | |||
@Test | |||
public void testDefaultFormatIsTar() throws Exception { | |||
commitGreeting(); | |||
byte[] result = CLIGitCommand.rawExecute( | |||
"git archive HEAD", db); | |||
byte[] result = CLIGitCommand.executeRaw( | |||
"git archive HEAD", db).outBytes(); | |||
assertArrayEquals(new String[] { "greeting" }, | |||
listTarEntries(result)); | |||
} | |||
@@ -298,8 +299,8 @@ public class ArchiveTest extends CLIRepositoryTestCase { | |||
git.add().addFilepattern("b").call(); | |||
git.commit().setMessage("add subdir").call(); | |||
byte[] result = CLIGitCommand.rawExecute( | |||
"git archive --format=zip master", db); | |||
byte[] result = CLIGitCommand.executeRaw( | |||
"git archive --format=zip master", db).outBytes(); | |||
String[] expect = { "a", "b.c", "b0c", "b/", "b/a", "b/b", "c" }; | |||
String[] actual = listZipEntries(result); | |||
@@ -324,8 +325,8 @@ public class ArchiveTest extends CLIRepositoryTestCase { | |||
git.add().addFilepattern("b").call(); | |||
git.commit().setMessage("add subdir").call(); | |||
byte[] result = CLIGitCommand.rawExecute( | |||
"git archive --format=tar master", db); | |||
byte[] result = CLIGitCommand.executeRaw( | |||
"git archive --format=tar master", db).outBytes(); | |||
String[] expect = { "a", "b.c", "b0c", "b/", "b/a", "b/b", "c" }; | |||
String[] actual = listTarEntries(result); | |||
@@ -345,8 +346,8 @@ public class ArchiveTest extends CLIRepositoryTestCase { | |||
@Test | |||
public void testArchivePrefixOption() throws Exception { | |||
commitBazAndFooSlashBar(); | |||
byte[] result = CLIGitCommand.rawExecute( | |||
"git archive --prefix=x/ --format=zip master", db); | |||
byte[] result = CLIGitCommand.executeRaw( | |||
"git archive --prefix=x/ --format=zip master", db).outBytes(); | |||
String[] expect = { "x/baz", "x/foo/", "x/foo/bar" }; | |||
String[] actual = listZipEntries(result); | |||
@@ -358,8 +359,8 @@ public class ArchiveTest extends CLIRepositoryTestCase { | |||
@Test | |||
public void testTarPrefixOption() throws Exception { | |||
commitBazAndFooSlashBar(); | |||
byte[] result = CLIGitCommand.rawExecute( | |||
"git archive --prefix=x/ --format=tar master", db); | |||
byte[] result = CLIGitCommand.executeRaw( | |||
"git archive --prefix=x/ --format=tar master", db).outBytes(); | |||
String[] expect = { "x/baz", "x/foo/", "x/foo/bar" }; | |||
String[] actual = listTarEntries(result); | |||
@@ -377,8 +378,8 @@ public class ArchiveTest extends CLIRepositoryTestCase { | |||
@Test | |||
public void testPrefixDoesNotNormalizeDoubleSlash() throws Exception { | |||
commitFoo(); | |||
byte[] result = CLIGitCommand.rawExecute( | |||
"git archive --prefix=x// --format=zip master", db); | |||
byte[] result = CLIGitCommand.executeRaw( | |||
"git archive --prefix=x// --format=zip master", db).outBytes(); | |||
String[] expect = { "x//foo" }; | |||
assertArrayEquals(expect, listZipEntries(result)); | |||
} | |||
@@ -386,8 +387,8 @@ public class ArchiveTest extends CLIRepositoryTestCase { | |||
@Test | |||
public void testPrefixDoesNotNormalizeDoubleSlashInTar() throws Exception { | |||
commitFoo(); | |||
byte[] result = CLIGitCommand.rawExecute( | |||
"git archive --prefix=x// --format=tar master", db); | |||
byte[] result = CLIGitCommand.executeRaw( | |||
"git archive --prefix=x// --format=tar master", db).outBytes(); | |||
String[] expect = { "x//foo" }; | |||
assertArrayEquals(expect, listTarEntries(result)); | |||
} | |||
@@ -404,8 +405,8 @@ public class ArchiveTest extends CLIRepositoryTestCase { | |||
@Test | |||
public void testPrefixWithoutTrailingSlash() throws Exception { | |||
commitBazAndFooSlashBar(); | |||
byte[] result = CLIGitCommand.rawExecute( | |||
"git archive --prefix=my- --format=zip master", db); | |||
byte[] result = CLIGitCommand.executeRaw( | |||
"git archive --prefix=my- --format=zip master", db).outBytes(); | |||
String[] expect = { "my-baz", "my-foo/", "my-foo/bar" }; | |||
String[] actual = listZipEntries(result); | |||
@@ -417,8 +418,8 @@ public class ArchiveTest extends CLIRepositoryTestCase { | |||
@Test | |||
public void testTarPrefixWithoutTrailingSlash() throws Exception { | |||
commitBazAndFooSlashBar(); | |||
byte[] result = CLIGitCommand.rawExecute( | |||
"git archive --prefix=my- --format=tar master", db); | |||
byte[] result = CLIGitCommand.executeRaw( | |||
"git archive --prefix=my- --format=tar master", db).outBytes(); | |||
String[] expect = { "my-baz", "my-foo/", "my-foo/bar" }; | |||
String[] actual = listTarEntries(result); | |||
@@ -437,8 +438,8 @@ public class ArchiveTest extends CLIRepositoryTestCase { | |||
git.submoduleAdd().setURI("./.").setPath("b").call().close(); | |||
git.commit().setMessage("add submodule").call(); | |||
byte[] result = CLIGitCommand.rawExecute( | |||
"git archive --format=zip master", db); | |||
byte[] result = CLIGitCommand.executeRaw( | |||
"git archive --format=zip master", db).outBytes(); | |||
String[] expect = { ".gitmodules", "a", "b/", "c" }; | |||
String[] actual = listZipEntries(result); | |||
@@ -457,8 +458,8 @@ public class ArchiveTest extends CLIRepositoryTestCase { | |||
git.submoduleAdd().setURI("./.").setPath("b").call().close(); | |||
git.commit().setMessage("add submodule").call(); | |||
byte[] result = CLIGitCommand.rawExecute( | |||
"git archive --format=tar master", db); | |||
byte[] result = CLIGitCommand.executeRaw( | |||
"git archive --format=tar master", db).outBytes(); | |||
String[] expect = { ".gitmodules", "a", "b/", "c" }; | |||
String[] actual = listTarEntries(result); | |||
@@ -487,8 +488,8 @@ public class ArchiveTest extends CLIRepositoryTestCase { | |||
git.commit().setMessage("three files with different modes").call(); | |||
byte[] zipData = CLIGitCommand.rawExecute( | |||
"git archive --format=zip master", db); | |||
byte[] zipData = CLIGitCommand.executeRaw( | |||
"git archive --format=zip master", db).outBytes(); | |||
writeRaw("zip-with-modes.zip", zipData); | |||
assertContainsEntryWithMode("zip-with-modes.zip", "-rw-", "plain"); | |||
assertContainsEntryWithMode("zip-with-modes.zip", "-rwx", "executable"); | |||
@@ -516,8 +517,8 @@ public class ArchiveTest extends CLIRepositoryTestCase { | |||
git.commit().setMessage("three files with different modes").call(); | |||
byte[] archive = CLIGitCommand.rawExecute( | |||
"git archive --format=tar master", db); | |||
byte[] archive = CLIGitCommand.executeRaw( | |||
"git archive --format=tar master", db).outBytes(); | |||
writeRaw("with-modes.tar", archive); | |||
assertTarContainsEntry("with-modes.tar", "-rw-r--r--", "plain"); | |||
assertTarContainsEntry("with-modes.tar", "-rwxr-xr-x", "executable"); | |||
@@ -539,8 +540,8 @@ public class ArchiveTest extends CLIRepositoryTestCase { | |||
git.add().addFilepattern("1234567890").call(); | |||
git.commit().setMessage("file with long name").call(); | |||
byte[] result = CLIGitCommand.rawExecute( | |||
"git archive --format=zip HEAD", db); | |||
byte[] result = CLIGitCommand.executeRaw( | |||
"git archive --format=zip HEAD", db).outBytes(); | |||
assertArrayEquals(l.toArray(new String[l.size()]), | |||
listZipEntries(result)); | |||
} | |||
@@ -559,8 +560,8 @@ public class ArchiveTest extends CLIRepositoryTestCase { | |||
git.add().addFilepattern("1234567890").call(); | |||
git.commit().setMessage("file with long name").call(); | |||
byte[] result = CLIGitCommand.rawExecute( | |||
"git archive --format=tar HEAD", db); | |||
byte[] result = CLIGitCommand.executeRaw( | |||
"git archive --format=tar HEAD", db).outBytes(); | |||
assertArrayEquals(l.toArray(new String[l.size()]), | |||
listTarEntries(result)); | |||
} | |||
@@ -572,8 +573,8 @@ public class ArchiveTest extends CLIRepositoryTestCase { | |||
git.add().addFilepattern("xyzzy").call(); | |||
git.commit().setMessage("add file with content").call(); | |||
byte[] result = CLIGitCommand.rawExecute( | |||
"git archive --format=zip HEAD", db); | |||
byte[] result = CLIGitCommand.executeRaw( | |||
"git archive --format=zip HEAD", db).outBytes(); | |||
assertArrayEquals(new String[] { payload }, | |||
zipEntryContent(result, "xyzzy")); | |||
} | |||
@@ -585,8 +586,8 @@ public class ArchiveTest extends CLIRepositoryTestCase { | |||
git.add().addFilepattern("xyzzy").call(); | |||
git.commit().setMessage("add file with content").call(); | |||
byte[] result = CLIGitCommand.rawExecute( | |||
"git archive --format=tar HEAD", db); | |||
byte[] result = CLIGitCommand.executeRaw( | |||
"git archive --format=tar HEAD", db).outBytes(); | |||
assertArrayEquals(new String[] { payload }, | |||
tarEntryContent(result, "xyzzy")); | |||
} |
@@ -90,14 +90,23 @@ public class Main { | |||
@Argument(index = 1, metaVar = "metaVar_arg") | |||
private List<String> arguments = new ArrayList<String>(); | |||
PrintWriter writer; | |||
/** | |||
* | |||
*/ | |||
public Main() { | |||
HttpTransport.setConnectionFactory(new HttpClientConnectionFactory()); | |||
} | |||
/** | |||
* Execute the command line. | |||
* | |||
* @param argv | |||
* arguments. | |||
* @throws Exception | |||
*/ | |||
public static void main(final String[] argv) { | |||
HttpTransport.setConnectionFactory(new HttpClientConnectionFactory()); | |||
public static void main(final String[] argv) throws Exception { | |||
new Main().run(argv); | |||
} | |||
@@ -116,8 +125,10 @@ public class Main { | |||
* | |||
* @param argv | |||
* arguments. | |||
* @throws Exception | |||
*/ | |||
protected void run(final String[] argv) { | |||
protected void run(final String[] argv) throws Exception { | |||
writer = createErrorWriter(); | |||
try { | |||
if (!installConsole()) { | |||
AwtAuthenticator.install(); | |||
@@ -126,12 +137,14 @@ public class Main { | |||
configureHttpProxy(); | |||
execute(argv); | |||
} catch (Die err) { | |||
if (err.isAborted()) | |||
System.exit(1); | |||
System.err.println(CLIText.fatalError(err.getMessage())); | |||
if (showStackTrace) | |||
err.printStackTrace(); | |||
System.exit(128); | |||
if (err.isAborted()) { | |||
exit(1, err); | |||
} | |||
writer.println(CLIText.fatalError(err.getMessage())); | |||
if (showStackTrace) { | |||
err.printStackTrace(writer); | |||
} | |||
exit(128, err); | |||
} catch (Exception err) { | |||
// Try to detect errno == EPIPE and exit normally if that happens | |||
// There may be issues with operating system versions and locale, | |||
@@ -139,46 +152,54 @@ public class Main { | |||
// under other circumstances. | |||
if (err.getClass() == IOException.class) { | |||
// Linux, OS X | |||
if (err.getMessage().equals("Broken pipe")) //$NON-NLS-1$ | |||
System.exit(0); | |||
if (err.getMessage().equals("Broken pipe")) { //$NON-NLS-1$ | |||
exit(0, err); | |||
} | |||
// Windows | |||
if (err.getMessage().equals("The pipe is being closed")) //$NON-NLS-1$ | |||
System.exit(0); | |||
if (err.getMessage().equals("The pipe is being closed")) { //$NON-NLS-1$ | |||
exit(0, err); | |||
} | |||
} | |||
if (!showStackTrace && err.getCause() != null | |||
&& err instanceof TransportException) | |||
System.err.println(CLIText.fatalError(err.getCause().getMessage())); | |||
&& err instanceof TransportException) { | |||
writer.println(CLIText.fatalError(err.getCause().getMessage())); | |||
} | |||
if (err.getClass().getName().startsWith("org.eclipse.jgit.errors.")) { //$NON-NLS-1$ | |||
System.err.println(CLIText.fatalError(err.getMessage())); | |||
if (showStackTrace) | |||
writer.println(CLIText.fatalError(err.getMessage())); | |||
if (showStackTrace) { | |||
err.printStackTrace(); | |||
System.exit(128); | |||
} | |||
exit(128, err); | |||
} | |||
err.printStackTrace(); | |||
System.exit(1); | |||
exit(1, err); | |||
} | |||
if (System.out.checkError()) { | |||
System.err.println(CLIText.get().unknownIoErrorStdout); | |||
System.exit(1); | |||
writer.println(CLIText.get().unknownIoErrorStdout); | |||
exit(1, null); | |||
} | |||
if (System.err.checkError()) { | |||
if (writer.checkError()) { | |||
// No idea how to present an error here, most likely disk full or | |||
// broken pipe | |||
System.exit(1); | |||
exit(1, null); | |||
} | |||
} | |||
PrintWriter createErrorWriter() { | |||
return new PrintWriter(System.err); | |||
} | |||
private void execute(final String[] argv) throws Exception { | |||
final CmdLineParser clp = new SubcommandLineParser(this); | |||
PrintWriter writer = new PrintWriter(System.err); | |||
try { | |||
clp.parseArgument(argv); | |||
} catch (CmdLineException err) { | |||
if (argv.length > 0 && !help && !version) { | |||
writer.println(CLIText.fatalError(err.getMessage())); | |||
writer.flush(); | |||
System.exit(1); | |||
exit(1, err); | |||
} | |||
} | |||
@@ -194,22 +215,24 @@ public class Main { | |||
writer.println(CLIText.get().mostCommonlyUsedCommandsAre); | |||
final CommandRef[] common = CommandCatalog.common(); | |||
int width = 0; | |||
for (final CommandRef c : common) | |||
for (final CommandRef c : common) { | |||
width = Math.max(width, c.getName().length()); | |||
} | |||
width += 2; | |||
for (final CommandRef c : common) { | |||
writer.print(' '); | |||
writer.print(c.getName()); | |||
for (int i = c.getName().length(); i < width; i++) | |||
for (int i = c.getName().length(); i < width; i++) { | |||
writer.print(' '); | |||
} | |||
writer.print(CLIText.get().resourceBundle().getString(c.getUsage())); | |||
writer.println(); | |||
} | |||
writer.println(); | |||
} | |||
writer.flush(); | |||
System.exit(1); | |||
exit(1, null); | |||
} | |||
if (version) { | |||
@@ -218,20 +241,38 @@ public class Main { | |||
} | |||
final TextBuiltin cmd = subcommand; | |||
if (cmd.requiresRepository()) | |||
cmd.init(openGitDir(gitdir), null); | |||
else | |||
cmd.init(null, gitdir); | |||
init(cmd); | |||
try { | |||
cmd.execute(arguments.toArray(new String[arguments.size()])); | |||
} finally { | |||
if (cmd.outw != null) | |||
if (cmd.outw != null) { | |||
cmd.outw.flush(); | |||
if (cmd.errw != null) | |||
} | |||
if (cmd.errw != null) { | |||
cmd.errw.flush(); | |||
} | |||
} | |||
} | |||
void init(final TextBuiltin cmd) throws IOException { | |||
if (cmd.requiresRepository()) { | |||
cmd.init(openGitDir(gitdir), null); | |||
} else { | |||
cmd.init(null, gitdir); | |||
} | |||
} | |||
/** | |||
* @param status | |||
* @param t | |||
* can be {@code null} | |||
* @throws Exception | |||
*/ | |||
void exit(int status, Exception t) throws Exception { | |||
writer.flush(); | |||
System.exit(status); | |||
} | |||
/** | |||
* Evaluate the {@code --git-dir} option and open the repository. | |||
* | |||
@@ -281,7 +322,7 @@ public class Main { | |||
throws IllegalAccessException, InvocationTargetException, | |||
NoSuchMethodException, ClassNotFoundException { | |||
try { | |||
Class.forName(name).getMethod("install").invoke(null); //$NON-NLS-1$ | |||
Class.forName(name).getMethod("install").invoke(null); //$NON-NLS-1$ | |||
} catch (InvocationTargetException e) { | |||
if (e.getCause() instanceof RuntimeException) | |||
throw (RuntimeException) e.getCause(); |