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