Skip to content

Commit eb78d5e

Browse files
authored
Unit tests & reorganize classes (#93)
* Pull in junit & assertj for some unit tests * Add validation to GitVersionArgs * Move all logic to new VersionDetails implementation * Cache the expensive git describe part * Delete old classes * Reduce methods in GitCli * Move utilities closer to usage * Move isRepoEmpty utility * Move util closer to usage * Reduce args * Delete GitCli utilities * Re-order slightly * Unit test for VersionDetails * Don't bother re-throwing IOExceptions * Use java 7 compatible assertJ * Convert to unit test * Move one more unit test
1 parent 5436b39 commit eb78d5e

File tree

13 files changed

+275
-416
lines changed

13 files changed

+275
-416
lines changed

build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ dependencies {
2121
compile 'com.google.guava:guava:20.0'
2222

2323
testCompile gradleTestKit()
24+
testCompile 'junit:junit:4.12'
25+
testCompile 'org.assertj:assertj-core:2.9.0'
2426
testCompile('org.spockframework:spock-core:1.0-groovy-2.4') {
2527
exclude module: 'groovy-all'
2628
}

src/main/java/com/palantir/gradle/gitversion/GitCli.java

Lines changed: 0 additions & 85 deletions
This file was deleted.

src/main/java/com/palantir/gradle/gitversion/GitDescribe.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ interface GitDescribe {
44

55
/**
66
* Mimics behaviour of 'git describe --tags --always --first-parent --match=${prefix}*'
7-
* Method returns null if repository is empty.
7+
* Method can assume repo is not empty but should never throw.
88
*/
99
String describe(String prefix);
1010
}
Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
package com.palantir.gradle.gitversion;
22

3-
import org.eclipse.jgit.api.Git;
4-
import org.eclipse.jgit.lib.ObjectId;
5-
import org.eclipse.jgit.lib.Ref;
6-
73
class GitUtils {
84

95
static final int SHA_ABBR_LENGTH = 7;
@@ -13,24 +9,4 @@ private GitUtils() {}
139
static String abbrevHash(String s) {
1410
return s.substring(0, SHA_ABBR_LENGTH);
1511
}
16-
17-
static boolean isRepoEmpty(Git git) {
18-
// back-compat: the JGit "describe" command throws an exception in repositories with no commits, so call it
19-
// first to preserve this behavior in cases where this call would fail but native "git" call does not.
20-
try {
21-
git.describe().call();
22-
return true;
23-
} catch (Exception ignored) {
24-
return false;
25-
}
26-
}
27-
28-
// getPeeledObjectId returns:
29-
// "if this ref is an annotated tag the id of the commit (or tree or blob) that the annotated tag refers to;
30-
// null if this ref does not refer to an annotated tag."
31-
// We use this to check if tag is annotated.
32-
static boolean isAnnotatedTag(Ref ref) {
33-
ObjectId peeledObjectId = ref.getPeeledObjectId();
34-
return peeledObjectId != null;
35-
}
3612
}

src/main/java/com/palantir/gradle/gitversion/GitVersionArgs.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,24 @@
11
package com.palantir.gradle.gitversion;
22

3+
import com.google.common.base.Preconditions;
4+
35
import java.util.Map;
46

57
class GitVersionArgs {
8+
private static final String PREFIX_REGEX = "[/@]?([A-Za-z]+[/@-])+";
9+
610
private String prefix = "";
711

812
public String getPrefix() {
913
return prefix;
1014
}
1115

1216
public void setPrefix(String prefix) {
17+
Preconditions.checkNotNull(prefix, "prefix must not be null");
18+
19+
Preconditions.checkState(prefix.matches(PREFIX_REGEX),
20+
"Specified prefix `" + prefix + "` does not match the allowed format regex `" + PREFIX_REGEX + "`.");
21+
1322
this.prefix = prefix;
1423
}
1524

src/main/java/com/palantir/gradle/gitversion/GitVersionPlugin.java

Lines changed: 19 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@
22

33
import groovy.lang.Closure;
44
import org.eclipse.jgit.api.Git;
5-
import org.eclipse.jgit.api.errors.GitAPIException;
65
import org.eclipse.jgit.internal.storage.file.FileRepository;
7-
import org.eclipse.jgit.lib.Constants;
8-
import org.eclipse.jgit.lib.ObjectId;
9-
import org.eclipse.jgit.lib.Ref;
106
import org.gradle.api.Action;
117
import org.gradle.api.Plugin;
128
import org.gradle.api.Project;
@@ -18,16 +14,18 @@
1814
public class GitVersionPlugin implements Plugin<Project> {
1915
public void apply(final Project project) {
2016

17+
final Git git = gitRepo(project);
18+
2119
// intentionally not using .getExtension() here for back-compat
2220
project.getExtensions().getExtraProperties().set("gitVersion", new Closure<String>(this, this) {
2321
public String doCall(Object args) {
24-
return versionDetails(project, GitVersionArgs.fromGroovyClosure(args)).getVersion();
22+
return new VersionDetails(git, GitVersionArgs.fromGroovyClosure(args)).getVersion();
2523
}
2624
});
2725

2826
project.getExtensions().getExtraProperties().set("versionDetails", new Closure<VersionDetails>(this, this) {
2927
public VersionDetails doCall(Object args) {
30-
return versionDetails(project, GitVersionArgs.fromGroovyClosure(args));
28+
return new VersionDetails(git, GitVersionArgs.fromGroovyClosure(args));
3129
}
3230
});
3331

@@ -42,105 +40,37 @@ public void execute(Task task) {
4240
printVersionTask.setDescription("Prints the project's configured version to standard out");
4341
}
4442

45-
public static void verifyPrefix(final String prefix) {
46-
assert prefix != null && (prefix.equals("") || prefix.matches(PREFIX_REGEX)) : "Specified prefix `" + prefix + "` does not match the allowed format regex `" + PREFIX_REGEX + "`.";
47-
}
48-
49-
private static String stripPrefix(String description, final String prefix) {
50-
return description == null ? description : description.replaceFirst("^" + prefix, "");
51-
}
52-
53-
private VersionDetails versionDetails(Project project, GitVersionArgs args) {
54-
verifyPrefix(args.getPrefix());
55-
Git git = gitRepo(project);
56-
String description = stripPrefix(gitDescribe(project, args.getPrefix()), args.getPrefix());
57-
String hash = gitHash(git);
58-
String fullHash = gitHashFull(git);
59-
String branchName = gitBranchName(git);
60-
boolean isClean = isClean(git);
61-
62-
return new VersionDetails(description, hash, fullHash, branchName, isClean);
63-
}
64-
6543
private Git gitRepo(Project project) {
6644
try {
67-
File gitDir = GitCli.getRootGitDir(project.getProjectDir());
45+
File gitDir = getRootGitDir(project.getProjectDir());
6846
return Git.wrap(new FileRepository(gitDir));
6947
} catch (IOException e) {
7048
throw new RuntimeException(e);
7149
}
7250
}
7351

74-
private String gitDescribe(Project project, String prefix) {
75-
// This used to be implemented with JGit and replaced with shelling out to installed git (#46) because JGit
76-
// didn't support required behavior. Using installed git doesn't work in some environments or
77-
// with older versions of git client. We're switching back to implementation with JGit. To make sure we don't
78-
// make breaking change, we're keeping both implementations. Plan is to get rid of installed git implementation.
79-
// TODO(mbakovic): Use JGit only implementation #87
80-
81-
Git git = gitRepo(project);
82-
String nativeGitDescribe = new NativeGitDescribe(project.getProjectDir(), git).describe(prefix);
83-
String jgitDescribe = new JGitDescribe(git).describe(prefix);
84-
85-
// If native failed, return JGit one
86-
if (nativeGitDescribe == null) {
87-
return jgitDescribe;
88-
}
89-
90-
91-
// If native succeeded, make sure it's same as JGit one
92-
if (!nativeGitDescribe.equals(jgitDescribe)) {
93-
throw new IllegalStateException(String.format("Inconsistent git describe: native was %s and jgit was %s. " + "Please report this on github.com/palantir/gradle-git-version", nativeGitDescribe, jgitDescribe));
94-
}
95-
96-
97-
return jgitDescribe;
98-
}
99-
100-
private String gitHash(Git git) {
101-
String gitHashFull = gitHashFull(git);
102-
if (gitHashFull == null) {
103-
return null;
52+
private static File getRootGitDir(File currentRoot) {
53+
File gitDir = scanForRootGitDir(currentRoot);
54+
if (!gitDir.exists()) {
55+
throw new IllegalArgumentException("Cannot find '.git' directory");
10456
}
105-
106-
return gitHashFull.substring(0, VERSION_ABBR_LENGTH);
57+
return gitDir;
10758
}
10859

109-
private String gitHashFull(Git git) {
110-
try {
111-
ObjectId objectId = git.getRepository().findRef(Constants.HEAD).getObjectId();
112-
if (objectId == null) {
113-
return null;
114-
}
60+
private static File scanForRootGitDir(File currentRoot) {
61+
File gitDir = new File(currentRoot, ".git");
11562

116-
return objectId.name();
117-
} catch (IOException e) {
118-
throw new RuntimeException(e);
63+
if (gitDir.exists()) {
64+
return gitDir;
11965
}
120-
}
12166

122-
private String gitBranchName(Git git) {
123-
try {
124-
Ref ref = git.getRepository().findRef(git.getRepository().getBranch());
125-
if (ref == null) {
126-
return null;
127-
}
128-
129-
return ref.getName().substring(Constants.R_HEADS.length());
130-
} catch (IOException e) {
131-
throw new RuntimeException(e);
67+
// stop at the root directory, return non-existing File object;
68+
if (currentRoot.getParentFile() == null) {
69+
return gitDir;
13270
}
133-
}
13471

135-
private boolean isClean(Git git) {
136-
try {
137-
return git.status().call().isClean();
138-
} catch (GitAPIException e) {
139-
throw new RuntimeException(e);
140-
}
72+
// look in parent directory;
73+
return scanForRootGitDir(currentRoot.getParentFile());
14174
}
142-
143-
private static final int VERSION_ABBR_LENGTH = 10;
144-
private static final String PREFIX_REGEX = "[/@]?([A-Za-z]+[/@-])+";
14575
}
14676

src/main/java/com/palantir/gradle/gitversion/JGitDescribe.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,6 @@ class JGitDescribe implements GitDescribe {
3030

3131
@Override
3232
public String describe(String prefix) {
33-
if (!GitUtils.isRepoEmpty(git)) {
34-
log.debug("Repository is empty");
35-
return null;
36-
}
37-
3833
try {
3934
ObjectId headObjectId = git.getRepository().resolve(Constants.HEAD);
4035

0 commit comments

Comments
 (0)