Skip to content

Commit 4ce9ffa

Browse files
authored
Merge pull request #192 from coverbeck/gittag_support
Support for Git tags #191
2 parents 25a9538 + a81aae5 commit 4ce9ffa

File tree

3 files changed

+121
-17
lines changed

3 files changed

+121
-17
lines changed

pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,12 @@
103103
<artifactId>org.eclipse.jgit</artifactId>
104104
<version>4.8.0.201706111038-r</version>
105105
</dependency>
106+
<dependency>
107+
<groupId>org.mockito</groupId>
108+
<artifactId>mockito-all</artifactId>
109+
<version>1.10.19</version>
110+
<scope>test</scope>
111+
</dependency>
106112
</dependencies>
107113

108114
<build>

src/main/java/org/commonwl/view/git/GitService.java

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.commonwl.view.researchobject.HashableAgent;
2424
import org.eclipse.jgit.api.Git;
2525
import org.eclipse.jgit.api.errors.GitAPIException;
26+
import org.eclipse.jgit.api.errors.RefNotFoundException;
2627
import org.eclipse.jgit.lib.ObjectId;
2728
import org.eclipse.jgit.lib.PersonIdent;
2829
import org.eclipse.jgit.revwalk.RevCommit;
@@ -32,6 +33,7 @@
3233
import org.springframework.beans.factory.annotation.Value;
3334
import org.springframework.stereotype.Service;
3435

36+
import java.io.File;
3537
import java.io.IOException;
3638
import java.net.URI;
3739
import java.net.URISyntaxException;
@@ -67,7 +69,7 @@ public GitService(@Value("${gitStorage}") Path gitStorage,
6769
* Gets a repository, cloning into a local directory or
6870
* @param gitDetails The details of the Git repository
6971
* @param reuseDir Whether the cached repository can be used
70-
* @returns The git object for the repository
72+
* @return The git object for the repository
7173
*/
7274
public Git getRepository(GitDetails gitDetails, boolean reuseDir)
7375
throws GitAPIException, IOException {
@@ -84,34 +86,45 @@ public Git getRepository(GitDetails gitDetails, boolean reuseDir)
8486
} else {
8587
// Create a folder and clone repository into it
8688
Files.createDirectory(repoDir);
87-
repo = Git.cloneRepository()
88-
.setCloneSubmodules(cloneSubmodules)
89-
.setURI(gitDetails.getRepoUrl())
90-
.setDirectory(repoDir.toFile())
91-
.setCloneAllBranches(true)
92-
.call();
89+
repo = cloneRepo(gitDetails.getRepoUrl(), repoDir.toFile());
9390
}
9491
} else {
9592
// Another thread is already using the existing folder
9693
// Must create another temporary one
97-
repo = Git.cloneRepository()
98-
.setCloneSubmodules(cloneSubmodules)
99-
.setURI(gitDetails.getRepoUrl())
100-
.setDirectory(createTempDir())
101-
.setCloneAllBranches(true)
102-
.call();
94+
repo = cloneRepo(gitDetails.getRepoUrl(), createTempDir());
10395
}
10496

10597
// Checkout the specific branch or commit ID
10698
if (repo != null) {
10799
// Create a new local branch if it does not exist and not a commit ID
108100
String branchOrCommitId = gitDetails.getBranch();
109-
if (!ObjectId.isId(branchOrCommitId)) {
101+
final boolean isId = ObjectId.isId(branchOrCommitId);
102+
if (!isId) {
110103
branchOrCommitId = "refs/remotes/origin/" + branchOrCommitId;
111104
}
112-
repo.checkout()
113-
.setName(branchOrCommitId)
114-
.call();
105+
try {
106+
repo.checkout()
107+
.setName(branchOrCommitId)
108+
.call();
109+
}
110+
catch (Exception ex) {
111+
// Maybe it was a tag
112+
if (!isId && ex instanceof RefNotFoundException) {
113+
final String tag = gitDetails.getBranch();
114+
try {
115+
repo.checkout()
116+
.setName(tag)
117+
.call();
118+
}
119+
catch (Exception ex2) {
120+
// Throw the first exception, to keep the same behavior as before.
121+
throw ex;
122+
}
123+
}
124+
else {
125+
throw ex;
126+
}
127+
}
115128
}
116129

117130
return repo;
@@ -184,4 +197,19 @@ public GitDetails transferPathToBranch(GitDetails githubInfo) {
184197
}
185198
}
186199

200+
/**
201+
* Clones a Git repository
202+
* @param repoUrl the url of the Git repository
203+
* @param directory the directory to clone the repo into
204+
* @return a Git instance
205+
* @throws GitAPIException if any error occurs cloning the repo
206+
*/
207+
protected Git cloneRepo(String repoUrl, File directory) throws GitAPIException {
208+
return Git.cloneRepository()
209+
.setCloneSubmodules(cloneSubmodules)
210+
.setURI(repoUrl)
211+
.setDirectory(directory)
212+
.setCloneAllBranches(true)
213+
.call();
214+
}
187215
}

src/test/java/org/commonwl/view/git/GitServiceTest.java

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,51 @@
1919

2020
package org.commonwl.view.git;
2121

22+
import java.io.File;
23+
import java.io.IOException;
24+
25+
import org.eclipse.jgit.api.CheckoutCommand;
26+
import org.eclipse.jgit.api.Git;
27+
import org.eclipse.jgit.api.errors.GitAPIException;
28+
import org.eclipse.jgit.api.errors.RefNotFoundException;
29+
import org.junit.Before;
2230
import org.junit.Test;
31+
import org.mockito.Mockito;
2332

2433
import static org.junit.Assert.assertEquals;
34+
import static org.junit.Assert.assertNotNull;
35+
import static org.junit.Assert.assertTrue;
36+
import static org.mockito.Mockito.doReturn;
37+
import static org.mockito.Mockito.mock;
38+
import static org.mockito.Mockito.spy;
39+
import static org.mockito.Mockito.when;
2540

2641
public class GitServiceTest {
2742

43+
private final RefNotFoundException branchNotFoundException = new RefNotFoundException("Branch not found");
44+
private final RefNotFoundException tagNotFoundException = new RefNotFoundException("Tag not found");
45+
46+
private GitService spyGitService;
47+
private Git mockGit;
48+
private CheckoutCommand mockGoodCheckoutCommand;
49+
private CheckoutCommand mockBranchNotFoundCommand;
50+
private CheckoutCommand mockTagNotFoundCommand;
51+
private CheckoutCommand mockCheckoutCommand;
52+
53+
@Before
54+
public void setup() throws GitAPIException {
55+
GitService gitService = new GitService(null, false);
56+
this.spyGitService = spy(gitService);
57+
this.mockGit = mock(Git.class);
58+
this.mockGoodCheckoutCommand = mock(CheckoutCommand.class);
59+
this.mockBranchNotFoundCommand = mock(CheckoutCommand.class);
60+
this.mockTagNotFoundCommand = mock(CheckoutCommand.class);
61+
this.mockCheckoutCommand = mock(CheckoutCommand.class);
62+
when(this.mockGit.checkout()).thenReturn(this.mockCheckoutCommand);
63+
when(this.mockBranchNotFoundCommand.call()).thenThrow(branchNotFoundException);
64+
when(this.mockTagNotFoundCommand.call()).thenThrow(tagNotFoundException);
65+
}
66+
2867
@Test
2968
public void transferPathToBranch() throws Exception {
3069
GitService gitService = new GitService(null, false);
@@ -39,4 +78,35 @@ public void transferPathToBranch() throws Exception {
3978
assertEquals("branchpart1/branchpart2/branchpart3", step2.getBranch());
4079
assertEquals("workflowInRoot.cwl", step2.getPath());
4180
}
81+
82+
@Test
83+
public void checksOutTag() throws Exception {
84+
when(mockCheckoutCommand.setName("refs/remotes/origin/mytag")).thenReturn(this.mockBranchNotFoundCommand);
85+
when(mockCheckoutCommand.setName("mytag")).thenReturn(this.mockGoodCheckoutCommand);
86+
doReturn(this.mockGit).when(this.spyGitService).cloneRepo(Mockito.any(String.class), Mockito.any(File.class));
87+
assertNotNull(this.spyGitService.getRepository(new GitDetails(null, "mytag", "foo"), false));
88+
}
89+
90+
@Test
91+
public void checksOutBranch() throws GitAPIException, IOException {
92+
when(mockCheckoutCommand.setName("refs/remotes/origin/mybranch")).thenReturn(this.mockGoodCheckoutCommand);
93+
when(mockCheckoutCommand.setName("mytag")).thenReturn(this.mockTagNotFoundCommand);
94+
doReturn(this.mockGit).when(this.spyGitService).cloneRepo(Mockito.any(String.class), Mockito.any(File.class));
95+
assertNotNull(this.spyGitService.getRepository(new GitDetails(null, "mybranch", "foo"), false));
96+
}
97+
98+
@Test()
99+
public void throwsFirstExceptionIfTagAndBranchFail() throws GitAPIException {
100+
when(mockCheckoutCommand.setName("refs/remotes/origin/mytag")).thenReturn(this.mockBranchNotFoundCommand);
101+
when(mockCheckoutCommand.setName("mytag")).thenReturn(this.mockTagNotFoundCommand);
102+
doReturn(this.mockGit).when(this.spyGitService).cloneRepo(Mockito.any(String.class), Mockito.any(File.class));
103+
boolean thrown = false;
104+
try {
105+
this.spyGitService.getRepository(new GitDetails(null, "mytag", "foo"), false);
106+
} catch (Exception e) {
107+
// Make sure it's not this.tagNotFoundException
108+
thrown = (e == this.branchNotFoundException);
109+
}
110+
assertTrue(thrown);
111+
}
42112
}

0 commit comments

Comments
 (0)