Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.devfactory.qualitygate.scm.git;
- import com.devfactory.qualitygate.scm.ScmRepository;
- import java.io.ByteArrayOutputStream;
- import java.io.IOException;
- import java.nio.file.Files;
- import java.nio.file.Path;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Objects;
- import java.util.Optional;
- import java.util.concurrent.ConcurrentHashMap;
- import java.util.concurrent.ConcurrentMap;
- import java.util.concurrent.locks.ReentrantLock;
- import java.util.stream.Collectors;
- import org.eclipse.jgit.api.CloneCommand;
- import org.eclipse.jgit.api.CreateBranchCommand;
- import org.eclipse.jgit.api.Git;
- import org.eclipse.jgit.api.errors.GitAPIException;
- import org.eclipse.jgit.internal.storage.file.LockFile;
- import org.eclipse.jgit.lib.Constants;
- import org.eclipse.jgit.lib.ObjectId;
- import org.eclipse.jgit.lib.ObjectLoader;
- import org.eclipse.jgit.lib.Repository;
- import org.eclipse.jgit.revwalk.RevCommit;
- import org.eclipse.jgit.revwalk.RevTree;
- import org.eclipse.jgit.revwalk.RevWalk;
- import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
- import org.eclipse.jgit.treewalk.TreeWalk;
- import org.eclipse.jgit.treewalk.filter.PathFilter;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- class GitScmRepository implements ScmRepository {
- private GitScmConfig config;
- private UsernamePasswordCredentialsProvider credentialsProvider;
- private static final Logger LOGGER = LoggerFactory.getLogger(GitScmRepository.class);
- private static ConcurrentMap<String, ReentrantLock> repositoryLocks = new ConcurrentHashMap<>();
- GitScmRepository(GitScmConfig config) {
- this.config = config;
- String username = config.getUsername();
- String password = config.getPassword();
- credentialsProvider = new UsernamePasswordCredentialsProvider(username, password);
- }
- @Override
- public Path sync() {
- Optional<Git> git = open(getRepositoryHome());
- if (git.isPresent()) {
- clean(git.get());
- pull(git.get());
- checkout(git.get(), config.getBranch());
- } else {
- clone(getRepositoryHome(), config.getRepositoryUrl());
- }
- return getRepositoryHome();
- }
- /**
- * Searches for a path according with it ending.
- *
- * @return List of found paths
- */
- @Override
- public List<Path> locate(String fileLocator) {
- try {
- getLock().lock();
- sync();
- return Files.walk(getRepositoryHome())
- .filter(f -> f.toFile().getAbsolutePath().endsWith(fromClassNameToPath(fileLocator)))
- .collect(Collectors.toList());
- } catch (IOException e) {
- LOGGER.error("Couldn't locate the specified file", e);
- } finally {
- getLock().unlock();
- }
- return new ArrayList<>();
- }
- @Override
- public Optional<String> getContent(String fileLocator) {
- try {
- getLock().lock();
- sync();
- return getContent(getRepositoryHome(), fileLocator);
- } finally {
- getLock().unlock();
- }
- }
- @Override
- public GitScmConfig getConfig() {
- return config;
- }
- private void pull(Git git) {
- try {
- git.pull()
- .setCredentialsProvider(credentialsProvider)
- .call();
- } catch (GitAPIException e) {
- LOGGER.error("Pulling error {}", git.getRepository().getDirectory(), e);
- }
- }
- private Optional<Git> open(Path repository) {
- try {
- Git git = Git.open(repository.toFile());
- return Optional.of(git);
- } catch (IOException e) {
- LOGGER.error("Couldn't open repository", e);
- }
- return Optional.empty();
- }
- private void clone(Path directory, String repositoryUrl) {
- try {
- CloneCommand cloneCommand = Git.cloneRepository();
- cloneCommand.setDirectory(directory.toFile());
- cloneCommand.setURI(repositoryUrl);
- cloneCommand.setCloneAllBranches(true);
- cloneCommand.setCredentialsProvider(credentialsProvider);
- cloneCommand.call();
- } catch (GitAPIException e) {
- LOGGER.error("Couldn't clone specified repository", e);
- }
- }
- private String getGitFileContent(Git git, String filePath) {
- filePath = fromClassNameToPath(filePath);
- try (Repository repository = git.getRepository()) {
- ObjectId lastCommitId = repository.resolve(Constants.HEAD);
- try (RevWalk revWalk = new RevWalk(repository)) {
- RevCommit commit = revWalk.parseCommit(lastCommitId);
- RevTree tree = commit.getTree();
- try (TreeWalk treeWalk = new TreeWalk(repository)) {
- treeWalk.addTree(tree);
- treeWalk.setRecursive(true);
- treeWalk.setFilter(PathFilter.create(filePath));
- if (!treeWalk.next()) {
- throw new IllegalStateException("Did not find expected file");
- }
- ObjectId objectId = treeWalk.getObjectId(0);
- ObjectLoader loader = repository.open(objectId);
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- loader.copyTo(baos);
- String content = new String(baos.toByteArray());
- revWalk.dispose();
- return content;
- }
- }
- } catch (IOException e) {
- LOGGER.error("Couldn't get file content", e);
- }
- return "";
- }
- private void checkout(Git git, String branch) {
- try {
- Boolean branchExists = Objects.nonNull(git.getRepository().findRef(branch));
- if (!branchExists) {
- git.branchCreate()
- .setName(branch)
- .setUpstreamMode(CreateBranchCommand.SetupUpstreamMode.TRACK)
- .setStartPoint("origin/" + branch)
- .call();
- }
- git.checkout().setName(branch).setForce(true).call();
- } catch (IOException | GitAPIException e) {
- LOGGER.error("Couldn't checkout repository", e);
- throw new IllegalStateException(
- "Couldn't checkout specified branch. Please check if the given branch exists.");
- }
- }
- private Optional<String> getContent(Path repositoryHome, String fileLocator) {
- Optional<String> result = Optional.empty();
- try {
- Git git = Git.open(repositoryHome.toFile());
- result = Optional.of(getGitFileContent(git, fileLocator));
- } catch (IOException e) {
- LOGGER.error("Couldn't locate the specified file", e);
- }
- return result;
- }
- private void clean(Git git) {
- try {
- git.clean().setCleanDirectories(true).call();
- LockFile.unlock(git.getRepository().getIndexFile());
- } catch (GitAPIException e) {
- LOGGER.error("Could not clean the repos", e);
- }
- }
- private ReentrantLock getLock() {
- ReentrantLock lock = repositoryLocks.get(config.getRepositoryUrl());
- if (Objects.isNull(lock)) {
- lock = new ReentrantLock();
- repositoryLocks.put(config.getRepositoryUrl(), lock);
- }
- return lock;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement