Last active
March 12, 2016 01:30
-
-
Save nedtwigg/54ceb8a9b5498ca04fb1 to your computer and use it in GitHub Desktop.
A way to call JGit commands and stream their output.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.File; | |
import java.io.OutputStream; | |
import java.nio.charset.Charset; | |
import java.util.ArrayList; | |
import java.util.List; | |
import java.util.Optional; | |
import org.eclipse.jgit.lib.Repository; | |
import org.eclipse.jgit.pgm.TextBuiltin; | |
import org.eclipse.jgit.pgm.opt.CmdLineParser; | |
import org.eclipse.jgit.pgm.opt.SubcommandHandler; | |
import org.kohsuke.args4j.Argument; | |
import com.diffplug.common.base.Either; | |
public class GitCliJGitWrapper { | |
/** Returns the output encoding for the given repository. */ | |
public static Charset getOutputEncoding(Optional<Repository> db) { | |
return db.map(d -> d.getConfig().getString("i18n", null, "logOutputEncoding")) | |
.map(Charset::forName).orElseGet(Charset::defaultCharset); | |
} | |
public static void rawExecute(String str, Either<Repository, File> repoOrFolder, OutputStream outputStream, OutputStream errorStream) throws Exception { | |
// either db or gitDir will be null | |
String[] args = split(str); | |
if (!args[0].equalsIgnoreCase("git") || args.length < 2) { //$NON-NLS-1$ | |
throw new IllegalArgumentException("Expected 'git <command> [<args>]', was:" + str); //$NON-NLS-1$ | |
} | |
String[] argv = new String[args.length - 1]; | |
System.arraycopy(args, 1, argv, 0, args.length - 1); | |
Streaming bean = new Streaming(); | |
final CmdLineParser clp = new CmdLineParser(bean); | |
clp.parseArgument(argv); | |
final TextBuiltin cmd = bean.subcommand; | |
cmd.outs = outputStream; | |
cmd.errs = errorStream; | |
cmd.init(repoOrFolder.asOptionalLeft().orElse(null), repoOrFolder.asOptionalRight().map(File::getAbsolutePath).orElse(null)); | |
try { | |
cmd.execute(bean.arguments.toArray(new String[bean.arguments.size()])); | |
} finally { | |
if (cmd.outw != null) { | |
cmd.outw.flush(); | |
} | |
if (cmd.errw != null) { | |
cmd.errw.flush(); | |
} | |
} | |
} | |
/** Command line entry point for streaming the command output. */ | |
private static class Streaming { | |
@Argument(index = 0, metaVar = "metaVar_command", required = true, handler = SubcommandHandler.class) | |
private TextBuiltin subcommand; | |
@Argument(index = 1, metaVar = "metaVar_arg") | |
private List<String> arguments = new ArrayList<String>(); | |
} | |
/** | |
* Split a command line into a string array. | |
* | |
* A copy of Gerrit's | |
* com.google.gerrit.sshd.CommandFactoryProvider#split(String) | |
* | |
* @param commandLine | |
* a command line | |
* @return the array | |
*/ | |
static String[] split(String commandLine) { | |
final List<String> list = new ArrayList<String>(); | |
boolean inquote = false; | |
boolean inDblQuote = false; | |
StringBuilder r = new StringBuilder(); | |
for (int ip = 0; ip < commandLine.length();) { | |
final char b = commandLine.charAt(ip++); | |
switch (b) { | |
case '\t': | |
case ' ': | |
if (inquote || inDblQuote) { | |
r.append(b); | |
} else if (r.length() > 0) { | |
list.add(r.toString()); | |
r = new StringBuilder(); | |
} | |
continue; | |
case '\"': | |
if (inquote) { | |
r.append(b); | |
} else { | |
inDblQuote = !inDblQuote; | |
} | |
continue; | |
case '\'': | |
if (inDblQuote) { | |
r.append(b); | |
} else { | |
inquote = !inquote; | |
} | |
continue; | |
default: | |
r.append(b); | |
continue; | |
} | |
} | |
if (r.length() > 0) { | |
list.add(r.toString()); | |
} | |
return list.toArray(new String[list.size()]); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment