22
33import groovy .lang .Closure ;
44import org .eclipse .jgit .api .Git ;
5- import org .eclipse .jgit .api .errors .GitAPIException ;
65import 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 ;
106import org .gradle .api .Action ;
117import org .gradle .api .Plugin ;
128import org .gradle .api .Project ;
1814public 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
0 commit comments