supporting cache the persists across runs (faster development)

This commit is contained in:
Brian Long 2021-01-07 15:36:51 -05:00
parent 77820bb25b
commit a076eb5986
2 changed files with 45 additions and 11 deletions

View File

@ -32,8 +32,8 @@ import org.slf4j.LoggerFactory;
public class ExtendedGit extends CachedGit {
private static final Pattern gitUrlPattern = Pattern.compile("(((ssh|http(s)?)://([^@]+@)?([^:/]+)(:[0-9]+)?/)|git@([^:]+):)([\\w\\.@\\:/\\-~]+)(\\.git)");
private final Logger logger = LoggerFactory.getLogger(ExtendedGit.class);
private final Pattern gitUrlPattern = Pattern.compile("(((ssh|http(s)?)://([^@]+@)?([^:/]+)(:[0-9]+)?/)|git@([^:]+):)([\\w\\.@\\:/\\-~]+)(\\.git)");
public ExtendedGit(Git git) {
super(git.getRepository());
@ -51,10 +51,13 @@ public class ExtendedGit extends CachedGit {
String gitUrl = this.getFirstRemoteUrl();
if (this.logger.isDebugEnabled())
this.logger.debug("Remote URL: " + gitUrl);
return getRepositoryFullyQualifiedName(gitUrl);
}
Matcher matcher = this.gitUrlPattern.matcher(gitUrl);
public static String getRepositoryFullyQualifiedName(String gitUrl) throws URISyntaxException {
Matcher matcher = gitUrlPattern.matcher(gitUrl);
if (!matcher.find())
throw new URISyntaxException(gitUrl, "The Git URL does not match the expected regular expression: " + this.gitUrlPattern.toString());
throw new URISyntaxException(gitUrl, "The Git URL does not match the expected regular expression: " + gitUrlPattern.toString());
return matcher.group(9);
}

View File

@ -16,6 +16,7 @@ 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.api.errors.TransportException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.util.FileUtils;
import org.slf4j.Logger;
@ -36,13 +37,24 @@ public class LocalRepositoryCache {
private final LRUExpiringHashMap<String, CachedGit> cachedGits = new LRUExpiringHashMap<>(30);
private final Map<String, Semaphore> gitUrlSemaphores = new HashMap<>();
final File cacheDirectory = new File(System.getProperty("java.io.tmpdir"), "git");
private final int simultaneousProcessesPerGitRepo = 1;
private int simultaneousThreadsPerGitRepo = 1;
private LocalRepositoryCache() {
this.cacheDirectory.mkdir();
this.cachedGits.addListener(new RepositoryCacheMapListener<CachedGit>());
}
/**
* This is helpful for the tweaking performance based on the environment of
* execution. A value of 1 disables concurrency which results in the
* persistence of Git Repositories between executions and disables cache
* expiration. This is great for development, testing, and command line
* usage. It is not recommended with web service frontends.
*/
public void setSimultaneousThreadsPerGitRepository(int threads) {
this.simultaneousThreadsPerGitRepo = threads;
}
@Override
protected void finalize() throws Throwable {
try {
@ -91,17 +103,32 @@ public class LocalRepositoryCache {
synchronized (this) {
semaphore = this.gitUrlSemaphores.get(url);
if (semaphore == null)
this.gitUrlSemaphores.put(url, semaphore = new Semaphore(this.simultaneousProcessesPerGitRepo));
this.gitUrlSemaphores.put(url, semaphore = new Semaphore(this.simultaneousThreadsPerGitRepo));
}
File gitRepoDirectory = null;
semaphore.acquire();
try {
CachedGit git = this.cachedGits.remove(url);
if (git == null) {
File gitRepoDirectory = new File(this.cacheDirectory, UUID.randomUUID().toString() + ".git");
String directoryBaseName;
if (this.simultaneousThreadsPerGitRepo == 1)
directoryBaseName = ExtendedGit.getRepositoryFullyQualifiedName(url).replace('/', '_');
else directoryBaseName = UUID.randomUUID().toString();
gitRepoDirectory = new File(this.cacheDirectory, directoryBaseName + ".git");
if (this.logger.isDebugEnabled())
this.logger.debug("Git directory cache for clone: " + gitRepoDirectory);
if (gitRepoDirectory.exists()) {
if (this.logger.isInfoEnabled())
this.logger.info("Git Repository already exists; reusing: " + gitRepoDirectory);
git = creds != null ? new CredentialedGit(Git.open(gitRepoDirectory), creds) : new ExtendedGit(Git.open(gitRepoDirectory));
}
}
if (git == null) {
CloneCommand clone = new CloneCommand()
.setURI(url)
.setDirectory(gitRepoDirectory);
@ -115,13 +142,17 @@ public class LocalRepositoryCache {
this.logger.info("Cloned Git Repository: " + ((ExtendedGit)git).getRepositoryFullyQualifiedName());
} else {
if (this.logger.isDebugEnabled())
this.logger.debug("reseting Git");
this.logger.debug("resetting Git");
git.reset().setMode(ResetType.HARD).call();
if (branch != null) {
if (branch != null && !branch.equals(git.getRepository().getBranch())) {
if (this.logger.isDebugEnabled())
this.logger.debug("switching Git branches: " + branch);
git.checkout().setName(branch).call();
if (git.getRepository().exactRef(Constants.R_HEADS + branch) == null) {
git.checkout().setName(branch).setStartPoint("origin/" + branch).setCreateBranch(true).call();
} else {
git.checkout().setName(branch).call();
}
}
if (this.logger.isDebugEnabled())