Skip to content

Commit c2bdc54

Browse files
committed
Merge branch 'master' of https://github.com/scm4j/scm4j-vcs-git
2 parents 83229a1 + af18a5f commit c2bdc54

File tree

4 files changed

+233
-53
lines changed

4 files changed

+233
-53
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
[![Release](https://jitpack.io/v/scm4j/scm4j-vcs-git.svg)](https://jitpack.io/#scm4j/scm4j-vcs-git)
22
[![Build Status](https://travis-ci.org/scm4j/scm4j-vcs-git.svg?branch=master)](https://travis-ci.org/scm4j/scm4j-vcs-git)
3+
[![Coverage Status](https://coveralls.io/repos/github/scm4j/scm4j-vcs-git/badge.svg?branch=master)](https://coveralls.io/github/scm4j/scm4j-vcs-git?branch=master)
34

45
# Overview
56
scm4j-vcs-git is lightweight library for execute basic Git VCS operations (merge, branch create etc). It uses [scm4j-vcs-api](https://github.com/scm4j/scm4j-vcs-api) exposing IVCS implementation for Git repositories and [JGit](https://eclipse.org/jgit/) as framework to work with Git repositories.
@@ -41,14 +42,14 @@ Features:
4142
```
4243
Or download release jars from https://github.com/scm4j/scm4j-vcs-git/releases
4344
- Code snippet
44-
```java
45+
```java
4546
public static final String WORKSPACE_DIR = System.getProperty("java.io.tmpdir") + "git-workspaces";
4647
IVCSWorkspace workspace = new VCSWorkspace(WORKSPACE_DIR);
4748
String repoUrl = "https://github.com/MyUser/MyRepo";
4849
IVCSRepositoryWorkspace repoWorkspace = workspace.getVCSRepositoryWorkspace(repoUrl);
4950
IVCS vcs = new GitVCS(repoWorkspace);
5051
vcs.setCredentials("user", "password"); // if necessary
51-
```
52+
```
5253
- Use methods of `IVCS` interface. See [scm4j-vcs-api](https://github.com/scm4j/scm4j-vcs-api) for details
5354
- Use `vcs.setProxy()` and `vcs.setCredentials()` if necessary
5455

src/main/java/org/scm4j/vcs/GitVCS.java

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -84,39 +84,29 @@ private String getRealBranchName(String branchName) {
8484
return branchName == null ? MASTER_BRANCH_NAME : branchName;
8585
}
8686

87-
public Git getLocalGit(IVCSLockedWorkingCopy wc) {
88-
Repository gitRepo;
89-
try {
90-
gitRepo = new FileRepositoryBuilder()
91-
.setGitDir(new File(wc.getFolder(), ".git"))
92-
.build();
93-
} catch (IOException e) {
94-
throw new RuntimeException(e);
95-
}
87+
public Git getLocalGit(IVCSLockedWorkingCopy wc) throws Exception {
88+
Repository gitRepo = new FileRepositoryBuilder()
89+
.setGitDir(new File(wc.getFolder(), ".git"))
90+
.build();
91+
9692
Boolean repoInited = gitRepo
9793
.getObjectDatabase()
9894
.exists();
99-
Git git = new Git(gitRepo);
10095
if (!repoInited) {
101-
try {
102-
Git
103-
.cloneRepository()
104-
.setDirectory(wc.getFolder())
105-
.setURI(repo.getRepoUrl())
106-
.setCredentialsProvider(credentials)
107-
.setNoCheckout(true)
108-
.setBranch(Constants.R_HEADS + Constants.MASTER)
109-
.call()
110-
.close();
111-
return git;
112-
} catch (Exception e) {
113-
throw new EVCSException(e);
114-
}
96+
Git
97+
.cloneRepository()
98+
.setDirectory(wc.getFolder())
99+
.setURI(repo.getRepoUrl())
100+
.setCredentialsProvider(credentials)
101+
.setNoCheckout(true)
102+
.setBranch(Constants.R_HEADS + Constants.MASTER)
103+
.call()
104+
.close();
115105
}
116-
return git;
106+
return new Git(gitRepo);
117107
}
118108

119-
private VCSChangeType gitChangeTypeToVCSChangeType(ChangeType changeType) {
109+
public VCSChangeType gitChangeTypeToVCSChangeType(ChangeType changeType) {
120110
switch (changeType) {
121111
case ADD:
122112
return VCSChangeType.ADD;
@@ -262,11 +252,11 @@ public VCSMergeResult merge(String srcBranchName, String dstBranchName, String c
262252

263253
@Override
264254
public void setCredentials(String user, String password) {
265-
credentials = new UsernamePasswordCredentialsProvider(user, password);
255+
setCredentials(new UsernamePasswordCredentialsProvider(user, password));
266256
}
267257

268258
@Override
269-
public void setProxy(final String host, final int port, String proxyUser, String proxyPassword) {
259+
public void setProxy(final String host, final int port, final String proxyUser, final String proxyPassword) {
270260
ProxySelector.setDefault(new ProxySelector() {
271261

272262
final ProxySelector delegate = ProxySelector.getDefault();
@@ -284,9 +274,21 @@ public List<Proxy> select(URI uri) {
284274

285275
@Override
286276
public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
287-
if (uri.toString().contains(repo.getRepoUrl())) {
288-
throw new RuntimeException("GitVCS proxy connect failed");
277+
if (delegate != null) {
278+
delegate.connectFailed(uri, sa, ioe);
279+
}
280+
}
281+
});
282+
Authenticator.setDefault(new Authenticator() {
283+
@Override
284+
protected PasswordAuthentication getPasswordAuthentication() {
285+
System.out.println(super.getRequestingSite().getHostName());
286+
System.out.println(repo.getRepoUrl());
287+
if (super.getRequestingSite().getHostName().contains(repo.getRepoUrl()) &&
288+
super.getRequestingPort() == port) {
289+
return new PasswordAuthentication(proxyUser, proxyPassword.toCharArray());
289290
}
291+
return super.getPasswordAuthentication();
290292
}
291293
});
292294
}

src/main/java/org/scm4j/vcs/GitVCSUtils.java

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,21 @@
22

33
import org.eclipse.jgit.api.Git;
44
import org.eclipse.jgit.api.errors.GitAPIException;
5-
import org.scm4j.vcs.api.exceptions.EVCSException;
65

76
import java.io.File;
87

98
public class GitVCSUtils {
109

11-
public static Git createRepository(File repoDir) {
12-
try {
13-
Git git = Git
14-
.init()
15-
.setDirectory(repoDir)
16-
.setBare(false)
17-
.call();
18-
git
19-
.commit()
20-
.setMessage("Initial commit")
21-
.call();
22-
return git;
23-
} catch (GitAPIException e) {
24-
throw new EVCSException(e);
25-
}
10+
public static Git createRepository(File repoDir) throws GitAPIException {
11+
Git git = Git
12+
.init()
13+
.setDirectory(repoDir)
14+
.setBare(false)
15+
.call();
16+
git
17+
.commit()
18+
.setMessage("Initial commit")
19+
.call();
20+
return git;
2621
}
2722
}

src/test/java/org/scm4j/vcs/GitVCSTest.java

Lines changed: 187 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,35 @@
11
package org.scm4j.vcs;
22

3-
import java.io.File;
4-
import java.io.IOException;
5-
63
import org.apache.commons.io.FileUtils;
74
import org.eclipse.jgit.api.Git;
5+
import org.eclipse.jgit.api.errors.GitAPIException;
6+
import org.eclipse.jgit.diff.DiffEntry;
87
import org.eclipse.jgit.lib.Repository;
8+
import org.eclipse.jgit.transport.CredentialItem;
99
import org.junit.After;
10+
import org.junit.Test;
1011
import org.mockito.Mockito;
12+
import org.mockito.exceptions.verification.WantedButNotInvoked;
1113
import org.scm4j.vcs.api.IVCS;
14+
import org.scm4j.vcs.api.VCSChangeType;
1215
import org.scm4j.vcs.api.abstracttest.VCSAbstractTest;
1316
import org.scm4j.vcs.api.workingcopy.IVCSRepositoryWorkspace;
1417

18+
import java.io.File;
19+
import java.io.IOException;
20+
import java.lang.reflect.InvocationTargetException;
21+
import java.lang.reflect.Method;
22+
import java.net.*;
23+
import java.nio.charset.IllegalCharsetNameException;
24+
import java.util.List;
25+
26+
import static org.junit.Assert.*;
27+
1528
public class GitVCSTest extends VCSAbstractTest {
1629

1730
private Repository localGitRepo;
18-
private final RuntimeException testGitResetException = new RuntimeException("test exeption on git.reset()");
31+
private ProxySelector proxySelectorBackup;
32+
private final RuntimeException testGitResetException = new RuntimeException("test exception on git.reset()");
1933

2034
@Override
2135
public void setUp() throws Exception {
@@ -26,12 +40,15 @@ public void setUp() throws Exception {
2640
.commit()
2741
.setMessage("Initial commit")
2842
.call();
43+
proxySelectorBackup = ProxySelector.getDefault();
44+
ProxySelector.setDefault(null);
2945
}
3046

3147
@After
3248
public void tearDown() throws IOException {
3349
localGitRepo.close();
3450
FileUtils.deleteDirectory(localGitRepo.getDirectory());
51+
ProxySelector.setDefault(proxySelectorBackup);
3552
}
3653

3754
@Override
@@ -45,7 +62,7 @@ protected IVCS getVCS(IVCSRepositoryWorkspace mockedVCSRepo) {
4562
}
4663

4764
@Override
48-
protected void setMakeFailureOnVCSReset(Boolean doMakeFailure) {
65+
protected void setMakeFailureOnVCSReset(Boolean doMakeFailure) throws Exception {
4966
Git mockedGit;
5067
if (doMakeFailure) {
5168
mockedGit = Mockito.spy(((GitVCS) vcs).getLocalGit(mockedLWC));
@@ -61,5 +78,170 @@ protected void setMakeFailureOnVCSReset(Boolean doMakeFailure) {
6178
protected String getVCSTypeString() {
6279
return GitVCS.GIT_VCS_TYPE_STRING;
6380
}
81+
82+
@Test
83+
public void testSetCredentials() {
84+
vcs.setCredentials("user", "password");
85+
CredentialItem.Username u = new CredentialItem.Username();
86+
CredentialItem.Password p = new CredentialItem.Password();
87+
assertTrue(((GitVCS) vcs).getCredentials().get(null, u, p));
88+
assertEquals(u.getValue(), "user");
89+
assertEquals(new String(p.getValue()), "password");
90+
}
91+
92+
@Test
93+
public void testProxyAuth() throws Exception {
94+
PasswordAuthentication initialAuth = Authenticator.requestPasswordAuthentication(InetAddress.getByName("localhost"),
95+
123, "http", "", "");
96+
IVCS vcs = new GitVCS(localVCSWorkspace.getVCSRepositoryWorkspace("localhost"));
97+
vcs.setProxy("localhost", 123, "username", "pwd");
98+
99+
PasswordAuthentication resultAuth = Authenticator.requestPasswordAuthentication(
100+
InetAddress.getByName("localhost"), 123, "http", "", "");
101+
assertEquals(resultAuth.getUserName(), "username");
102+
assertEquals(new String(resultAuth.getPassword()), "pwd");
103+
104+
resultAuth = Authenticator.requestPasswordAuthentication(
105+
InetAddress.getByName("localhost"), 124, "http", "", "");
106+
assertEquals(resultAuth, initialAuth);
107+
}
108+
109+
@Test
110+
public void testProxySelector() throws URISyntaxException {
111+
vcs.setProxy("localhost", 123, "username", "pwd");
112+
ProxySelector actualPS = ProxySelector.getDefault();
113+
List<Proxy> proxies = actualPS.select(new URI(vcs.getRepoUrl()));
114+
assertTrue(proxies.size() == 1);
115+
Proxy actualP = proxies.get(0);
116+
assertTrue(actualP.address() instanceof InetSocketAddress);
117+
InetSocketAddress isa = (InetSocketAddress) actualP.address();
118+
assertEquals(isa.getHostName(), "localhost");
119+
assertEquals(isa.getPort(), 123);
120+
}
121+
122+
@Test
123+
public void testParentProxySelectorUsage() throws URISyntaxException {
124+
ProxySelector mockedPS = Mockito.mock(ProxySelector.class);
125+
ProxySelector.setDefault(mockedPS);
126+
vcs.setProxy("localhost", 123, "username", "pwd");
127+
ProxySelector actualPS = ProxySelector.getDefault();
128+
URI uri = new URI("http://unknown");
129+
actualPS.select(uri);
130+
Mockito.verify(mockedPS).select(uri);
131+
}
132+
133+
@Test
134+
public void testNullProxySelector() throws URISyntaxException {
135+
ProxySelector.setDefault(null);
136+
vcs.setProxy("localhost", 123, "username", "pwd");
137+
ProxySelector actualPS = ProxySelector.getDefault();
138+
List<Proxy> proxies = actualPS.select(new URI("http://unknown"));
139+
assertTrue(proxies.size() == 1);
140+
assertEquals(proxies.get(0), Proxy.NO_PROXY);
141+
}
142+
143+
@Test
144+
public void testParentSelectorCallOnConnectFailed() throws URISyntaxException {
145+
ProxySelector mockedPS = Mockito.mock(ProxySelector.class);
146+
ProxySelector.setDefault(mockedPS);
147+
vcs.setProxy("localhost", 123, "username", "pwd");
148+
ProxySelector actualPS = ProxySelector.getDefault();
149+
URI testURI = new URI("http://proxy.net");
150+
SocketAddress testSA = InetSocketAddress.createUnresolved("http://proxy.net", 123);
151+
IOException testException = new IOException("test exception");
152+
actualPS.connectFailed(testURI, testSA, testException);
153+
Mockito.verify(mockedPS).connectFailed(testURI, testSA, testException);
154+
}
155+
@Test
156+
public void testNoParentSelectorOnConnectFailed() throws URISyntaxException {
157+
ProxySelector.setDefault(null);
158+
vcs.setProxy("localhost", 123, "username", "pwd");
159+
ProxySelector actualPS = Mockito.spy(ProxySelector.getDefault());
160+
URI testURI = new URI("http://proxy.net");
161+
SocketAddress testSA = InetSocketAddress.createUnresolved("http://proxy.net", 123);
162+
IOException testException = new IOException("test exception");
163+
actualPS.connectFailed(testURI, testSA, testException);
164+
Mockito.verify(actualPS).connectFailed(testURI, testSA, testException);
165+
Mockito.verifyNoMoreInteractions(actualPS);
166+
}
167+
168+
@Test
169+
public void testVCSTypeString() {
170+
assertEquals(vcs.getVCSTypeString(), GitVCS.GIT_VCS_TYPE_STRING);
171+
}
172+
173+
@Test
174+
public void testExceptions() throws Exception {
175+
GitAPIException eApi = new GitAPIException("test git exception") {};
176+
Exception eCommon = new Exception("test common exception");
177+
for (Method m : IVCS.class.getDeclaredMethods()) {
178+
Object[] params = new Object[m.getParameterTypes().length];
179+
Integer i = 0;
180+
for (Class clazz : m.getParameterTypes()) {
181+
params[i] = clazz.isPrimitive() ? 0: null;
182+
i++;
183+
}
184+
testExceptionThrowing(eApi, m, params);
185+
186+
testExceptionThrowing(eCommon, m, params);
187+
}
188+
}
189+
190+
private void testExceptionThrowing(Exception testException, Method m, Object[] params) throws Exception {
191+
Mockito.reset((GitVCS) vcs);
192+
Mockito.doThrow(testException).when((GitVCS) vcs).getLocalGit(mockedLWC);
193+
try {
194+
m.invoke(vcs, params);
195+
if (wasGetLocalGitInvoked(vcs)) {
196+
fail();
197+
}
198+
} catch (InvocationTargetException e) {
199+
if (wasGetLocalGitInvoked(vcs)) {
200+
assertTrue(e.getCause() instanceof RuntimeException);
201+
assertTrue(e.getCause().getMessage().contains(testException.getMessage()));
202+
}
203+
} catch (Exception e) {
204+
if (wasGetLocalGitInvoked(vcs)) {
205+
fail();
206+
}
207+
}
208+
}
209+
210+
private Boolean wasGetLocalGitInvoked(IVCS vcs) throws Exception {
211+
try {
212+
Mockito.verify((GitVCS) vcs).getLocalGit(mockedLWC);
213+
return true;
214+
} catch (WantedButNotInvoked e1) {
215+
return false;
216+
}
217+
}
218+
219+
@Test
220+
public void testDefaultChangeTypeToVCSType() {
221+
for (DiffEntry.ChangeType ct : DiffEntry.ChangeType.values()) {
222+
if (ct != DiffEntry.ChangeType.ADD && ct != DiffEntry.ChangeType.DELETE && ct != DiffEntry.ChangeType.MODIFY) {
223+
assertEquals(((GitVCS) vcs).gitChangeTypeToVCSChangeType(ct), VCSChangeType.UNKNOWN);
224+
}
225+
}
226+
}
227+
228+
@Test
229+
public void testGetFileContentExceptions() {
230+
vcs.setFileContent(null, FILE1_NAME, LINE_1, FILE1_ADDED_COMMIT_MESSAGE);
231+
try {
232+
vcs.getFileContent(null, FILE1_NAME, "wrong encoding");
233+
fail();
234+
} catch (RuntimeException e) {
235+
assertTrue(e.getCause() instanceof IllegalCharsetNameException);
236+
} catch (Exception e) {
237+
fail();
238+
}
239+
}
240+
241+
@Test
242+
public void testGitVCSUtilsCreation() {
243+
new GitVCSUtils();
244+
}
245+
64246
}
65247

0 commit comments

Comments
 (0)