diff --git a/src/main/java/ru/ulstu/extractor/Changes.java b/src/main/java/ru/ulstu/extractor/Changes.java new file mode 100644 index 0000000..2e32603 --- /dev/null +++ b/src/main/java/ru/ulstu/extractor/Changes.java @@ -0,0 +1,19 @@ +package ru.ulstu.extractor; + +import java.util.ArrayList; +import java.util.List; + +public class Changes { + private List fileChanges = new ArrayList<>(); + + public Changes() { + } + + public Changes(List fileChanges) { + this.fileChanges = fileChanges; + } + + public List getFileChanges() { + return fileChanges; + } +} diff --git a/src/main/java/ru/ulstu/extractor/Commit.java b/src/main/java/ru/ulstu/extractor/Commit.java index 463525a..44f1357 100644 --- a/src/main/java/ru/ulstu/extractor/Commit.java +++ b/src/main/java/ru/ulstu/extractor/Commit.java @@ -6,6 +6,7 @@ public class Commit { private String message; private Date date; private String author; + private Changes changes; public Commit(String message, String author, Date date) { this.message = message; @@ -25,4 +26,12 @@ public class Commit { public String getAuthor() { return author; } + + public Changes getChanges() { + return changes; + } + + public void setChanges(Changes changes) { + this.changes = changes; + } } diff --git a/src/main/java/ru/ulstu/extractor/FileChange.java b/src/main/java/ru/ulstu/extractor/FileChange.java new file mode 100644 index 0000000..beb2384 --- /dev/null +++ b/src/main/java/ru/ulstu/extractor/FileChange.java @@ -0,0 +1,50 @@ +package ru.ulstu.extractor; + +import java.util.ArrayList; +import java.util.List; + +public class FileChange { + private String file; + private boolean removed; + private boolean added; + private List lineChanges = new ArrayList<>(); + + public FileChange() { + } + + public FileChange(String file) { + this.file = file; + } + + public String getFile() { + return file; + } + + public boolean getRemoved() { + return removed; + } + + public boolean getAdded() { + return added; + } + + public List getLineChanges() { + return lineChanges; + } + + public void setFile(String file) { + this.file = file; + } + + public void setRemoved(boolean removed) { + this.removed = removed; + } + + public void setAdded(boolean added) { + this.added = added; + } + + public void setLineChanges(List lineChanges) { + this.lineChanges = lineChanges; + } +} diff --git a/src/main/java/ru/ulstu/extractor/GitRepositoryService.java b/src/main/java/ru/ulstu/extractor/GitRepositoryService.java index b53e8ec..d8ec67f 100644 --- a/src/main/java/ru/ulstu/extractor/GitRepositoryService.java +++ b/src/main/java/ru/ulstu/extractor/GitRepositoryService.java @@ -2,12 +2,14 @@ package ru.ulstu.extractor; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.diff.DiffFormatter; import org.eclipse.jgit.internal.storage.file.FileRepository; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevCommit; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.nio.file.Path; @@ -15,6 +17,7 @@ import java.time.Instant; import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.Optional; import static org.apache.logging.log4j.util.Strings.isBlank; @@ -23,7 +26,6 @@ public class GitRepositoryService { @Value("${extractor.custom-projects-dir}") private String customProjectsDir; - public void cloneOrUpdateRepo(String url) throws GitAPIException, IOException { Git git; if (projectDirExists(getProjectDirectoryFile(url))) { @@ -37,7 +39,7 @@ public class GitRepositoryService { .call(); } Iterable commits = git.log().call(); - commits.forEach(c -> System.out.println(c.getFullMessage())); + //commits.forEach(c -> System.out.println(c.getFullMessage())); } private String getProjectDirectory(String url) { @@ -69,14 +71,58 @@ public class GitRepositoryService { git.log().call().forEach(commits::add); List list = new ArrayList<>(); - for (RevCommit commit : commits) { - Commit fullMessage = new Commit( - commit.getFullMessage(), - commit.getAuthorIdent().getName(), - Date.from(Instant.ofEpochSecond(commit.getCommitTime()))); - list.add(fullMessage); + RevCommit prevCommit = null; + for (RevCommit revCommit : commits) { + Commit commit = new Commit( + revCommit.getFullMessage(), + revCommit.getAuthorIdent().getName(), + Date.from(Instant.ofEpochSecond(revCommit.getCommitTime()))); + if (prevCommit != null) { + commit.setChanges(findDiffBetweenTwoRevisions(revCommit, prevCommit, localRepo)); + } + list.add(commit); + prevCommit = revCommit; } - return list; } + + public Changes findDiffBetweenTwoRevisions(RevCommit laterCommit, RevCommit earlierCommit, Repository localRepo) { + if (laterCommit == null || earlierCommit == null) { + return null; + } + String output = null; + try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { + DiffFormatter diffFormatter = new DiffFormatter(out); + diffFormatter.setRepository(localRepo); + diffFormatter.format(earlierCommit.getId(), laterCommit.getId()); + output = out.toString(); + } catch (IOException e) { + throw new RuntimeException("Error occurred during diff computation. Message: " + e.getMessage()); + } + return parseOutputDiff(output); + } + + private Changes parseOutputDiff(String output) { + Changes changes = new Changes(); + String[] strings = output.split("\n"); + for (String string : strings) { + Optional maybeFileName = getFileName(string); + if (maybeFileName.isPresent()) { + FileChange fileChange = new FileChange(); + fileChange.setFile(maybeFileName.get()); + /// вытащить другие изменения из коммита + changes.getFileChanges().add(fileChange); + } + } + return changes; + } + + private Optional getFileName(String commitString) { + String startString = "diff --git a/"; + if (commitString.startsWith(startString)) { + String name = commitString.substring(commitString.indexOf(startString) + startString.length(), commitString.indexOf("b/")); + return Optional.of(name); + } + return Optional.empty(); + } } diff --git a/src/main/java/ru/ulstu/extractor/LineChange.java b/src/main/java/ru/ulstu/extractor/LineChange.java new file mode 100644 index 0000000..4adc8ca --- /dev/null +++ b/src/main/java/ru/ulstu/extractor/LineChange.java @@ -0,0 +1,32 @@ +package ru.ulstu.extractor; + +public class LineChange { + private boolean added; + private boolean removed; + private int lineFrom; + private int lineTo; + + public LineChange(boolean added, boolean removed, int lineFrom, int lineTo) { + this.added = added; + this.removed = removed; + this.lineFrom = lineFrom; + this.lineTo = lineTo; + } + + public boolean getAdd() { + return added; + } + + public boolean getRemoved() { + return removed; + } + + public int getLineFrom() { + return lineFrom; + } + + public int getLineTo() { + return lineTo; + } + +} diff --git a/src/main/java/ru/ulstu/extractor/NewClass.java b/src/main/java/ru/ulstu/extractor/NewClass.java new file mode 100644 index 0000000..d777668 --- /dev/null +++ b/src/main/java/ru/ulstu/extractor/NewClass.java @@ -0,0 +1,47 @@ +package ru.ulstu.extractor; + +import org.eclipse.jgit.diff.DiffEntry; +import org.eclipse.jgit.diff.DiffFormatter; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.revwalk.RevWalk; + +import java.io.IOException; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class NewClass { + + private final RevWalk revWalk; + private final DiffFormatter diffFormatter; + + private NewClass(RevWalk revWalk, DiffFormatter diffFormatter) { + this.revWalk = revWalk; + this.diffFormatter = diffFormatter; + } + + public Set getModified(final RevCommit commit) throws IOException { + final RevCommit[] parents = commit.getParents(); + final Set result = new HashSet<>(); + if (parents.length == 1) { // merge commit if length > 1 + final RevCommit parent = revWalk.parseCommit(parents[0].getId()); + // get diff of this commit to its parent, as list of paths + final List diffs = getDiffEntries(commit, parent); + for (final DiffEntry diff : diffs) { + final String changePath = diff.getChangeType().equals(DiffEntry.ChangeType.DELETE) ? diff.getOldPath() : diff.getNewPath(); + result.add(changePath); + } + } + return result; + } + + private List getDiffEntries(final RevCommit commit, final RevCommit parent) { + try { + return diffFormatter.scan(parent.getTree(), commit.getTree()); + } catch (Exception e) { + e.printStackTrace(); + } + return Collections.emptyList(); + } +}