You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ma...@apache.org on 2024/10/24 13:02:39 UTC
(camel-karavan) 04/09: Git Improvements
This is an automated email from the ASF dual-hosted git repository.
marat pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-karavan.git
commit f183adf3be7874ee4b124aaa6f13470e0b13f669
Author: Marat Gubaidullin <ma...@talismancloud.io>
AuthorDate: Thu Oct 24 09:00:34 2024 -0400
Git Improvements
---
.../apache/camel/karavan/service/GitService.java | 88 +++++++++++++++++++++-
1 file changed, 87 insertions(+), 1 deletion(-)
diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/service/GitService.java b/karavan-app/src/main/java/org/apache/camel/karavan/service/GitService.java
index d1e81300..83660f3b 100644
--- a/karavan-app/src/main/java/org/apache/camel/karavan/service/GitService.java
+++ b/karavan-app/src/main/java/org/apache/camel/karavan/service/GitService.java
@@ -29,23 +29,31 @@ 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.diff.DiffEntry;
+import org.eclipse.jgit.diff.DiffFormatter;
import org.eclipse.jgit.lib.*;
import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevTree;
+import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.transport.*;
import org.eclipse.jgit.transport.ssh.jsch.JschConfigSessionFactory;
+import org.eclipse.jgit.treewalk.AbstractTreeIterator;
+import org.eclipse.jgit.treewalk.CanonicalTreeParser;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.treewalk.filter.TreeFilter;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.jboss.logging.Logger;
+import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
+import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.regex.Pattern;
+import java.util.stream.StreamSupport;
@ApplicationScoped
public class GitService {
@@ -179,7 +187,7 @@ public class GitService {
LOGGER.info("Temp folder created " + folder);
Git git = null;
if (ephemeral) {
- LOGGER.error("New ephemeral repository");
+ LOGGER.warn("New ephemeral repository");
git = init(folder, gitConfig.getUri(), gitConfig.getBranch());
} else {
try {
@@ -462,4 +470,82 @@ public class GitService {
}
return sshSessionFactory;
}
+
+ public List<ProjectCommit> getProjectCommits(String projectId) {
+ List<ProjectCommit> result = new ArrayList<>();
+ try {
+ Git pollGit = getGit(true, vertx.fileSystem().createTempDirectoryBlocking("commits"));
+ if (pollGit != null) {
+ StreamSupport.stream(pollGit.log().all().addPath(projectId).call().spliterator(), false)
+ .sorted(Comparator.comparingInt(RevCommit::getCommitTime))
+ .forEach(commit -> {
+ var diffs = getProjectFileCommitDiffs(pollGit, commit);
+ var projectCommit = new ProjectCommit(commit.getId().getName(), projectId,
+ commit.getAuthorIdent().getName(), commit.getAuthorIdent().getEmailAddress(),
+ commit.getShortMessage(), diffs);
+ result.add(projectCommit);
+ });
+ }
+ } catch (Exception e) {
+ LOGGER.error("Error", e);
+ }
+ return result;
+ }
+
+ private List<ProjectFileCommitDiff> getProjectFileCommitDiffs(Git git, RevCommit commit) {
+ List<ProjectFileCommitDiff> result = new ArrayList<>();
+ var repository = git.getRepository();
+ try {
+ try (RevWalk revWalk = new RevWalk(repository)) {
+ if (commit.getParentCount() > 0) {
+ RevCommit parentCommit = commit.getParent(0);
+ revWalk.parseCommit(parentCommit);
+
+ AbstractTreeIterator oldTreeIter = prepareTreeParser(repository, parentCommit);
+ AbstractTreeIterator newTreeIter = prepareTreeParser(repository, commit);
+
+ try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ DiffFormatter diffFormatter = new DiffFormatter(baos)) {
+ diffFormatter.setRepository(repository);
+ List<DiffEntry> diffs = diffFormatter.scan(oldTreeIter, newTreeIter);
+
+ for (DiffEntry diff : diffs) {
+ diffFormatter.format(diff);
+ var fileDiff = new ProjectFileCommitDiff(diff.getChangeType().name(), diff.getNewPath(), diff.getOldPath(), baos.toString(StandardCharsets.UTF_8));
+ result.add(fileDiff);
+ baos.reset(); // Clear the output stream for the next diff
+ }
+ }
+ } else {
+ try (TreeWalk treeWalk = new TreeWalk(repository)) {
+ treeWalk.addTree(commit.getTree());
+ treeWalk.setRecursive(true);
+ while (treeWalk.next()) {
+ // Get the object ID for the file (blob)
+ ObjectId objectId = treeWalk.getObjectId(0);
+ // Load the file content
+ ObjectLoader loader = repository.open(objectId);
+ byte[] content = loader.getBytes();
+ var fileDiff = new ProjectFileCommitDiff(DiffEntry.ChangeType.ADD.name(), treeWalk.getPathString(), DiffEntry.DEV_NULL, new String(content, StandardCharsets.UTF_8));
+ result.add(fileDiff);
+ }
+ }
+ }
+ }
+ } catch (IOException e) {
+ LOGGER.error("Error", e);
+ }
+ return result;
+ }
+
+ private static AbstractTreeIterator prepareTreeParser(Repository repository, RevCommit commit) throws IOException {
+ try (RevWalk walk = new RevWalk(repository)) {
+ RevTree tree = walk.parseTree(commit.getTree().getId());
+ CanonicalTreeParser treeParser = new CanonicalTreeParser();
+ try (ObjectReader reader = repository.newObjectReader()) {
+ treeParser.reset(reader, tree.getId());
+ }
+ return treeParser;
+ }
+ }
}