1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 package org.eclipse.jgit.pgm;
44
45 import static java.nio.charset.StandardCharsets.UTF_8;
46 import static org.junit.Assert.assertNull;
47
48 import java.io.ByteArrayOutputStream;
49 import java.io.File;
50 import java.io.IOException;
51 import java.io.OutputStreamWriter;
52 import java.io.PrintWriter;
53 import java.util.ArrayList;
54 import java.util.List;
55
56 import org.eclipse.jgit.internal.storage.file.FileRepository;
57 import org.eclipse.jgit.lib.Repository;
58 import org.eclipse.jgit.pgm.TextBuiltin.TerminatedByHelpException;
59 import org.eclipse.jgit.util.IO;
60
61 public class CLIGitCommand extends Main {
62
63 private final Result result;
64
65 private final Repository db;
66
67 public CLIGitCommand(Repository db) {
68 super();
69 this.db = db;
70 result = new Result();
71 }
72
73
74
75
76
77
78
79
80
81
82
83
84 public static void main(String[] args) throws Exception {
85 String workDir = System.getProperty("git_work_tree");
86 if (workDir == null) {
87 workDir = ".";
88 System.out.println(
89 "System property 'git_work_tree' not specified, using current directory: "
90 + new File(workDir).getAbsolutePath());
91 }
92 try (Repository db = new FileRepository(workDir + "/.git")) {
93 for (String cmd : args) {
94 List<String> result = execute(cmd, db);
95 for (String line : result) {
96 System.out.println(line);
97 }
98 }
99 }
100 }
101
102 public static List<String> execute(String str, Repository db)
103 throws Exception {
104 Result result = executeRaw(str, db);
105 return getOutput(result);
106 }
107
108 public static Result executeRaw(String str, Repository db)
109 throws Exception {
110 CLIGitCommand cmd = new CLIGitCommand(db);
111 cmd.run(str);
112 return cmd.result;
113 }
114
115 public static List<String> executeUnchecked(String str, Repository db)
116 throws Exception {
117 CLIGitCommand cmd = new CLIGitCommand(db);
118 try {
119 cmd.run(str);
120 return getOutput(cmd.result);
121 } catch (Throwable e) {
122 return cmd.result.errLines();
123 }
124 }
125
126 private static List<String> getOutput(Result result) {
127 if (result.ex instanceof TerminatedByHelpException) {
128 return result.errLines();
129 }
130 return result.outLines();
131 }
132
133 private void run(String commandLine) throws Exception {
134 String[] argv = convertToMainArgs(commandLine);
135 try {
136 super.run(argv);
137 } catch (TerminatedByHelpException e) {
138
139 } finally {
140 writer.flush();
141 }
142 }
143
144 private static String[] convertToMainArgs(String str)
145 throws Exception {
146 String[] args = split(str);
147 if (!args[0].equalsIgnoreCase("git") || args.length < 2) {
148 throw new IllegalArgumentException(
149 "Expected 'git <command> [<args>]', was:" + str);
150 }
151 String[] argv = new String[args.length - 1];
152 System.arraycopy(args, 1, argv, 0, args.length - 1);
153 return argv;
154 }
155
156 @Override
157 PrintWriter createErrorWriter() {
158 return new PrintWriter(new OutputStreamWriter(
159 result.err, UTF_8));
160 }
161
162 @Override
163 void init(TextBuiltin cmd) throws IOException {
164 cmd.outs = result.out;
165 cmd.errs = result.err;
166 super.init(cmd);
167 }
168
169 @Override
170 protected Repository openGitDir(String aGitdir) throws IOException {
171 assertNull(aGitdir);
172 return db;
173 }
174
175 @Override
176 void exit(int status, Exception t) throws Exception {
177 if (t == null) {
178 t = new IllegalStateException(Integer.toString(status));
179 }
180 result.ex = t;
181 throw t;
182 }
183
184
185
186
187
188
189
190
191
192
193
194 static String[] split(String commandLine) {
195 final List<String> list = new ArrayList<>();
196 boolean inquote = false;
197 boolean inDblQuote = false;
198 StringBuilder r = new StringBuilder();
199 for (int ip = 0; ip < commandLine.length();) {
200 final char b = commandLine.charAt(ip++);
201 switch (b) {
202 case '\t':
203 case ' ':
204 if (inquote || inDblQuote)
205 r.append(b);
206 else if (r.length() > 0) {
207 list.add(r.toString());
208 r = new StringBuilder();
209 }
210 continue;
211 case '\"':
212 if (inquote)
213 r.append(b);
214 else
215 inDblQuote = !inDblQuote;
216 continue;
217 case '\'':
218 if (inDblQuote)
219 r.append(b);
220 else
221 inquote = !inquote;
222 continue;
223 case '\\':
224 if (inDblQuote || inquote || ip == commandLine.length())
225 r.append(b);
226 else
227 r.append(commandLine.charAt(ip++));
228 continue;
229 default:
230 r.append(b);
231 continue;
232 }
233 }
234 if (r.length() > 0)
235 list.add(r.toString());
236 return list.toArray(new String[0]);
237 }
238
239 public static class Result {
240 public final ByteArrayOutputStream out = new ByteArrayOutputStream();
241
242 public final ByteArrayOutputStream err = new ByteArrayOutputStream();
243
244 public Exception ex;
245
246 public byte[] outBytes() {
247 return out.toByteArray();
248 }
249
250 public byte[] errBytes() {
251 return err.toByteArray();
252 }
253
254 public String outString() {
255 return new String(out.toByteArray(), UTF_8);
256 }
257
258 public List<String> outLines() {
259 return IO.readLines(outString());
260 }
261
262 public String errString() {
263 return new String(err.toByteArray(), UTF_8);
264 }
265
266 public List<String> errLines() {
267 return IO.readLines(errString());
268 }
269 }
270
271 }