Skip to content

Commit 45f8982

Browse files
committed
Merge pull request #155 from hgschmie/git-output-fix
Fix differences in the output of native and jgit
2 parents cd1f79d + a0f7db7 commit 45f8982

File tree

5 files changed

+316
-102
lines changed

5 files changed

+316
-102
lines changed

src/main/java/pl/project13/maven/git/JGitProvider.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
import com.google.common.annotations.VisibleForTesting;
44
import com.google.common.base.Function;
55
import com.google.common.base.Joiner;
6+
import com.google.common.base.Objects;
67
import com.google.common.base.Predicate;
78
import com.google.common.collect.Collections2;
9+
810
import org.apache.maven.plugin.MojoExecutionException;
911
import org.eclipse.jgit.api.Git;
1012
import org.eclipse.jgit.api.errors.GitAPIException;
@@ -18,6 +20,7 @@
1820
import org.eclipse.jgit.revwalk.RevWalk;
1921
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
2022
import org.jetbrains.annotations.NotNull;
23+
2124
import pl.project13.jgit.DescribeCommand;
2225
import pl.project13.jgit.DescribeResult;
2326
import pl.project13.maven.git.log.LoggerBridge;
@@ -66,13 +69,13 @@ protected void init() throws MojoExecutionException {
6669
@Override
6770
protected String getBuildAuthorName() {
6871
String userName = git.getConfig().getString("user", null, "name");
69-
return userName;
72+
return Objects.firstNonNull(userName, "");
7073
}
7174

7275
@Override
7376
protected String getBuildAuthorEmail() {
7477
String userEmail = git.getConfig().getString("user", null, "email");
75-
return userEmail;
78+
return Objects.firstNonNull(userEmail, "");
7679
}
7780

7881
@Override
@@ -142,13 +145,13 @@ protected String getCommitAuthorEmail() {
142145
@Override
143146
protected String getCommitMessageFull() {
144147
String fullMessage = headCommit.getFullMessage();
145-
return fullMessage;
148+
return fullMessage.trim();
146149
}
147150

148151
@Override
149152
protected String getCommitMessageShort() {
150153
String shortMessage = headCommit.getShortMessage();
151-
return shortMessage;
154+
return shortMessage.trim();
152155
}
153156

154157
@Override

src/main/java/pl/project13/maven/git/NativeGitProvider.java

Lines changed: 128 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
package pl.project13.maven.git;
22

3-
import com.google.common.base.Function;
4-
import com.google.common.base.Joiner;
5-
import com.google.common.base.Predicate;
3+
import static java.lang.String.format;
4+
65
import com.google.common.base.Splitter;
7-
import com.google.common.collect.FluentIterable;
8-
import com.google.common.collect.ImmutableList;
6+
import com.google.common.base.Throwables;
97
import com.google.common.collect.Lists;
8+
109
import org.apache.maven.plugin.MojoExecutionException;
1110
import org.jetbrains.annotations.NotNull;
11+
1212
import pl.project13.maven.git.log.LoggerBridge;
1313

1414
import java.io.*;
15-
import java.util.Arrays;
15+
import java.text.SimpleDateFormat;
1616

1717

1818
public class NativeGitProvider extends GitDataProvider {
@@ -55,12 +55,26 @@ protected void init() throws MojoExecutionException {
5555

5656
@Override
5757
protected String getBuildAuthorName() {
58-
return tryToRunGitCommand(canonical, "log -1 --pretty=format:\"%an\"");
58+
try {
59+
return runGitCommand(canonical, "config --get user.name");
60+
} catch (NativeCommandException e) {
61+
if (e.getExitCode() == 1) { // No config file found
62+
return "";
63+
}
64+
throw Throwables.propagate(e);
65+
}
5966
}
6067

6168
@Override
6269
protected String getBuildAuthorEmail() {
63-
return tryToRunGitCommand(canonical, "log -1 --pretty=format:\"%ae\"");
70+
try {
71+
return runGitCommand(canonical, "config --get user.email");
72+
} catch (NativeCommandException e) {
73+
if (e.getExitCode() == 1) { // No config file found
74+
return "";
75+
}
76+
throw Throwables.propagate(e);
77+
}
6478
}
6579

6680
@Override
@@ -75,21 +89,26 @@ protected String getBranchName() throws IOException {
7589
private String getBranch(File canonical) {
7690
String branch = null;
7791
try{
78-
branch = tryToRunGitCommand(canonical, "symbolic-ref HEAD");
92+
branch = runGitCommand(canonical, "symbolic-ref HEAD");
7993
if (branch != null) {
8094
branch = branch.replace("refs/heads/", "");
8195
}
82-
}catch(RuntimeException e){
96+
} catch(NativeCommandException e) {
8397
// it seems that git repro is in 'DETACHED HEAD'-State, using Commid-Id as Branch
84-
branch = getCommitId();
98+
String err = e.getStderr();
99+
if (err != null && err.contains("ref HEAD is not a symbolic ref")) {
100+
branch = getCommitId();
101+
} else {
102+
throw Throwables.propagate(e);
103+
}
85104
}
86105
return branch;
87106
}
88107

89108
@Override
90-
protected String getGitDescribe() throws MojoExecutionException {
109+
protected String getGitDescribe() {
91110
final String argumentsForGitDescribe = getArgumentsForGitDescribe(gitDescribe);
92-
final String gitDescribe = tryToRunGitCommand(canonical, "describe" + argumentsForGitDescribe);
111+
final String gitDescribe = runQuietGitCommand(canonical, "describe" + argumentsForGitDescribe);
93112
return gitDescribe;
94113
}
95114

@@ -126,11 +145,11 @@ private String getArgumentsForGitDescribe(GitDescribeConfig describeConfig) {
126145

127146
@Override
128147
protected String getCommitId() {
129-
return tryToRunGitCommand(canonical, "rev-parse HEAD");
148+
return runQuietGitCommand(canonical, "rev-parse HEAD");
130149
}
131150

132151
@Override
133-
protected String getAbbrevCommitId() throws MojoExecutionException {
152+
protected String getAbbrevCommitId() {
134153
// we could run: tryToRunGitCommand(canonical, "rev-parse --short="+abbrevLength+" HEAD");
135154
// but minimum length for --short is 4, our abbrevLength could be 2
136155
String commitId = getCommitId();
@@ -150,58 +169,35 @@ protected boolean isDirty() throws MojoExecutionException {
150169

151170
@Override
152171
protected String getCommitAuthorName() {
153-
return tryToRunGitCommand(canonical, "log -1 --pretty=format:\"%cn\"");
172+
return runQuietGitCommand(canonical, "log -1 --pretty=format:%an");
154173
}
155174

156175
@Override
157176
protected String getCommitAuthorEmail() {
158-
return tryToRunGitCommand(canonical, "log -1 --pretty=format:\"%ce\"");
177+
return runQuietGitCommand(canonical, "log -1 --pretty=format:%ae");
159178
}
160179

161180
@Override
162181
protected String getCommitMessageFull() {
163-
return tryToRunGitCommand(canonical, "log -1 --pretty=format:\"%B\"");
182+
return runQuietGitCommand(canonical, "log -1 --pretty=format:%B");
164183
}
165184

166185
@Override
167186
protected String getCommitMessageShort() {
168-
return tryToRunGitCommand(canonical, "log -1 --pretty=format:\"%s\"");
187+
return runQuietGitCommand(canonical, "log -1 --pretty=format:%s");
169188
}
170189

171190
@Override
172191
protected String getCommitTime() {
173-
return tryToRunGitCommand(canonical, "log -1 --pretty=format:\"%ci\"");
192+
String value = runQuietGitCommand(canonical, "log -1 --pretty=format:%ct");
193+
SimpleDateFormat smf = new SimpleDateFormat(dateFormat);
194+
return smf.format(Long.parseLong(value)*1000L);
174195
}
175196

176197
@Override
177-
protected String getTags() throws MojoExecutionException {
178-
final String branch = tryToRunGitCommand(canonical, "rev-parse --abbrev-ref HEAD");
179-
180-
String out = tryToRunGitCommand(canonical, "log -n 1 --pretty=format:'%d'");
181-
String[] nms = out
182-
.replaceAll("HEAD", "")
183-
.replaceAll("\\)", "")
184-
.replaceAll("\\(", "")
185-
.replaceAll("'", "")
186-
.replaceAll("tag: ", "")
187-
.replaceAll(",", "")
188-
.trim()
189-
.split(" ");
190-
191-
192-
ImmutableList<String> cleanTags = FluentIterable.from(Arrays.asList(nms)).
193-
transform(new Function<String, String>() {
194-
@Override public String apply(String input) {
195-
return input.trim();
196-
}
197-
}).
198-
filter(new Predicate<String>() {
199-
@Override public boolean apply(String input) {
200-
return !input.equals(branch);
201-
}
202-
}).toList();
203-
204-
return Joiner.on(",").join(cleanTags);
198+
protected String getTags() {
199+
final String result = runQuietGitCommand(canonical, "tag --contains");
200+
return result.replace('\n', ',');
205201
}
206202

207203
@Override
@@ -215,70 +211,67 @@ protected void finalCleanUp() {
215211

216212
private String getOriginRemote(File directory) throws MojoExecutionException {
217213
String remoteUrl = null;
218-
try {
219-
String remotes = runGitCommand(directory, "remote -v");
214+
String remotes = runQuietGitCommand(directory, "remote -v");
220215

221-
// welcome to text output parsing hell! - no `\n` is not enough
222-
for (String line : Splitter.onPattern("\\((fetch|push)\\)?").split(remotes)) {
223-
String trimmed = line.trim();
216+
// welcome to text output parsing hell! - no `\n` is not enough
217+
for (String line : Splitter.onPattern("\\((fetch|push)\\)?").split(remotes)) {
218+
String trimmed = line.trim();
224219

225-
if (trimmed.startsWith("origin")) {
226-
String[] splited = trimmed.split("\\s+");
227-
if (splited.length != REMOTE_COLS - 1) { // because (fetch/push) was trimmed
228-
throw new MojoExecutionException("Unsupported GIT output (verbose remote address): " + line);
229-
}
230-
remoteUrl = splited[1];
220+
if (trimmed.startsWith("origin")) {
221+
String[] splited = trimmed.split("\\s+");
222+
if (splited.length != REMOTE_COLS - 1) { // because (fetch/push) was trimmed
223+
throw new MojoExecutionException("Unsupported GIT output (verbose remote address): " + line);
231224
}
225+
remoteUrl = splited[1];
232226
}
233-
} catch (Exception e) {
234-
throw new MojoExecutionException("Error while obtaining origin remote", e);
235227
}
236228
return remoteUrl;
237229
}
238230

239-
private String tryToRunGitCommand(File directory, String gitCommand) {
240-
String retValue = "";
241-
try {
242-
retValue = runGitCommand(directory, gitCommand);
243-
} catch (MojoExecutionException ex) {
244-
// do nothing
245-
}
246-
return retValue;
247-
}
248-
249231
/**
250232
* Runs a maven command and returns {@code true} if output was non empty.
251233
* Can be used to short cut reading output from command when we know it may be a rather long one.
252-
* */
234+
*
235+
* Return true if the result is empty.
236+
*
237+
**/
253238
private boolean tryCheckEmptyRunGitCommand(File directory, String gitCommand) {
254239
try {
255240
String env = System.getenv("GIT_PATH");
256241
String exec = (env == null) ? "git" : env;
257242
String command = String.format("%s %s", exec, gitCommand);
258243

259-
boolean empty = getRunner().runEmpty(directory, command);
260-
return !empty;
244+
return getRunner().runEmpty(directory, command);
261245
} catch (IOException ex) {
246+
// Error means "non-empty"
262247
return false;
263248
// do nothing...
264249
}
265250
}
266251

267-
private String runGitCommand(File directory, String gitCommand) throws MojoExecutionException {
252+
private String runQuietGitCommand(File directory, String gitCommand) {
253+
final String env = System.getenv("GIT_PATH");
254+
final String exec = (env == null) ? "git" : env;
255+
final String command = String.format("%s %s", exec, gitCommand);
256+
268257
try {
269-
final String env = System.getenv("GIT_PATH");
270-
final String exec = (env == null) ? "git" : env;
271-
final String command = String.format("%s %s", exec, gitCommand);
258+
return getRunner().run(directory, command.trim()).trim();
259+
} catch (IOException e) {
260+
throw Throwables.propagate(e);
261+
}
262+
}
272263

273-
final String result = getRunner().run(directory, command.trim()).trim();
274-
return result;
275-
} catch (IOException ex) {
276-
if (ex.getMessage().contains("exited with invalid status")) {
277-
throw new RuntimeException("Failed to execute git command (`git " + gitCommand + "` @ " + directory +")!", ex);
278-
} else {
279-
throw new MojoExecutionException("Could not run GIT command - GIT is not installed or not exists in system path? " +
280-
"Tried to run: 'git " + gitCommand + "'", ex);
281-
}
264+
private String runGitCommand(File directory, String gitCommand) throws NativeCommandException {
265+
final String env = System.getenv("GIT_PATH");
266+
final String exec = (env == null) ? "git" : env;
267+
final String command = String.format("%s %s", exec, gitCommand);
268+
269+
try {
270+
return getRunner().run(directory, command.trim()).trim();
271+
} catch (NativeCommandException e) {
272+
throw e;
273+
} catch (IOException e) {
274+
throw Throwables.propagate(e);
282275
}
283276
}
284277

@@ -296,6 +289,52 @@ public interface ProcessRunner {
296289
boolean runEmpty(File directory, String command) throws IOException;
297290
}
298291

292+
public static class NativeCommandException extends IOException
293+
{
294+
private final int exitCode;
295+
private final String command;
296+
private final File directory;
297+
private final String stdout;
298+
private final String stderr;
299+
300+
public NativeCommandException(int exitCode,
301+
String command,
302+
File directory,
303+
String stdout,
304+
String stderr) {
305+
this.exitCode = exitCode;
306+
this.command = command;
307+
this.directory = directory;
308+
this.stdout = stdout;
309+
this.stderr = stderr;
310+
}
311+
312+
public int getExitCode() {
313+
return exitCode;
314+
}
315+
316+
public String getCommand() {
317+
return command;
318+
}
319+
320+
public File getDirectory() {
321+
return directory;
322+
}
323+
324+
public String getStdout() {
325+
return stdout;
326+
}
327+
328+
public String getStderr() {
329+
return stderr;
330+
}
331+
332+
@Override
333+
public String getMessage() {
334+
return format("Git command exited with invalid status [%d]: stdout: `%s`, stderr: `%s`", exitCode, stdout, stderr);
335+
}
336+
}
337+
299338
protected static class JavaProcessRunner implements ProcessRunner {
300339
@Override
301340
public String run(File directory, String command) throws IOException {
@@ -311,14 +350,12 @@ public String run(File directory, String command) throws IOException {
311350
final StringBuilder commandResult = new StringBuilder();
312351
String line;
313352
while ((line = reader.readLine()) != null) {
314-
commandResult.append(line);
353+
commandResult.append(line).append("\n");
315354
}
316355

317356
if (proc.exitValue() != 0) {
318357
final StringBuilder errMsg = readStderr(err);
319-
320-
final String message = String.format("Git command exited with invalid status [%d]: stdout: `%s`, stderr: `%s`", proc.exitValue(), output, errMsg.toString());
321-
throw new IOException(message);
358+
throw new NativeCommandException(proc.exitValue(), command, directory, output, errMsg.toString());
322359
}
323360
output = commandResult.toString();
324361
} catch (InterruptedException ex) {

0 commit comments

Comments
 (0)