initial checkin

This commit is contained in:
Brian Long 2020-12-01 10:18:56 -05:00
commit 13e190fd5c
18 changed files with 975 additions and 0 deletions

8
.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
# Maven
target
# Eclipse
.project
.classpath
.settings

77
pom.xml Normal file
View File

@ -0,0 +1,77 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>me.brianlong</groupId>
<artifactId>github-api</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>GitHub API &amp; Utilities</name>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
<version>5.9.0.202009080501-r</version>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.ssh.jsch</artifactId>
<version>5.9.0.202009080501-r</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.12</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>unit-tests</id>
<phase>test</phase>
<goals><goal>test</goal></goals>
<configuration>
<excludes>
<exclude>**/*IT.class</exclude>
</excludes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

16
src/jetty/log4j2.xml Normal file
View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="[%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="me.brianlong" level="trace" additivity="false">
<AppenderRef ref="STDOUT" />
</Logger>
<Root level="trace">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>

View File

@ -0,0 +1,29 @@
package me.brianlong.git;
import org.eclipse.jgit.api.CloneCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.InvalidRemoteException;
import org.eclipse.jgit.api.errors.TransportException;
import org.eclipse.jgit.lib.Repository;
public class CachedGit extends Git {
public CachedGit(Git git) {
super(git.getRepository());
}
public CachedGit(CloneCommand clone) throws TransportException, InvalidRemoteException, GitAPIException {
super(clone.call().getRepository());
}
public CachedGit(Repository repo) {
super(repo);
}
@Override
public void close() {
LocalRepositoryCache.getInstance().release(this);
}
}

View File

@ -0,0 +1,53 @@
package me.brianlong.git;
import org.eclipse.jgit.api.CloneCommand;
import org.eclipse.jgit.api.FetchCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.LsRemoteCommand;
import org.eclipse.jgit.api.PullCommand;
import org.eclipse.jgit.api.PushCommand;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.InvalidRemoteException;
import org.eclipse.jgit.api.errors.TransportException;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.transport.CredentialsProvider;
public class CredentialedGit extends CachedGit {
private CredentialsProvider credProvider;
public CredentialedGit(CloneCommand clone, GitCredentials creds) throws TransportException, InvalidRemoteException, GitAPIException {
this(clone.setCredentialsProvider(creds.toJGitCredentialsProvider()).call(), creds);
}
public CredentialedGit(Git git, GitCredentials creds) {
super(git.getRepository());
this.credProvider = creds.toJGitCredentialsProvider();
}
public CredentialedGit(Repository repo, GitCredentials creds) {
super(repo);
this.credProvider = creds.toJGitCredentialsProvider();
}
@Override
public FetchCommand fetch() {
return super.fetch().setCredentialsProvider(this.credProvider);
}
@Override
public LsRemoteCommand lsRemote() {
return super.lsRemote().setCredentialsProvider(this.credProvider);
}
@Override
public PullCommand pull() {
return super.pull().setCredentialsProvider(this.credProvider);
}
@Override
public PushCommand push() {
return super.push().setCredentialsProvider(this.credProvider);
}
}

View File

@ -0,0 +1,9 @@
package me.brianlong.git;
import java.util.Map.Entry;
public interface ExpiringMapListener<K, V> extends MapListener<K, V> {
void expired(Entry<K, V> entry);
}

View File

@ -0,0 +1,26 @@
package me.brianlong.git;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
public class GitCredentials extends UsernamePasswordCredentials {
private static final long serialVersionUID = -8811637815236347412L;
public GitCredentials(String username, String passwordOrToken) {
super(username, passwordOrToken);
}
public org.apache.http.client.CredentialsProvider toHttpClientCredentialsProvider() {
org.apache.http.client.CredentialsProvider credProvider = new BasicCredentialsProvider();
credProvider.setCredentials(AuthScope.ANY, this);
return credProvider;
}
public org.eclipse.jgit.transport.CredentialsProvider toJGitCredentialsProvider() {
return new UsernamePasswordCredentialsProvider(this.getUserName(), this.getPassword());
}
}

View File

@ -0,0 +1,242 @@
package me.brianlong.git;
import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
// TODO need to implement the actual expiration schedule
public class LRUExpiringHashMap<K extends Serializable, V> implements ListeningMap<K, V> {
private final Map<ExpiringHashKey, V> map;
private final List<MapListener<K, V>> listeners = new LinkedList<MapListener<K, V>>();
private final long expirationTimeMillis;
public LRUExpiringHashMap(int expirationTimeInMinutes) {
this.map = new LinkedHashMap<ExpiringHashKey, V>();
this.expirationTimeMillis = expirationTimeInMinutes * 60L + 1000L;
}
public LRUExpiringHashMap(int expirationTimeInMinutes, int initialCapacity) {
this.map = new LinkedHashMap<ExpiringHashKey, V>(initialCapacity);
this.expirationTimeMillis = expirationTimeInMinutes * 60L + 1000L;
}
@Override
public void addListener(MapListener<K, V> listener) {
this.listeners.add(listener);
}
@Override
public boolean containsKey(Object key) {
return this.map.containsKey(key);
}
@Override
public boolean containsValue(Object value) {
return this.map.containsValue(value);
}
@Override
public Set<Entry<K, V>> entrySet() {
throw new UnsupportedOperationException();
}
@Override
public Set<K> keySet() {
throw new UnsupportedOperationException();
}
@Override
public Collection<V> values() {
throw new UnsupportedOperationException();
}
@Override
public boolean isEmpty() {
return this.map.isEmpty();
}
@Override
public int size() {
return this.map.size();
}
@Override
@SuppressWarnings("unchecked")
public V get(Object key) {
if (!this.map.containsKey(key))
return null;
// remove and put to move the entry to the end of the map; helping with finding expired entries
V value = this.map.remove(key);
this.map.put(new ExpiringHashKey((K)key, System.currentTimeMillis() + this.expirationTimeMillis), value);
for (MapListener<K, V> listener : this.listeners)
listener.accessed(new ExpiringHashMapEntry((K)key, value));
return value;
}
@Override
public V put(K key, V value) {
ExpiringHashKey ehkey = new ExpiringHashKey(key, System.currentTimeMillis() + this.expirationTimeMillis);
V oldValue = this.map.put(ehkey, value);
for (MapListener<K, V> listener : this.listeners)
listener.added(new ExpiringHashMapEntry(key, value));
return oldValue;
}
@Override
public void clear() {
for (Entry<ExpiringHashKey, V> entry : this.map.entrySet()) {
for (MapListener<K, V> listener : this.listeners)
listener.cleared(new ExpiringHashMapEntry(entry.getKey().getKey(), entry.getValue()));
}
this.map.clear();
}
@SuppressWarnings("unchecked")
@Override
public V remove(Object key) {
if (!this.map.containsKey(key))
return null;
V value = this.map.remove(key);
for (MapListener<K, V> listener : this.listeners)
listener.removed(new ExpiringHashMapEntry((K)key, value));
return value;
}
@Override
public void putAll(Map<? extends K, ? extends V> m) {
throw new UnsupportedOperationException();
}
@Override
public int hashCode() {
return this.map.hashCode();
}
@Override
public boolean equals(Object obj) {
return this.map.equals(obj);
}
public void exipriationCheck() {
Iterator<Entry<ExpiringHashKey, V>> i = this.map.entrySet().iterator();
for (Entry<ExpiringHashKey, V> entry = i.next(); i.hasNext(); entry = i.next()) {
if (entry.getKey().isExpired()) {
i.remove();
for (MapListener<K, V> listener : this.listeners)
if (listener instanceof ExpiringMapListener)
((ExpiringMapListener<K, V>)listener).expired(new ExpiringHashMapEntry(entry.getKey().getKey(), entry.getValue()));
}
}
}
public void expire(K key) {
if (!this.map.containsKey(key))
return;
V value = this.map.remove(key);
for (MapListener<K, V> listener : this.listeners)
if (listener instanceof ExpiringMapListener)
((ExpiringMapListener<K, V>)listener).expired(new ExpiringHashMapEntry(key, value));
}
private class ExpiringHashMapEntry implements Entry<K, V> {
private final K key;
private V value;
public ExpiringHashMapEntry(K key, V value) {
this.key = key;
this.value = value;
}
@Override
public K getKey() {
return this.key;
}
@Override
public V getValue() {
return this.value;
}
@Override
public V setValue(V value) {
return this.value = value;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Entry<?, ?>) {
return this.key.equals(((Entry<?, ?>)obj).getKey()) && this.value.equals(((Entry<?, ?>)obj).getValue());
} else {
return false;
}
}
@Override
public int hashCode() {
return this.key.hashCode() + this.value.hashCode();
}
@Override
public String toString() {
return "{" + this.key + ", " + this.value + "}";
}
}
private class ExpiringHashKey implements Serializable {
private static final long serialVersionUID = -6511298315143655313L;
private long expirationTimeInMillis;
private K key;
public ExpiringHashKey(K key, long expirationTimeInMillis) {
this.key = key;
this.expirationTimeInMillis = expirationTimeInMillis;
}
public K getKey() {
return this.key;
}
public boolean isExpired() {
return this.expirationTimeInMillis <= System.currentTimeMillis();
}
@Override
public int hashCode() {
return this.key.hashCode();
}
@Override
public String toString() {
return this.key.toString();
}
@Override
@SuppressWarnings("unchecked")
public boolean equals(Object obj) {
if (obj instanceof LRUExpiringHashMap.ExpiringHashKey) {
return this.key.equals(((ExpiringHashKey)obj).key);
} else {
return this.key.equals(obj);
}
}
}
}

View File

@ -0,0 +1,9 @@
package me.brianlong.git;
import java.util.Map;
public interface ListeningMap<K, V> extends Map<K, V> {
void addListener(MapListener<K, V> listener);
}

View File

@ -0,0 +1,151 @@
package me.brianlong.git;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
import org.eclipse.jgit.api.CloneCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.InvalidRemoteException;
import org.eclipse.jgit.api.errors.RefNotFoundException;
import org.eclipse.jgit.util.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LocalRepositoryCache {
private static final LocalRepositoryCache INSTANCE = new LocalRepositoryCache();
public static LocalRepositoryCache getInstance() {
return INSTANCE;
}
private final Logger logger = LoggerFactory.getLogger(LocalRepositoryCache.class);
private final LRUExpiringHashMap<String, Git> cachedGits = new LRUExpiringHashMap<String, Git>(30);
private final Map<String, String> gitIdsToUrls = new HashMap<String, String>();
private final File cacheDirectory = new File(System.getProperty("java.io.tmpdir"), "git");
private LocalRepositoryCache() {
this.cacheDirectory.mkdir();
this.cachedGits.addListener(new RepositoryCacheMapListener());
}
@Override
protected void finalize() throws Throwable {
try {
this.destroy();
} finally {
super.finalize();
}
}
private void destroy() {
if (this.logger.isInfoEnabled())
this.logger.info("destroy()");
this.clear();
}
public synchronized Git acquire(String url) throws GitAPIException, InvalidRemoteException, RefNotFoundException {
return this.acquire(url, null, null);
}
public synchronized Git acquire(String url, GitCredentials creds) throws GitAPIException, InvalidRemoteException, RefNotFoundException {
return this.acquire(url, creds, null);
}
public synchronized Git acquire(String url, String branch) throws GitAPIException, InvalidRemoteException, RefNotFoundException {
return this.acquire(url, null, branch);
}
public synchronized Git acquire(String url, GitCredentials creds, String branch) throws GitAPIException, InvalidRemoteException, RefNotFoundException {
Git git = this.cachedGits.remove(url);
if (git == null) {
File gitRepoDirectory = new File(this.cacheDirectory, UUID.randomUUID().toString() + ".git");
CloneCommand clone = new CloneCommand()
.setURI(url)
.setDirectory(gitRepoDirectory);
if (branch != null)
clone.setBranch(branch);
git = creds != null ? new CredentialedGit(clone, creds) : new CachedGit(clone);
this.gitIdsToUrls.put(git.getRepository().getIdentifier(), url);
} else {
if (branch != null)
git.checkout().setName(branch).call();
git.pull().call();
}
return git;
}
public synchronized void release(Git git) {
String sshUrl = this.gitIdsToUrls.get(git.getRepository().getIdentifier());
this.cachedGits.put(sshUrl, git);
}
public synchronized void clear() {
this.cachedGits.clear();
}
private class RepositoryCacheMapListener implements ExpiringMapListener<String, Git> {
@Override
public void accessed(Entry<String, Git> entry) {
}
@Override
public void added(Entry<String, Git> entry) {
// a clean one or one returned after being previously removed
}
@Override
public void expired(Entry<String, Git> entry) {
this.expunge(entry.getValue());
}
@Override
public void removed(Entry<String, Git> entry) {
// expected to be removed only temporarily...for use elsewhere; do not close
}
@Override
public void cleared(Entry<String, Git> entry) {
this.expunge(entry.getValue());
}
private void expunge(Git git) {
gitIdsToUrls.remove(git.getRepository().getIdentifier());
File gitDir = git.getRepository().getDirectory();
File workingTreeDir = git.getRepository().getWorkTree();
git.getRepository().close();
try {
FileUtils.delete(gitDir, FileUtils.RECURSIVE);
} catch (IOException ie) {
logger.warn("Failed to delete a git directory: " + gitDir);
if (logger.isDebugEnabled())
logger.debug(ie.getMessage(), ie);
gitDir.deleteOnExit();
}
try {
FileUtils.delete(workingTreeDir, FileUtils.RECURSIVE);
} catch (IOException ie) {
logger.warn("Failed to delete a git directory: " + workingTreeDir);
if (logger.isDebugEnabled())
logger.debug(ie.getMessage(), ie);
workingTreeDir.deleteOnExit();
}
}
}
}

View File

@ -0,0 +1,15 @@
package me.brianlong.git;
import java.util.Map.Entry;
public interface MapListener<K, V> {
void added(Entry<K, V> entry);
void accessed(Entry<K, V> entry);
void removed(Entry<K, V> entry);
void cleared(Entry<K, V> entry);
}

View File

@ -0,0 +1,30 @@
package me.brianlong.github.model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
@JsonIgnoreProperties(ignoreUnknown = true)
public class CreateReference {
@JsonProperty(required = true)
private String ref;
@JsonProperty(required = true)
private String sha;
public String getRef() {
return this.ref;
}
public void setRef(String ref) {
this.ref = ref;
}
public String getSha() {
return this.sha;
}
public void setSha(String sha) {
this.sha = sha;
}
}

View File

@ -0,0 +1,68 @@
package me.brianlong.github.model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
@JsonIgnoreProperties(ignoreUnknown = true)
public class PullRequest {
@JsonProperty(required = true)
private String title;
@JsonProperty(required = true)
private String head;
@JsonProperty(required = true)
private String base;
private String body;
@JsonProperty(value = "maintainer_can_modify")
private Boolean maintainerCanModify;
private Boolean draft;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getHead() {
return head;
}
public void setHead(String head) {
this.head = head;
}
public String getBase() {
return base;
}
public void setBase(String base) {
this.base = base;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public Boolean getMaintainerCanModify() {
return maintainerCanModify;
}
public void setMaintainerCanModify(Boolean maintainerCanModify) {
this.maintainerCanModify = maintainerCanModify;
}
public Boolean getDraft() {
return draft;
}
public void setDraft(Boolean draft) {
this.draft = draft;
}
}

View File

@ -0,0 +1,37 @@
package me.brianlong.http;
import java.io.IOException;
import org.apache.http.HttpException;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.AuthState;
import org.apache.http.auth.Credentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.HttpCoreContext;
public class PreemptiveAuthInterceptor implements HttpRequestInterceptor {
public void process(final HttpRequest request, final HttpContext context) throws HttpException, IOException {
AuthState authState = (AuthState) context.getAttribute(HttpClientContext.TARGET_AUTH_STATE);
// If no auth scheme available yet, try to initialize it
// preemptively
if (authState.getAuthScheme() == null) {
CredentialsProvider credsProvider = (CredentialsProvider) context.getAttribute(HttpClientContext.CREDS_PROVIDER);
HttpHost targetHost = (HttpHost) context.getAttribute(HttpCoreContext.HTTP_TARGET_HOST);
Credentials creds = credsProvider.getCredentials(new AuthScope(targetHost.getHostName(), targetHost.getPort()));
if (creds == null) {
throw new HttpException("No credentials for preemptive authentication");
}
authState.update(new BasicScheme(), creds);
}
}
}

View File

@ -0,0 +1,51 @@
package me.brianlong.git;
import java.io.File;
import java.io.IOException;
import java.util.List;
import org.eclipse.jgit.api.CloneCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.ListBranchCommand.ListMode;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.Ref;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
public class CommandUnitTest {
private final static GitHubTestCredentials githubCreds = new GitHubTestCredentials();
private static File tmpdir;
private static Git git;
@BeforeClass
public static void init() throws GitAPIException, IOException {
tmpdir = new File(System.getProperty("java.io.tmpdir"), "git.tmp");
tmpdir.mkdirs();
git = new CloneCommand()
.setURI("git@github.com:bmlong137/env-docker-adbp.git")
.setCredentialsProvider(githubCreds.toJGitCredentialsProvider())
.setDirectory(tmpdir)
.call();
}
@AfterClass
public static void cleanup() {
git.getRepository().close();
git.close();
tmpdir.deleteOnExit();
}
@Test
public void lotsOfBranches() throws GitAPIException {
List<Ref> remoteBranches = git.branchList().setListMode(ListMode.REMOTE).call();
Assert.assertNotNull(remoteBranches);
Assert.assertTrue(remoteBranches.size() > 5);
}
}

View File

@ -0,0 +1,11 @@
package me.brianlong.git;
public class GitHubTestCredentials extends GitCredentials {
private static final long serialVersionUID = -4460599306349661667L;
public GitHubTestCredentials() {
super(System.getProperty("github.username"), System.getProperty("github.token"));
}
}

View File

@ -0,0 +1,124 @@
package me.brianlong.git;
import java.io.IOException;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.InvalidRemoteException;
import org.eclipse.jgit.api.errors.TransportException;
import org.eclipse.jgit.lib.Repository;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Test;
public class LocalRepositoryCacheUnitTest {
private final static GitHubTestCredentials githubCreds = new GitHubTestCredentials();
@AfterClass
public static void cleanup() {
LocalRepositoryCache.getInstance().clear();
}
/**
* Since "host-does-not-exist.com" does not exist, an UnknownHostException
* is thrown. It is wrapped inside a JGit TransportException.
*/
@Test(expected = TransportException.class)
public void cacheBadHostRepo() throws GitAPIException {
LocalRepositoryCache.getInstance().acquire("https://host-does-not-exist.com/bmlong137/does-not-exist.git");
}
/**
* Since "does-not-exist" isn't a public repo, it requires authentication
* to even check to see if it is private. This causes a
* NoRemoteRepositoryException which is wrapped inside a JGit
* InvalidRemoteException. This is because SSH authentication makes this
* more like cacheNonExistentRepoAuth() than cacheNonExistentRepo().
*/
@Test(expected = InvalidRemoteException.class)
public void cacheNonExistentRepoViaSsh() throws GitAPIException {
LocalRepositoryCache.getInstance().acquire("git@github.com:bmlong137/does-not-exist.git");
}
/**
* Since "does-not-exist" isn't a public repo, it requires authentication
* to even check to see if it is private. This causes a JSchException
* which is wrapped inside a JGit TransportException.
*/
@Test(expected = TransportException.class)
public void cacheNonExistentRepo() throws GitAPIException {
LocalRepositoryCache.getInstance().acquire("https://github.com/bmlong137/does-not-exist.git");
}
/**
* Since "does-not-exist" isn't a repo, a NoRemoteRepositoryException is
* thrown. It is wrapped inside a JGit InvalidRemoteException.
*/
@Test(expected = InvalidRemoteException.class)
public void cacheNonExistentRepoAuth() throws GitAPIException {
LocalRepositoryCache.getInstance().acquire("https://github.com/bmlong137/does-not-exist.git", githubCreds);
}
@Test
public void cachePublicRepo() throws GitAPIException {
Git git = LocalRepositoryCache.getInstance().acquire("https://github.com/bmlong137/maven-file-management.git");
try {
this.validateGenericGitRepo(git);
} finally {
git.close();
}
}
@Test
public void cachePublicRepoViaSsh() throws GitAPIException {
Git git = LocalRepositoryCache.getInstance().acquire("git@github.com:bmlong137/maven-file-management.git");
try {
this.validateGenericGitRepo(git);
} finally {
git.close();
}
}
/**
* Since "github-api" isn't a public repo, it requires authentication
* to even check to see if it is private. This causes a JSchException
* which is wrapped inside a JGit TransportException.
*/
@Test(expected = TransportException.class)
public void cachePrivateRepoUnauth() throws GitAPIException {
LocalRepositoryCache.getInstance().acquire("https://github.com/bmlong137/github-api.git");
}
@Test
public void cachePrivateRepo() throws GitAPIException {
Git git = LocalRepositoryCache.getInstance().acquire("https://github.com/bmlong137/github-api.git", githubCreds);
try {
this.validateGenericGitRepo(git);
} finally {
git.close();
}
}
@Test
public void cachePublicRepoBranch() throws GitAPIException, IOException {
Git git = LocalRepositoryCache.getInstance().acquire("https://github.com/bmlong137/maven-file-management.git", "master");
try {
this.validateGenericGitRepo(git);
Assert.assertEquals("master", git.getRepository().getBranch());
} finally {
git.close();
}
}
private void validateGenericGitRepo(Git git) throws GitAPIException {
Assert.assertNotNull(git);
Repository repo = git.getRepository();
Assert.assertTrue(repo.getDirectory().exists());
Assert.assertTrue(repo.getWorkTree().exists());
Assert.assertTrue(repo.getWorkTree().listFiles().length > 0);
}
}

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="[%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="me.brianlong" level="trace" additivity="false">
<AppenderRef ref="STDOUT" />
</Logger>
<Logger name="org.apache.http" level="trace" additivity="false">
<AppenderRef ref="STDOUT" />
</Logger>
<Root level="trace">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>