Advertisement
Guest User

Untitled

a guest
Jun 21st, 2016
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.57 KB | None | 0 0
  1. package com.devfactory.qualitygate.scm.git;
  2.  
  3. import com.devfactory.qualitygate.scm.ScmRepository;
  4. import java.io.ByteArrayOutputStream;
  5. import java.io.IOException;
  6. import java.nio.file.Files;
  7. import java.nio.file.Path;
  8. import java.util.ArrayList;
  9. import java.util.List;
  10. import java.util.Objects;
  11. import java.util.Optional;
  12. import java.util.concurrent.ConcurrentHashMap;
  13. import java.util.concurrent.ConcurrentMap;
  14. import java.util.concurrent.locks.ReentrantLock;
  15. import java.util.stream.Collectors;
  16. import org.eclipse.jgit.api.CloneCommand;
  17. import org.eclipse.jgit.api.CreateBranchCommand;
  18. import org.eclipse.jgit.api.Git;
  19. import org.eclipse.jgit.api.errors.GitAPIException;
  20. import org.eclipse.jgit.internal.storage.file.LockFile;
  21. import org.eclipse.jgit.lib.Constants;
  22. import org.eclipse.jgit.lib.ObjectId;
  23. import org.eclipse.jgit.lib.ObjectLoader;
  24. import org.eclipse.jgit.lib.Repository;
  25. import org.eclipse.jgit.revwalk.RevCommit;
  26. import org.eclipse.jgit.revwalk.RevTree;
  27. import org.eclipse.jgit.revwalk.RevWalk;
  28. import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
  29. import org.eclipse.jgit.treewalk.TreeWalk;
  30. import org.eclipse.jgit.treewalk.filter.PathFilter;
  31. import org.slf4j.Logger;
  32. import org.slf4j.LoggerFactory;
  33.  
  34. class GitScmRepository implements ScmRepository {
  35.  
  36. private GitScmConfig config;
  37.  
  38. private UsernamePasswordCredentialsProvider credentialsProvider;
  39.  
  40. private static final Logger LOGGER = LoggerFactory.getLogger(GitScmRepository.class);
  41.  
  42. private static ConcurrentMap<String, ReentrantLock> repositoryLocks = new ConcurrentHashMap<>();
  43.  
  44. GitScmRepository(GitScmConfig config) {
  45. this.config = config;
  46. String username = config.getUsername();
  47. String password = config.getPassword();
  48. credentialsProvider = new UsernamePasswordCredentialsProvider(username, password);
  49. }
  50.  
  51. @Override
  52. public Path sync() {
  53. Optional<Git> git = open(getRepositoryHome());
  54. if (git.isPresent()) {
  55. clean(git.get());
  56. pull(git.get());
  57. checkout(git.get(), config.getBranch());
  58. } else {
  59. clone(getRepositoryHome(), config.getRepositoryUrl());
  60. }
  61. return getRepositoryHome();
  62. }
  63.  
  64. /**
  65. * Searches for a path according with it ending.
  66. *
  67. * @return List of found paths
  68. */
  69. @Override
  70. public List<Path> locate(String fileLocator) {
  71. try {
  72. getLock().lock();
  73. sync();
  74. return Files.walk(getRepositoryHome())
  75. .filter(f -> f.toFile().getAbsolutePath().endsWith(fromClassNameToPath(fileLocator)))
  76. .collect(Collectors.toList());
  77. } catch (IOException e) {
  78. LOGGER.error("Couldn't locate the specified file", e);
  79. } finally {
  80. getLock().unlock();
  81. }
  82. return new ArrayList<>();
  83. }
  84.  
  85. @Override
  86. public Optional<String> getContent(String fileLocator) {
  87. try {
  88. getLock().lock();
  89. sync();
  90. return getContent(getRepositoryHome(), fileLocator);
  91. } finally {
  92. getLock().unlock();
  93. }
  94. }
  95.  
  96. @Override
  97. public GitScmConfig getConfig() {
  98. return config;
  99. }
  100.  
  101. private void pull(Git git) {
  102. try {
  103. git.pull()
  104. .setCredentialsProvider(credentialsProvider)
  105. .call();
  106. } catch (GitAPIException e) {
  107. LOGGER.error("Pulling error {}", git.getRepository().getDirectory(), e);
  108. }
  109. }
  110.  
  111. private Optional<Git> open(Path repository) {
  112. try {
  113. Git git = Git.open(repository.toFile());
  114. return Optional.of(git);
  115. } catch (IOException e) {
  116. LOGGER.error("Couldn't open repository", e);
  117. }
  118. return Optional.empty();
  119. }
  120.  
  121. private void clone(Path directory, String repositoryUrl) {
  122. try {
  123. CloneCommand cloneCommand = Git.cloneRepository();
  124. cloneCommand.setDirectory(directory.toFile());
  125. cloneCommand.setURI(repositoryUrl);
  126. cloneCommand.setCloneAllBranches(true);
  127. cloneCommand.setCredentialsProvider(credentialsProvider);
  128. cloneCommand.call();
  129. } catch (GitAPIException e) {
  130. LOGGER.error("Couldn't clone specified repository", e);
  131. }
  132. }
  133.  
  134. private String getGitFileContent(Git git, String filePath) {
  135. filePath = fromClassNameToPath(filePath);
  136. try (Repository repository = git.getRepository()) {
  137. ObjectId lastCommitId = repository.resolve(Constants.HEAD);
  138.  
  139. try (RevWalk revWalk = new RevWalk(repository)) {
  140. RevCommit commit = revWalk.parseCommit(lastCommitId);
  141. RevTree tree = commit.getTree();
  142.  
  143. try (TreeWalk treeWalk = new TreeWalk(repository)) {
  144. treeWalk.addTree(tree);
  145. treeWalk.setRecursive(true);
  146. treeWalk.setFilter(PathFilter.create(filePath));
  147. if (!treeWalk.next()) {
  148. throw new IllegalStateException("Did not find expected file");
  149. }
  150.  
  151. ObjectId objectId = treeWalk.getObjectId(0);
  152. ObjectLoader loader = repository.open(objectId);
  153.  
  154. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  155. loader.copyTo(baos);
  156. String content = new String(baos.toByteArray());
  157. revWalk.dispose();
  158. return content;
  159. }
  160. }
  161. } catch (IOException e) {
  162. LOGGER.error("Couldn't get file content", e);
  163. }
  164. return "";
  165. }
  166.  
  167. private void checkout(Git git, String branch) {
  168. try {
  169. Boolean branchExists = Objects.nonNull(git.getRepository().findRef(branch));
  170. if (!branchExists) {
  171. git.branchCreate()
  172. .setName(branch)
  173. .setUpstreamMode(CreateBranchCommand.SetupUpstreamMode.TRACK)
  174. .setStartPoint("origin/" + branch)
  175. .call();
  176. }
  177. git.checkout().setName(branch).setForce(true).call();
  178. } catch (IOException | GitAPIException e) {
  179. LOGGER.error("Couldn't checkout repository", e);
  180. throw new IllegalStateException(
  181. "Couldn't checkout specified branch. Please check if the given branch exists.");
  182. }
  183. }
  184.  
  185. private Optional<String> getContent(Path repositoryHome, String fileLocator) {
  186. Optional<String> result = Optional.empty();
  187. try {
  188. Git git = Git.open(repositoryHome.toFile());
  189. result = Optional.of(getGitFileContent(git, fileLocator));
  190. } catch (IOException e) {
  191. LOGGER.error("Couldn't locate the specified file", e);
  192. }
  193. return result;
  194. }
  195.  
  196. private void clean(Git git) {
  197. try {
  198. git.clean().setCleanDirectories(true).call();
  199. LockFile.unlock(git.getRepository().getIndexFile());
  200. } catch (GitAPIException e) {
  201. LOGGER.error("Could not clean the repos", e);
  202. }
  203. }
  204.  
  205. private ReentrantLock getLock() {
  206. ReentrantLock lock = repositoryLocks.get(config.getRepositoryUrl());
  207. if (Objects.isNull(lock)) {
  208. lock = new ReentrantLock();
  209. repositoryLocks.put(config.getRepositoryUrl(), lock);
  210. }
  211. return lock;
  212. }
  213. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement