15
15
*/
16
16
package com.palantir.gradle.gitversion
17
17
18
- import com.google.common.base.Preconditions
19
- import com.google.common.base.Splitter
20
- import com.google.common.collect.Sets
21
18
import groovy.transform.Memoized
22
- import org.eclipse.jgit.api.DescribeCommand
23
19
import org.eclipse.jgit.api.Git
24
20
import org.eclipse.jgit.internal.storage.file.FileRepository
25
21
import org.eclipse.jgit.lib.Constants
@@ -30,11 +26,8 @@ import org.gradle.api.Project
30
26
31
27
class GitVersionPlugin implements Plugin<Project > {
32
28
33
- private static final int SHA_ABBR_LENGTH = 7
34
29
private static final int VERSION_ABBR_LENGTH = 10
35
30
private static final String PREFIX_REGEX = " [/@]?([A-Za-z]+[/@-])+"
36
- private static final Splitter LINE_SPLITTER = Splitter . on(System . getProperty(" line.separator" )). omitEmptyStrings()
37
- private static final Splitter WORD_SPLITTER = Splitter . on(" " ). omitEmptyStrings()
38
31
39
32
void apply (Project project ) {
40
33
project. ext. gitVersion = {
@@ -79,65 +72,35 @@ class GitVersionPlugin implements Plugin<Project> {
79
72
80
73
@Memoized
81
74
private Git gitRepo (Project project ) {
82
- File gitDir = GitCli . getRootGitDir(project. projectDir);
75
+ File gitDir = GitCli . getRootGitDir(project. projectDir)
83
76
return Git . wrap(new FileRepository (gitDir))
84
77
}
85
78
86
79
@Memoized
87
80
private String gitDescribe (Project project , String prefix ) {
88
- // verify that "git" command exists (throws exception if it does not)
89
- GitCli . verifyGitCommandExists()
90
-
91
- def runGitCmd = { String ... commands ->
92
- return GitCli . runGitCommand(project. projectDir, commands);
81
+ // This used to be implemented with JGit and replaced with shelling out to installed git (#46) because JGit
82
+ // didn't support required behavior. Using installed git doesn't work in some environments or
83
+ // with older versions of git client. We're switching back to implementation with JGit. To make sure we don't
84
+ // make breaking change, we're keeping both implementations. Plan is to get rid of installed git implementation.
85
+ // TODO(mbakovic): Use JGit only implementation #87
86
+
87
+ String nativeGitDescribe = new NativeGitDescribe (project. projectDir). describe(prefix)
88
+ String jgitDescribe = new JGitDescribe (project. projectDir). describe(prefix)
89
+
90
+ // If native failed, return JGit one
91
+ if (nativeGitDescribe == null ) {
92
+ return jgitDescribe
93
93
}
94
94
95
- Git git = gitRepo(project)
96
- try {
97
- // back-compat: the JGit "describe" command throws an exception in repositories with no commits, so call it
98
- // first to preserve this behavior in cases where this call would fail but native "git" call does not.
99
- new DescribeCommand (git. getRepository()). call()
100
-
101
- /*
102
- * Mimick 'git describe --tags --always --first-parent --match=${prefix}*' by using rev-list to
103
- * support versions of git < 1.8.4
104
- */
105
-
106
- // Get SHAs of all tags, we only need to search for these later on
107
- Set<String > tagRefs = Sets . newHashSet()
108
- for (String tag : getLines(runGitCmd(" show-ref" , " --tags" , " -d" ))) {
109
- List<String > parts = WORD_SPLITTER . splitToList(tag)
110
- Preconditions . checkArgument(parts. size() == 2 , " Could not parse output of `git show-ref`: %s" , parts)
111
- tagRefs. add(parts. get(0 ))
112
- }
113
-
114
- List<String > revs = getLines(runGitCmd(" rev-list" , " --first-parent" , " HEAD" ))
115
- for (int depth = 0 ; depth < revs. size(); depth++ ) {
116
- String rev = revs. get(depth)
117
- if (tagRefs. contains(rev)) {
118
- String exactTag = runGitCmd(" describe" , " --tags" , " --exact-match" , " --match=${ prefix} *" , rev)
119
- if (exactTag != " " ) {
120
- return depth == 0 ?
121
- exactTag : String . format(" %s-%s-g%s" , exactTag, depth, abbrevHash(revs. get(0 )))
122
- }
123
- }
124
- }
125
-
126
- // No tags found, so return commit hash of HEAD
127
- return abbrevHash(runGitCmd(" rev-parse" , " HEAD" ))
128
- } catch (Throwable t) {
129
- return null
95
+ // If native succeeded, make sure it's same as JGit one
96
+ if (! nativeGitDescribe. equals(jgitDescribe)) {
97
+ throw new IllegalStateException (String . format(
98
+ " Inconsistent git describe: native was %s and jgit was %s. "
99
+ + " Please report this on github.com/palantir/gradle-git-version" ,
100
+ nativeGitDescribe, jgitDescribe))
130
101
}
131
- }
132
-
133
- @Memoized
134
- private List<String > getLines (String s ) {
135
- return LINE_SPLITTER . splitToList(s)
136
- }
137
102
138
- @Memoized
139
- private String abbrevHash (String s ) {
140
- return s. substring(0 , SHA_ABBR_LENGTH )
103
+ return jgitDescribe
141
104
}
142
105
143
106
@Memoized
@@ -152,7 +115,7 @@ class GitVersionPlugin implements Plugin<Project> {
152
115
@Memoized
153
116
private String gitHashFull (Project project ) {
154
117
Git git = gitRepo(project)
155
- ObjectId objectId = git. getRepository(). getRef(" HEAD" ). getObjectId();
118
+ ObjectId objectId = git. getRepository(). getRef(" HEAD" ). getObjectId()
156
119
if (objectId == null ) {
157
120
return null
158
121
}
@@ -172,6 +135,6 @@ class GitVersionPlugin implements Plugin<Project> {
172
135
@Memoized
173
136
private boolean isClean (Project project ) {
174
137
Git git = gitRepo(project)
175
- return git. status(). call(). isClean();
138
+ return git. status(). call(). isClean()
176
139
}
177
140
}
0 commit comments