From 47fe0b5321f16c2999f9ff3fc87ea2f9d1221ad0 Mon Sep 17 00:00:00 2001 From: Dmitry Mamchur Date: Wed, 26 Feb 2020 18:41:53 +0000 Subject: [PATCH 01/20] first steps --- .../gitchangelog/api/GitChangelogApi.java | 65 +++++++++++++++---- .../gitchangelog/internal/git/GitRepo.java | 48 +++++++++++--- 2 files changed, 94 insertions(+), 19 deletions(-) diff --git a/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java b/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java index 36c2df5d..a8441222 100644 --- a/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java +++ b/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java @@ -27,10 +27,13 @@ import java.io.Writer; import java.net.URL; import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; import org.eclipse.jgit.lib.ObjectId; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import se.bjurr.gitchangelog.api.exceptions.GitChangelogIntegrationException; import se.bjurr.gitchangelog.api.exceptions.GitChangelogRepositoryException; import se.bjurr.gitchangelog.api.model.Changelog; @@ -48,6 +51,8 @@ public class GitChangelogApi { + private static final Logger LOG = LoggerFactory.getLogger(GitChangelogApi.class); + public static GitChangelogApi gitChangelogApiBuilder() { return new GitChangelogApi(); } @@ -431,17 +436,10 @@ public GitChangelogApi withUntaggedName(final String untaggedName) { private Changelog getChangelog(final GitRepo gitRepo, final boolean useIntegrationIfConfigured) throws GitChangelogRepositoryException { - final ObjectId fromId = - getId(gitRepo, this.settings.getFromRef(), this.settings.getFromCommit()) // - .or(gitRepo.getCommit(ZERO_COMMIT)); - final Optional toIdOpt = - getId(gitRepo, this.settings.getToRef(), this.settings.getToCommit()); - ObjectId toId; - if (toIdOpt.isPresent()) { - toId = toIdOpt.get(); - } else { - toId = gitRepo.getRef(REF_MASTER); - } + final ObjectId[] fromToParent = getFromTo(gitRepo); + final ObjectId fromId = fromToParent[0]; + final ObjectId toId = fromToParent[1]; + GitRepoData gitRepoData = gitRepo.getGitRepoData( fromId, @@ -465,6 +463,36 @@ private Changelog getChangelog(final GitRepo gitRepo, final boolean useIntegrati diff = gitRepoData.getGitCommits(); } final List tags = gitRepoData.getGitTags(); + + if (gitRepo.hasSubmodules()) { + final List submoduleGitRepoData = new ArrayList<>(); + + for (GitRepo submodule : gitRepo.submodules) { + final ObjectId[] fromToSubmodule = getFromTo(submodule); + final ObjectId fromIdSubmodule = fromToSubmodule[0]; + final ObjectId toIdSubmodule = fromToSubmodule[1]; + submoduleGitRepoData.add( + gitRepo.getGitRepoDataSubmodule( + submodule, + fromIdSubmodule, + toIdSubmodule, + this.settings.getUntaggedName(), + this.settings.getIgnoreTagsIfNameMatches())); + } + + for (GitTag tag : tags) { + for (GitRepoData sGitRepoData : submoduleGitRepoData) { + final List stags = sGitRepoData.getGitTags(); + for (GitTag stag : stags) { + LOG.info("Submodule tag " + stag.getName()); + if (stag.getName().equals(tag.getName())) { + LOG.info("Found tag in submodules: " + stag.getName()); + } + } + } + } + } + final Transformer transformer = new Transformer(this.settings); return new Changelog( // transformer.toCommits(diff), // @@ -476,6 +504,21 @@ private Changelog getChangelog(final GitRepo gitRepo, final boolean useIntegrati gitRepoData.findRepoName().orNull()); } + private ObjectId[] getFromTo(final GitRepo gitRepo) throws GitChangelogRepositoryException { + final ObjectId fromId = + getId(gitRepo, this.settings.getFromRef(), this.settings.getFromCommit()) // + .or(gitRepo.getCommit(ZERO_COMMIT)); + final Optional toIdOpt = + getId(gitRepo, this.settings.getToRef(), this.settings.getToCommit()); + ObjectId toId; + if (toIdOpt.isPresent()) { + toId = toIdOpt.get(); + } else { + toId = gitRepo.getRef(REF_MASTER); + } + return new ObjectId[] {fromId, toId}; + } + private Optional getId( final GitRepo gitRepo, final Optional ref, final Optional commit) throws GitChangelogRepositoryException { diff --git a/src/main/java/se/bjurr/gitchangelog/internal/git/GitRepo.java b/src/main/java/se/bjurr/gitchangelog/internal/git/GitRepo.java index 5f528d2f..3bd32129 100644 --- a/src/main/java/se/bjurr/gitchangelog/internal/git/GitRepo.java +++ b/src/main/java/se/bjurr/gitchangelog/internal/git/GitRepo.java @@ -17,14 +17,7 @@ import java.io.Closeable; import java.io.File; import java.io.IOException; -import java.util.Collection; -import java.util.Comparator; -import java.util.Date; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; +import java.util.*; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.ObjectId; @@ -34,6 +27,7 @@ import org.eclipse.jgit.revwalk.RevTag; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.storage.file.FileRepositoryBuilder; +import org.eclipse.jgit.submodule.SubmoduleWalk; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import se.bjurr.gitchangelog.api.GitChangelogApiConstants; @@ -47,10 +41,12 @@ public class GitRepo implements Closeable { private Git git; private final Repository repository; private final RevWalk revWalk; + public final List submodules; public GitRepo() { this.repository = null; this.revWalk = null; + this.submodules = null; } public GitRepo(final File repo) throws GitChangelogRepositoryException { @@ -71,6 +67,19 @@ public GitRepo(final File repo) throws GitChangelogRepositoryException { this.repository = builder.build(); this.revWalk = new RevWalk(this.repository); this.git = new Git(this.repository); + + if (SubmoduleWalk.containsGitModulesFile(repository)) { + this.submodules = new ArrayList<>(); + final SubmoduleWalk submoduleWalk = SubmoduleWalk.forIndex(repository); + while (submoduleWalk.next()) { + final Repository submoduleRepository = submoduleWalk.getRepository(); + this.submodules.add(new GitRepo(submoduleRepository.getDirectory())); + submoduleRepository.close(); + } + } else { + this.submodules = null; + } + } catch (final IOException e) { throw new GitChangelogRepositoryException( "Could not use GIT repo in " + repo.getAbsolutePath(), e); @@ -89,6 +98,11 @@ public void close() throws IOException { LOG.error(e.getMessage(), e); } } + if (submodules != null) { + for (GitRepo submodule : submodules) { + submodule.close(); + } + } } public ObjectId getCommit(final String fromCommit) throws GitChangelogRepositoryException { @@ -123,6 +137,20 @@ public GitRepoData getGitRepoData( } } + public GitRepoData getGitRepoDataSubmodule( + final GitRepo submodule, + final ObjectId from, + final ObjectId to, + final String untaggedName, + final Optional ignoreTagsIfNameMatches) + throws GitChangelogRepositoryException { + try { + return submodule.getGitRepoData(from, to, untaggedName, ignoreTagsIfNameMatches); + } catch (final Exception e) { + throw new GitChangelogRepositoryException(toString(), e); + } + } + public ObjectId getRef(final String fromRef) throws GitChangelogRepositoryException { try { for (final Ref foundRef : getAllRefs().values()) { @@ -142,6 +170,10 @@ public ObjectId getRef(final String fromRef) throws GitChangelogRepositoryExcept throw new GitChangelogRepositoryException(fromRef + " not found in:\n" + toString()); } + public boolean hasSubmodules() { + return submodules != null; + } + @Override public String toString() { final StringBuilder sb = new StringBuilder(); From 085fecc29b0f26157e29d26c9be3482755f5ddd7 Mon Sep 17 00:00:00 2001 From: Dmitry Mamchur Date: Thu, 27 Feb 2020 18:04:19 +0000 Subject: [PATCH 02/20] wip --- .../gitchangelog/api/GitChangelogApi.java | 39 ++++++-------- .../api/model/SubmoduleSection.java | 47 +++++++++++++++++ .../se/bjurr/gitchangelog/api/model/Tag.java | 11 +++- .../internal/model/Transformer.java | 52 ++++++++++++++----- 4 files changed, 111 insertions(+), 38 deletions(-) create mode 100644 src/main/java/se/bjurr/gitchangelog/api/model/SubmoduleSection.java diff --git a/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java b/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java index a8441222..c079c59d 100644 --- a/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java +++ b/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java @@ -38,6 +38,8 @@ import se.bjurr.gitchangelog.api.exceptions.GitChangelogRepositoryException; import se.bjurr.gitchangelog.api.model.Changelog; import se.bjurr.gitchangelog.api.model.Issue; +import se.bjurr.gitchangelog.api.model.SubmoduleSection; +import se.bjurr.gitchangelog.api.model.Tag; import se.bjurr.gitchangelog.internal.git.GitRepo; import se.bjurr.gitchangelog.internal.git.GitRepoData; import se.bjurr.gitchangelog.internal.git.model.GitCommit; @@ -464,39 +466,30 @@ private Changelog getChangelog(final GitRepo gitRepo, final boolean useIntegrati } final List tags = gitRepoData.getGitTags(); + List> allSubmoduleSections = null; if (gitRepo.hasSubmodules()) { - final List submoduleGitRepoData = new ArrayList<>(); + allSubmoduleSections = new ArrayList<>(); for (GitRepo submodule : gitRepo.submodules) { - final ObjectId[] fromToSubmodule = getFromTo(submodule); - final ObjectId fromIdSubmodule = fromToSubmodule[0]; - final ObjectId toIdSubmodule = fromToSubmodule[1]; - submoduleGitRepoData.add( - gitRepo.getGitRepoDataSubmodule( - submodule, - fromIdSubmodule, - toIdSubmodule, - this.settings.getUntaggedName(), - this.settings.getIgnoreTagsIfNameMatches())); - } - - for (GitTag tag : tags) { - for (GitRepoData sGitRepoData : submoduleGitRepoData) { - final List stags = sGitRepoData.getGitTags(); - for (GitTag stag : stags) { - LOG.info("Submodule tag " + stag.getName()); - if (stag.getName().equals(tag.getName())) { - LOG.info("Found tag in submodules: " + stag.getName()); - } - } + final Changelog submoduleChangelog = getChangelog(submodule, useIntegrationIfConfigured); + + List submoduleSections = new ArrayList<>(); + for (Tag tag : submoduleChangelog.getTags()) { + submoduleSections.add( + new SubmoduleSection( + submoduleChangelog.getOwnerName(), + submoduleChangelog.getRepoName(), + tag.getName(), + tag.getIssues())); } + allSubmoduleSections.add(submoduleSections); } } final Transformer transformer = new Transformer(this.settings); return new Changelog( // transformer.toCommits(diff), // - transformer.toTags(tags, issues), // + transformer.toTags(tags, issues, allSubmoduleSections), // transformer.toAuthors(diff), // transformer.toIssues(issues), // transformer.toIssueTypes(issues), // diff --git a/src/main/java/se/bjurr/gitchangelog/api/model/SubmoduleSection.java b/src/main/java/se/bjurr/gitchangelog/api/model/SubmoduleSection.java new file mode 100644 index 00000000..7a174010 --- /dev/null +++ b/src/main/java/se/bjurr/gitchangelog/api/model/SubmoduleSection.java @@ -0,0 +1,47 @@ +package se.bjurr.gitchangelog.api.model; + +import java.io.Serializable; +import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import se.bjurr.gitchangelog.api.model.interfaces.IIssues; + +public class SubmoduleSection implements Serializable, IIssues { + private static final Logger LOG = LoggerFactory.getLogger(SubmoduleSection.class); + private static final long serialVersionUID = 2140208294219785889L; + + private final String ownerName; + private final String repoName; + private final String tagName; + private final List issues; + + public SubmoduleSection(String ownerName, String repoName, String tagName, List issues) { + this.ownerName = ownerName; + this.repoName = repoName; + this.tagName = tagName; + this.issues = issues; + LOG.info("new SubmoduleSection " + ownerName + " " + repoName + " " + tagName); + } + + public String getTagName() { + return this.tagName; + } + + @Override + public List getIssues() { + return this.issues; + } + + @Override + public String toString() { + return "name: " + this.repoName; + } + + public String getOwnerName() { + return ownerName; + } + + public String getRepoName() { + return repoName; + } +} diff --git a/src/main/java/se/bjurr/gitchangelog/api/model/Tag.java b/src/main/java/se/bjurr/gitchangelog/api/model/Tag.java index dbdd9739..7a604914 100644 --- a/src/main/java/se/bjurr/gitchangelog/api/model/Tag.java +++ b/src/main/java/se/bjurr/gitchangelog/api/model/Tag.java @@ -9,11 +9,12 @@ import se.bjurr.gitchangelog.api.model.interfaces.IIssues; public class Tag implements ICommits, IAuthors, IIssues, Serializable { - private static final long serialVersionUID = 2140208294219785889L; + private static final long serialVersionUID = 2140208294219785899L; private final String annotation; private final List authors; private final List commits; private final List issues; + private final List submoduleSections; private final List issueTypes; private final String name; private final String tagTime; @@ -28,7 +29,8 @@ public Tag( List issues, List issueTypes, String tagTime, - Long tagTimeLong) { + Long tagTimeLong, + List submoduleSections) { this.commits = commits; this.authors = authors; this.issues = issues; @@ -38,6 +40,7 @@ public Tag( this.tagTime = tagTime; this.tagTimeLong = tagTimeLong; this.hasTagTime = !isNullOrEmpty(tagTime); + this.submoduleSections = submoduleSections; } public String getAnnotation() { @@ -63,6 +66,10 @@ public List getIssues() { return this.issues; } + public List getSubmoduleSections() { + return this.submoduleSections; + } + public List getIssueTypes() { return this.issueTypes; } diff --git a/src/main/java/se/bjurr/gitchangelog/internal/model/Transformer.java b/src/main/java/se/bjurr/gitchangelog/internal/model/Transformer.java index 8600cb5c..9ddd003b 100644 --- a/src/main/java/se/bjurr/gitchangelog/internal/model/Transformer.java +++ b/src/main/java/se/bjurr/gitchangelog/internal/model/Transformer.java @@ -16,17 +16,11 @@ import com.google.common.base.Predicate; import com.google.common.collect.Multimap; import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.regex.Matcher; -import se.bjurr.gitchangelog.api.model.Author; -import se.bjurr.gitchangelog.api.model.Commit; -import se.bjurr.gitchangelog.api.model.Issue; -import se.bjurr.gitchangelog.api.model.IssueType; -import se.bjurr.gitchangelog.api.model.Tag; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import se.bjurr.gitchangelog.api.model.*; import se.bjurr.gitchangelog.internal.git.model.GitCommit; import se.bjurr.gitchangelog.internal.git.model.GitTag; import se.bjurr.gitchangelog.internal.settings.IssuesUtil; @@ -34,6 +28,7 @@ import se.bjurr.gitchangelog.internal.settings.SettingsIssue; public class Transformer { + private static final Logger LOG = LoggerFactory.getLogger(Transformer.class); private final Settings settings; @@ -117,7 +112,10 @@ public List toIssueTypes(List issues) { return issueTypes; } - public List toTags(List gitTags, final List allParsedIssues) { + public List toTags( + List gitTags, + final List allParsedIssues, + final List> allSubmoduleSections) { Iterable tags = transform( @@ -126,21 +124,25 @@ public List toTags(List gitTags, final List allParsedI @Override public Tag apply(GitTag input) { List gitCommits = input.getGitCommits(); + final String readableName = toReadableTagName(input.getName()); List parsedIssues = reduceParsedIssuesToOnlyGitCommits(allParsedIssues, gitCommits); + List submoduleSections = + reduceSubmoduleSectionsToOnlyGitTag(allSubmoduleSections, readableName); List commits = toCommits(gitCommits); List authors = toAuthors(gitCommits); List issues = toIssues(parsedIssues); List issueTypes = toIssueTypes(parsedIssues); return new Tag( - toReadableTagName(input.getName()), + readableName, input.findAnnotation().orNull(), commits, authors, issues, issueTypes, input.getTagTime() != null ? format(input.getTagTime()) : "", - input.getTagTime() != null ? input.getTagTime().getTime() : -1); + input.getTagTime() != null ? input.getTagTime().getTime() : -1, + submoduleSections); } private List reduceParsedIssuesToOnlyGitCommits( @@ -167,6 +169,30 @@ private List reduceParsedIssuesToOnlyGitCommits( } return parsedIssues; } + + private List reduceSubmoduleSectionsToOnlyGitTag( + List> allSubmoduleSections, String tagName) { + List result = newArrayList(); + if (allSubmoduleSections == null) { + return null; + } + for (List submoduleSections : allSubmoduleSections) { + for (SubmoduleSection submoduleSection : submoduleSections) { + LOG.info( + "Compare section " + + submoduleSection.getRepoName() + + " " + + submoduleSection.getTagName() + + " and " + + tagName); + if (submoduleSection.getTagName().equals(tagName)) { + LOG.info("Add section"); + result.add(submoduleSection); + } + } + } + return result; + } }); tags = From 97985563549af4afcef2f1a841d067ca8992b528 Mon Sep 17 00:00:00 2001 From: Dmitry Mamchur Date: Mon, 2 Mar 2020 10:21:14 +0000 Subject: [PATCH 03/20] remove debug logs --- .../gitchangelog/api/GitChangelogApi.java | 29 +++++++------------ .../api/model/SubmoduleSection.java | 4 --- 2 files changed, 11 insertions(+), 22 deletions(-) diff --git a/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java b/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java index c079c59d..24704c6e 100644 --- a/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java +++ b/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java @@ -438,9 +438,17 @@ public GitChangelogApi withUntaggedName(final String untaggedName) { private Changelog getChangelog(final GitRepo gitRepo, final boolean useIntegrationIfConfigured) throws GitChangelogRepositoryException { - final ObjectId[] fromToParent = getFromTo(gitRepo); - final ObjectId fromId = fromToParent[0]; - final ObjectId toId = fromToParent[1]; + final ObjectId fromId = + getId(gitRepo, this.settings.getFromRef(), this.settings.getFromCommit()) // + .or(gitRepo.getCommit(ZERO_COMMIT)); + final Optional toIdOpt = + getId(gitRepo, this.settings.getToRef(), this.settings.getToCommit()); + ObjectId toId; + if (toIdOpt.isPresent()) { + toId = toIdOpt.get(); + } else { + toId = gitRepo.getRef(REF_MASTER); + } GitRepoData gitRepoData = gitRepo.getGitRepoData( @@ -497,21 +505,6 @@ private Changelog getChangelog(final GitRepo gitRepo, final boolean useIntegrati gitRepoData.findRepoName().orNull()); } - private ObjectId[] getFromTo(final GitRepo gitRepo) throws GitChangelogRepositoryException { - final ObjectId fromId = - getId(gitRepo, this.settings.getFromRef(), this.settings.getFromCommit()) // - .or(gitRepo.getCommit(ZERO_COMMIT)); - final Optional toIdOpt = - getId(gitRepo, this.settings.getToRef(), this.settings.getToCommit()); - ObjectId toId; - if (toIdOpt.isPresent()) { - toId = toIdOpt.get(); - } else { - toId = gitRepo.getRef(REF_MASTER); - } - return new ObjectId[] {fromId, toId}; - } - private Optional getId( final GitRepo gitRepo, final Optional ref, final Optional commit) throws GitChangelogRepositoryException { diff --git a/src/main/java/se/bjurr/gitchangelog/api/model/SubmoduleSection.java b/src/main/java/se/bjurr/gitchangelog/api/model/SubmoduleSection.java index 7a174010..9c1cc886 100644 --- a/src/main/java/se/bjurr/gitchangelog/api/model/SubmoduleSection.java +++ b/src/main/java/se/bjurr/gitchangelog/api/model/SubmoduleSection.java @@ -2,12 +2,9 @@ import java.io.Serializable; import java.util.List; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import se.bjurr.gitchangelog.api.model.interfaces.IIssues; public class SubmoduleSection implements Serializable, IIssues { - private static final Logger LOG = LoggerFactory.getLogger(SubmoduleSection.class); private static final long serialVersionUID = 2140208294219785889L; private final String ownerName; @@ -20,7 +17,6 @@ public SubmoduleSection(String ownerName, String repoName, String tagName, List< this.repoName = repoName; this.tagName = tagName; this.issues = issues; - LOG.info("new SubmoduleSection " + ownerName + " " + repoName + " " + tagName); } public String getTagName() { From 8521cb72a911c9e05833e2fcd02cc56994ae1379 Mon Sep 17 00:00:00 2001 From: Dmitry Mamchur Date: Tue, 3 Mar 2020 15:09:51 +0000 Subject: [PATCH 04/20] styling --- .../java/se/bjurr/gitchangelog/api/GitChangelogApi.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java b/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java index 24704c6e..9efb42dd 100644 --- a/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java +++ b/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java @@ -439,10 +439,10 @@ public GitChangelogApi withUntaggedName(final String untaggedName) { private Changelog getChangelog(final GitRepo gitRepo, final boolean useIntegrationIfConfigured) throws GitChangelogRepositoryException { final ObjectId fromId = - getId(gitRepo, this.settings.getFromRef(), this.settings.getFromCommit()) // - .or(gitRepo.getCommit(ZERO_COMMIT)); + getId(gitRepo, this.settings.getFromRef(), this.settings.getFromCommit()) // + .or(gitRepo.getCommit(ZERO_COMMIT)); final Optional toIdOpt = - getId(gitRepo, this.settings.getToRef(), this.settings.getToCommit()); + getId(gitRepo, this.settings.getToRef(), this.settings.getToCommit()); ObjectId toId; if (toIdOpt.isPresent()) { toId = toIdOpt.get(); From 8751a3aa351a0020cd9bf47a339dfc7db85c5156 Mon Sep 17 00:00:00 2001 From: Dmitry Mamchur Date: Tue, 3 Mar 2020 15:10:18 +0000 Subject: [PATCH 05/20] return empty changelist when from and to point to the same commit --- src/main/java/se/bjurr/gitchangelog/internal/git/GitRepo.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/se/bjurr/gitchangelog/internal/git/GitRepo.java b/src/main/java/se/bjurr/gitchangelog/internal/git/GitRepo.java index 3bd32129..45143dc3 100644 --- a/src/main/java/se/bjurr/gitchangelog/internal/git/GitRepo.java +++ b/src/main/java/se/bjurr/gitchangelog/internal/git/GitRepo.java @@ -323,6 +323,10 @@ private List gitTags( final RevCommit from = this.revWalk.lookupCommit(fromObjectId); final RevCommit to = this.revWalk.lookupCommit(toObjectId); + if (from == to) { + return newArrayList(); + } + this.commitsToInclude = getDiffingCommits(from, to); final List tagList = tagsBetweenFromAndTo(from, to); From 7a95ab5f1f0ed4a30fe0c866074a25854949e8a3 Mon Sep 17 00:00:00 2001 From: Dmitry Mamchur Date: Tue, 3 Mar 2020 15:14:33 +0000 Subject: [PATCH 06/20] remove logging, reverse import changes --- .../internal/model/Transformer.java | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/main/java/se/bjurr/gitchangelog/internal/model/Transformer.java b/src/main/java/se/bjurr/gitchangelog/internal/model/Transformer.java index 9ddd003b..7074edba 100644 --- a/src/main/java/se/bjurr/gitchangelog/internal/model/Transformer.java +++ b/src/main/java/se/bjurr/gitchangelog/internal/model/Transformer.java @@ -16,11 +16,18 @@ import com.google.common.base.Predicate; import com.google.common.collect.Multimap; import java.text.SimpleDateFormat; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Map; import java.util.regex.Matcher; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import se.bjurr.gitchangelog.api.model.*; +import se.bjurr.gitchangelog.api.model.Author; +import se.bjurr.gitchangelog.api.model.Commit; +import se.bjurr.gitchangelog.api.model.Issue; +import se.bjurr.gitchangelog.api.model.IssueType; +import se.bjurr.gitchangelog.api.model.SubmoduleSection; +import se.bjurr.gitchangelog.api.model.Tag; import se.bjurr.gitchangelog.internal.git.model.GitCommit; import se.bjurr.gitchangelog.internal.git.model.GitTag; import se.bjurr.gitchangelog.internal.settings.IssuesUtil; @@ -28,7 +35,6 @@ import se.bjurr.gitchangelog.internal.settings.SettingsIssue; public class Transformer { - private static final Logger LOG = LoggerFactory.getLogger(Transformer.class); private final Settings settings; @@ -178,15 +184,7 @@ private List reduceSubmoduleSectionsToOnlyGitTag( } for (List submoduleSections : allSubmoduleSections) { for (SubmoduleSection submoduleSection : submoduleSections) { - LOG.info( - "Compare section " - + submoduleSection.getRepoName() - + " " - + submoduleSection.getTagName() - + " and " - + tagName); if (submoduleSection.getTagName().equals(tagName)) { - LOG.info("Add section"); result.add(submoduleSection); } } From 2a5d0c50343947ca75d56e45402404b517290d2a Mon Sep 17 00:00:00 2001 From: Dmitry Mamchur Date: Tue, 3 Mar 2020 15:21:55 +0000 Subject: [PATCH 07/20] remove logs, revert import changes --- .../gitchangelog/api/GitChangelogApi.java | 6 +--- .../gitchangelog/internal/git/GitRepo.java | 32 +++++++++---------- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java b/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java index 9efb42dd..7dadeeff 100644 --- a/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java +++ b/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java @@ -32,8 +32,6 @@ import java.util.List; import java.util.Map; import org.eclipse.jgit.lib.ObjectId; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import se.bjurr.gitchangelog.api.exceptions.GitChangelogIntegrationException; import se.bjurr.gitchangelog.api.exceptions.GitChangelogRepositoryException; import se.bjurr.gitchangelog.api.model.Changelog; @@ -53,8 +51,6 @@ public class GitChangelogApi { - private static final Logger LOG = LoggerFactory.getLogger(GitChangelogApi.class); - public static GitChangelogApi gitChangelogApiBuilder() { return new GitChangelogApi(); } @@ -478,7 +474,7 @@ private Changelog getChangelog(final GitRepo gitRepo, final boolean useIntegrati if (gitRepo.hasSubmodules()) { allSubmoduleSections = new ArrayList<>(); - for (GitRepo submodule : gitRepo.submodules) { + for (GitRepo submodule : gitRepo.getSubmodules()) { final Changelog submoduleChangelog = getChangelog(submodule, useIntegrationIfConfigured); List submoduleSections = new ArrayList<>(); diff --git a/src/main/java/se/bjurr/gitchangelog/internal/git/GitRepo.java b/src/main/java/se/bjurr/gitchangelog/internal/git/GitRepo.java index 45143dc3..9b96edc8 100644 --- a/src/main/java/se/bjurr/gitchangelog/internal/git/GitRepo.java +++ b/src/main/java/se/bjurr/gitchangelog/internal/git/GitRepo.java @@ -17,7 +17,15 @@ import java.io.Closeable; import java.io.File; import java.io.IOException; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.ObjectId; @@ -41,7 +49,7 @@ public class GitRepo implements Closeable { private Git git; private final Repository repository; private final RevWalk revWalk; - public final List submodules; + private final List submodules; public GitRepo() { this.repository = null; @@ -137,20 +145,6 @@ public GitRepoData getGitRepoData( } } - public GitRepoData getGitRepoDataSubmodule( - final GitRepo submodule, - final ObjectId from, - final ObjectId to, - final String untaggedName, - final Optional ignoreTagsIfNameMatches) - throws GitChangelogRepositoryException { - try { - return submodule.getGitRepoData(from, to, untaggedName, ignoreTagsIfNameMatches); - } catch (final Exception e) { - throw new GitChangelogRepositoryException(toString(), e); - } - } - public ObjectId getRef(final String fromRef) throws GitChangelogRepositoryException { try { for (final Ref foundRef : getAllRefs().values()) { @@ -171,7 +165,11 @@ public ObjectId getRef(final String fromRef) throws GitChangelogRepositoryExcept } public boolean hasSubmodules() { - return submodules != null; + return submodules != null && submodules.size() > 0; + } + + public List getSubmodules() { + return submodules; } @Override From 4e1585352efebcd17a41296ab8070faf4391481e Mon Sep 17 00:00:00 2001 From: Dmitry Mamchur Date: Tue, 3 Mar 2020 15:26:49 +0000 Subject: [PATCH 08/20] undo newline --- src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java b/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java index 7dadeeff..4879a94d 100644 --- a/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java +++ b/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java @@ -445,7 +445,6 @@ private Changelog getChangelog(final GitRepo gitRepo, final boolean useIntegrati } else { toId = gitRepo.getRef(REF_MASTER); } - GitRepoData gitRepoData = gitRepo.getGitRepoData( fromId, From 34e52523e8543203a205272c04a21ecebe2c115f Mon Sep 17 00:00:00 2001 From: Dmitry Mamchur Date: Fri, 20 Mar 2020 11:19:34 +0000 Subject: [PATCH 09/20] handle uninitialized submodules --- .../java/se/bjurr/gitchangelog/internal/git/GitRepo.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/se/bjurr/gitchangelog/internal/git/GitRepo.java b/src/main/java/se/bjurr/gitchangelog/internal/git/GitRepo.java index 9b96edc8..3afb8d3e 100644 --- a/src/main/java/se/bjurr/gitchangelog/internal/git/GitRepo.java +++ b/src/main/java/se/bjurr/gitchangelog/internal/git/GitRepo.java @@ -81,8 +81,10 @@ public GitRepo(final File repo) throws GitChangelogRepositoryException { final SubmoduleWalk submoduleWalk = SubmoduleWalk.forIndex(repository); while (submoduleWalk.next()) { final Repository submoduleRepository = submoduleWalk.getRepository(); - this.submodules.add(new GitRepo(submoduleRepository.getDirectory())); - submoduleRepository.close(); + if (submoduleRepository != null) { + this.submodules.add(new GitRepo(submoduleRepository.getDirectory())); + submoduleRepository.close(); + } } } else { this.submodules = null; From c33d1f45c1f9af70be893a659d07111b8c16a0b4 Mon Sep 17 00:00:00 2001 From: Dmitry Mamchur Date: Tue, 24 Mar 2020 10:42:09 +0000 Subject: [PATCH 10/20] submodule support v2 --- .../gitchangelog/api/GitChangelogApi.java | 48 ++++------ .../bjurr/gitchangelog/api/model/Author.java | 2 +- .../gitchangelog/api/model/Changelog.java | 2 +- .../bjurr/gitchangelog/api/model/Commit.java | 11 ++- .../bjurr/gitchangelog/api/model/Issue.java | 2 +- .../gitchangelog/api/model/IssueType.java | 2 +- .../api/model/SubmoduleSection.java | 43 --------- .../se/bjurr/gitchangelog/api/model/Tag.java | 9 +- .../gitchangelog/internal/git/GitRepo.java | 91 ++++++++++++++----- .../internal/git/GitSubmoduleParser.java | 91 +++++++++++++++++++ .../internal/model/Transformer.java | 89 +++++++----------- .../internal/model/CommitFilterTest.java | 6 +- 12 files changed, 231 insertions(+), 165 deletions(-) delete mode 100644 src/main/java/se/bjurr/gitchangelog/api/model/SubmoduleSection.java create mode 100644 src/main/java/se/bjurr/gitchangelog/internal/git/GitSubmoduleParser.java diff --git a/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java b/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java index 4879a94d..ebfb2dae 100644 --- a/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java +++ b/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java @@ -8,6 +8,7 @@ import static com.google.common.io.Files.createParentDirs; import static com.google.common.io.Files.write; import static com.google.common.io.Resources.getResource; +import static org.slf4j.LoggerFactory.getLogger; import static se.bjurr.gitchangelog.api.GitChangelogApiConstants.REF_MASTER; import static se.bjurr.gitchangelog.api.GitChangelogApiConstants.ZERO_COMMIT; import static se.bjurr.gitchangelog.internal.git.GitRepoDataHelper.removeCommitsWithoutIssue; @@ -27,19 +28,16 @@ import java.io.Writer; import java.net.URL; import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Map; +import java.util.*; import org.eclipse.jgit.lib.ObjectId; +import org.slf4j.Logger; import se.bjurr.gitchangelog.api.exceptions.GitChangelogIntegrationException; import se.bjurr.gitchangelog.api.exceptions.GitChangelogRepositoryException; import se.bjurr.gitchangelog.api.model.Changelog; import se.bjurr.gitchangelog.api.model.Issue; -import se.bjurr.gitchangelog.api.model.SubmoduleSection; -import se.bjurr.gitchangelog.api.model.Tag; import se.bjurr.gitchangelog.internal.git.GitRepo; import se.bjurr.gitchangelog.internal.git.GitRepoData; +import se.bjurr.gitchangelog.internal.git.GitSubmoduleParser; import se.bjurr.gitchangelog.internal.git.model.GitCommit; import se.bjurr.gitchangelog.internal.git.model.GitTag; import se.bjurr.gitchangelog.internal.integrations.mediawiki.MediaWikiClient; @@ -50,6 +48,7 @@ import se.bjurr.gitchangelog.internal.settings.SettingsIssue; public class GitChangelogApi { + private static final Logger LOG = getLogger(GitChangelogApi.class); public static GitChangelogApi gitChangelogApiBuilder() { return new GitChangelogApi(); @@ -383,6 +382,12 @@ public GitChangelogApi withSettings(final URL url) { return this; } + /** {@link Settings}. */ + public GitChangelogApi withSettings(final Settings settings) { + this.settings = settings; + return this; + } + /** Use string as template. {@link #withTemplatePath}. */ public GitChangelogApi withTemplateContent(final String templateContent) { this.templateContent = templateContent; @@ -469,33 +474,20 @@ private Changelog getChangelog(final GitRepo gitRepo, final boolean useIntegrati } final List tags = gitRepoData.getGitTags(); - List> allSubmoduleSections = null; + HashMap> submoduleMap = null; if (gitRepo.hasSubmodules()) { - allSubmoduleSections = new ArrayList<>(); - - for (GitRepo submodule : gitRepo.getSubmodules()) { - final Changelog submoduleChangelog = getChangelog(submodule, useIntegrationIfConfigured); - - List submoduleSections = new ArrayList<>(); - for (Tag tag : submoduleChangelog.getTags()) { - submoduleSections.add( - new SubmoduleSection( - submoduleChangelog.getOwnerName(), - submoduleChangelog.getRepoName(), - tag.getName(), - tag.getIssues())); - } - allSubmoduleSections.add(submoduleSections); - } + submoduleMap = + new GitSubmoduleParser() + .parseForSubmodules(this, useIntegrationIfConfigured, gitRepo, diff); } final Transformer transformer = new Transformer(this.settings); return new Changelog( // - transformer.toCommits(diff), // - transformer.toTags(tags, issues, allSubmoduleSections), // - transformer.toAuthors(diff), // - transformer.toIssues(issues), // - transformer.toIssueTypes(issues), // + transformer.toCommits(diff, submoduleMap), // + transformer.toTags(tags, issues, submoduleMap), // + transformer.toAuthors(diff, submoduleMap), // + transformer.toIssues(issues, submoduleMap), // + transformer.toIssueTypes(issues, submoduleMap), // gitRepoData.findOwnerName().orNull(), // gitRepoData.findRepoName().orNull()); } diff --git a/src/main/java/se/bjurr/gitchangelog/api/model/Author.java b/src/main/java/se/bjurr/gitchangelog/api/model/Author.java index dc70ca8a..458f239a 100644 --- a/src/main/java/se/bjurr/gitchangelog/api/model/Author.java +++ b/src/main/java/se/bjurr/gitchangelog/api/model/Author.java @@ -5,7 +5,7 @@ import se.bjurr.gitchangelog.api.model.interfaces.ICommits; public class Author implements ICommits, Serializable { - private static final long serialVersionUID = -672028657732998142L; + private static final long serialVersionUID = -672028657732998143L; private final List commits; private final String authorName; private final String authorEmail; diff --git a/src/main/java/se/bjurr/gitchangelog/api/model/Changelog.java b/src/main/java/se/bjurr/gitchangelog/api/model/Changelog.java index e82f801b..47b3a76e 100644 --- a/src/main/java/se/bjurr/gitchangelog/api/model/Changelog.java +++ b/src/main/java/se/bjurr/gitchangelog/api/model/Changelog.java @@ -9,7 +9,7 @@ import se.bjurr.gitchangelog.api.model.interfaces.IIssues; public class Changelog implements ICommits, IAuthors, IIssues, Serializable { - private static final long serialVersionUID = 2193789018496738737L; + private static final long serialVersionUID = 2193789018496738738L; private final List commits; private final List tags; private final List authors; diff --git a/src/main/java/se/bjurr/gitchangelog/api/model/Commit.java b/src/main/java/se/bjurr/gitchangelog/api/model/Commit.java index d81e93d9..0219253d 100644 --- a/src/main/java/se/bjurr/gitchangelog/api/model/Commit.java +++ b/src/main/java/se/bjurr/gitchangelog/api/model/Commit.java @@ -10,7 +10,7 @@ import java.util.List; public class Commit implements Serializable { - private static final long serialVersionUID = 6622555148468372816L; + private static final long serialVersionUID = 6622555148468372817L; private static List notFirst(List stringList) { return stringList.subList(1, stringList.size()); @@ -77,6 +77,7 @@ static String toMessageTitle(String message) { private final String hashFull; private final Boolean merge; private final String message; + private final List submoduleSections; public Commit( String authorName, @@ -85,7 +86,8 @@ public Commit( Long commitTimeLong, String message, String hash, - Boolean merge) { + Boolean merge, + List submoduleSections) { this.authorName = checkNotNull(authorName, "authorName"); this.authorEmailAddress = checkNotNull(authorEmailAddress, "authorEmailAddress"); this.message = checkNotNull(message, "message").trim(); @@ -94,6 +96,7 @@ public Commit( this.hash = toHash(checkNotNull(hash, "hash")); this.hashFull = checkNotNull(hash, "hashFull"); this.merge = checkNotNull(merge, "merge"); + this.submoduleSections = submoduleSections; } public String getAuthorEmailAddress() { @@ -140,6 +143,10 @@ public Boolean isMerge() { return this.merge; } + public List getSubmoduleSections() { + return this.submoduleSections; + } + @Override public String toString() { return "hash: " + this.hash + " message: " + this.message; diff --git a/src/main/java/se/bjurr/gitchangelog/api/model/Issue.java b/src/main/java/se/bjurr/gitchangelog/api/model/Issue.java index 05ae4f92..27f3576d 100644 --- a/src/main/java/se/bjurr/gitchangelog/api/model/Issue.java +++ b/src/main/java/se/bjurr/gitchangelog/api/model/Issue.java @@ -18,7 +18,7 @@ public class Issue implements ICommits, IAuthors, Serializable { - private static final long serialVersionUID = -7571341639024417199L; + private static final long serialVersionUID = -7571341639024417200L; private final List commits; private final List authors; /** Like JIRA, or GitHub. */ diff --git a/src/main/java/se/bjurr/gitchangelog/api/model/IssueType.java b/src/main/java/se/bjurr/gitchangelog/api/model/IssueType.java index 9abf0c72..113175bf 100644 --- a/src/main/java/se/bjurr/gitchangelog/api/model/IssueType.java +++ b/src/main/java/se/bjurr/gitchangelog/api/model/IssueType.java @@ -14,7 +14,7 @@ public class IssueType implements Serializable { - private static final long serialVersionUID = 8850522973130773606L; + private static final long serialVersionUID = 8850522973130773607L; private final String name; private final List issues; private final SettingsIssueType type; diff --git a/src/main/java/se/bjurr/gitchangelog/api/model/SubmoduleSection.java b/src/main/java/se/bjurr/gitchangelog/api/model/SubmoduleSection.java deleted file mode 100644 index 9c1cc886..00000000 --- a/src/main/java/se/bjurr/gitchangelog/api/model/SubmoduleSection.java +++ /dev/null @@ -1,43 +0,0 @@ -package se.bjurr.gitchangelog.api.model; - -import java.io.Serializable; -import java.util.List; -import se.bjurr.gitchangelog.api.model.interfaces.IIssues; - -public class SubmoduleSection implements Serializable, IIssues { - private static final long serialVersionUID = 2140208294219785889L; - - private final String ownerName; - private final String repoName; - private final String tagName; - private final List issues; - - public SubmoduleSection(String ownerName, String repoName, String tagName, List issues) { - this.ownerName = ownerName; - this.repoName = repoName; - this.tagName = tagName; - this.issues = issues; - } - - public String getTagName() { - return this.tagName; - } - - @Override - public List getIssues() { - return this.issues; - } - - @Override - public String toString() { - return "name: " + this.repoName; - } - - public String getOwnerName() { - return ownerName; - } - - public String getRepoName() { - return repoName; - } -} diff --git a/src/main/java/se/bjurr/gitchangelog/api/model/Tag.java b/src/main/java/se/bjurr/gitchangelog/api/model/Tag.java index 7a604914..bf475883 100644 --- a/src/main/java/se/bjurr/gitchangelog/api/model/Tag.java +++ b/src/main/java/se/bjurr/gitchangelog/api/model/Tag.java @@ -14,7 +14,6 @@ public class Tag implements ICommits, IAuthors, IIssues, Serializable { private final List authors; private final List commits; private final List issues; - private final List submoduleSections; private final List issueTypes; private final String name; private final String tagTime; @@ -29,8 +28,7 @@ public Tag( List issues, List issueTypes, String tagTime, - Long tagTimeLong, - List submoduleSections) { + Long tagTimeLong) { this.commits = commits; this.authors = authors; this.issues = issues; @@ -40,7 +38,6 @@ public Tag( this.tagTime = tagTime; this.tagTimeLong = tagTimeLong; this.hasTagTime = !isNullOrEmpty(tagTime); - this.submoduleSections = submoduleSections; } public String getAnnotation() { @@ -66,10 +63,6 @@ public List getIssues() { return this.issues; } - public List getSubmoduleSections() { - return this.submoduleSections; - } - public List getIssueTypes() { return this.issueTypes; } diff --git a/src/main/java/se/bjurr/gitchangelog/internal/git/GitRepo.java b/src/main/java/se/bjurr/gitchangelog/internal/git/GitRepo.java index 3afb8d3e..36369dae 100644 --- a/src/main/java/se/bjurr/gitchangelog/internal/git/GitRepo.java +++ b/src/main/java/se/bjurr/gitchangelog/internal/git/GitRepo.java @@ -14,28 +14,20 @@ import com.google.common.base.Optional; import com.google.common.collect.Ordering; -import java.io.Closeable; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Comparator; -import java.util.Date; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; +import java.io.*; +import java.util.*; import org.eclipse.jgit.api.Git; -import org.eclipse.jgit.lib.AnyObjectId; -import org.eclipse.jgit.lib.ObjectId; -import org.eclipse.jgit.lib.Ref; -import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.diff.DiffEntry; +import org.eclipse.jgit.diff.DiffFormatter; +import org.eclipse.jgit.errors.ConfigInvalidException; +import org.eclipse.jgit.lib.*; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevTag; +import org.eclipse.jgit.revwalk.RevTree; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.storage.file.FileRepositoryBuilder; import org.eclipse.jgit.submodule.SubmoduleWalk; +import org.eclipse.jgit.treewalk.CanonicalTreeParser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import se.bjurr.gitchangelog.api.GitChangelogApiConstants; @@ -49,7 +41,7 @@ public class GitRepo implements Closeable { private Git git; private final Repository repository; private final RevWalk revWalk; - private final List submodules; + private final HashMap submodules; public GitRepo() { this.repository = null; @@ -77,12 +69,17 @@ public GitRepo(final File repo) throws GitChangelogRepositoryException { this.git = new Git(this.repository); if (SubmoduleWalk.containsGitModulesFile(repository)) { - this.submodules = new ArrayList<>(); + this.submodules = new HashMap<>(); final SubmoduleWalk submoduleWalk = SubmoduleWalk.forIndex(repository); while (submoduleWalk.next()) { final Repository submoduleRepository = submoduleWalk.getRepository(); if (submoduleRepository != null) { - this.submodules.add(new GitRepo(submoduleRepository.getDirectory())); + try { + String submodulePath = submoduleWalk.getModulesPath(); + this.submodules.put(submodulePath, new GitRepo(submoduleRepository.getDirectory())); + } catch (ConfigInvalidException e) { + LOG.warn("invalid submodule configuration; skipping submodule\n" + e); + } submoduleRepository.close(); } } @@ -109,8 +106,8 @@ public void close() throws IOException { } } if (submodules != null) { - for (GitRepo submodule : submodules) { - submodule.close(); + for (Map.Entry submodule : submodules.entrySet()) { + submodule.getValue().close(); } } } @@ -170,8 +167,39 @@ public boolean hasSubmodules() { return submodules != null && submodules.size() > 0; } - public List getSubmodules() { - return submodules; + public GitRepo getSubmodule(String submodulePath) { + return submodules.getOrDefault(submodulePath, null); + } + + public String getDiff(String commitHash) { + RevCommit commit = null; + RevCommit prevCommit = null; + + try { + commit = this.revWalk.parseCommit(getCommit(commitHash)); + prevCommit = commit.getParentCount() > 0 ? commit.getParent(0) : null; + } catch (GitChangelogRepositoryException | IOException e) { + e.printStackTrace(); + } + + OutputStream outputStream = new ByteArrayOutputStream(); + DiffFormatter diffFormatter = new DiffFormatter(outputStream); + diffFormatter.setRepository(this.repository); + diffFormatter.setAbbreviationLength(10); + + try { + for (DiffEntry entry : diffFormatter.scan(prevCommit, commit)) { + diffFormatter.format(diffFormatter.toFileHeader(entry)); + } + } catch (IOException e) { + e.printStackTrace(); + } + + return outputStream.toString(); + } + + public String getDirectory() { + return this.repository.getDirectory().getAbsolutePath(); } @Override @@ -183,6 +211,23 @@ public String toString() { return "Repo: " + this.repository + "\n" + sb.toString(); } + private CanonicalTreeParser getTreeParser(RevCommit commit) { + LOG.info("getTreeParser for " + commit.toString()); + RevTree revTree = commit.getTree(); + if (revTree == null) { + LOG.info("revTree is null"); + return null; + } + ObjectId treeId = commit.getTree().getId(); + ObjectReader reader = this.repository.newObjectReader(); + try { + return new CanonicalTreeParser(null, reader, treeId); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + private boolean addCommitToCurrentTag( final Map> commitsPerTagName, final String currentTagName, diff --git a/src/main/java/se/bjurr/gitchangelog/internal/git/GitSubmoduleParser.java b/src/main/java/se/bjurr/gitchangelog/internal/git/GitSubmoduleParser.java new file mode 100644 index 00000000..e04a6519 --- /dev/null +++ b/src/main/java/se/bjurr/gitchangelog/internal/git/GitSubmoduleParser.java @@ -0,0 +1,91 @@ +package se.bjurr.gitchangelog.internal.git; + +import static org.slf4j.LoggerFactory.getLogger; + +import com.google.common.base.Optional; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.slf4j.Logger; +import se.bjurr.gitchangelog.api.GitChangelogApi; +import se.bjurr.gitchangelog.api.exceptions.GitChangelogRepositoryException; +import se.bjurr.gitchangelog.api.model.Changelog; +import se.bjurr.gitchangelog.internal.git.model.GitCommit; +import se.bjurr.gitchangelog.internal.settings.Settings; + +public class GitSubmoduleParser { + private static final Logger LOG = getLogger(GitSubmoduleParser.class); + + public GitSubmoduleParser() {} + + public HashMap> parseForSubmodules( + final GitChangelogApi gitChangelogApi, + final boolean useIntegrationIfConfigured, + final GitRepo gitRepo, + final List commits) { + + HashMap> submoduleSections = new HashMap<>(); + Pattern submoduleNamePattern = + Pattern.compile( + "(?m)^\\+{3} b/([\\w/\\s-]+)$\\n-Subproject commit (\\w+)$\\n\\+Subproject commit (\\w+)$"); + + Settings settings = gitChangelogApi.getSettings(); + + Optional cachedFromCommit = settings.getFromCommit(); + Optional cachedToCommit = settings.getToCommit(); + Optional cachedFromRef = settings.getFromRef(); + Optional cachedToRef = settings.getToRef(); + String cachedFromRepo = settings.getFromRepo(); + + for (GitCommit commit : commits) { + String diff = gitRepo.getDiff(commit.getHash()); + Matcher submoduleMatch = submoduleNamePattern.matcher(diff); + while (submoduleMatch.find()) { + String submoduleName = submoduleMatch.group(1); + String previousSubmoduleHash = submoduleMatch.group(2); + String currentSubmoduleHash = submoduleMatch.group(3); + GitRepo submodule = gitRepo.getSubmodule(submoduleName); + if (submodule == null) { + continue; + } + + settings.setFromCommit(previousSubmoduleHash); + settings.setToCommit(currentSubmoduleHash); + settings.setFromRef(null); + settings.setToRef(null); + settings.setFromRepo(submodule.getDirectory()); + + if (!submoduleSections.containsKey(commit)) { + submoduleSections.put(commit, new ArrayList<>()); + } + List submoduleSectionList = submoduleSections.get(commit); + try { + submoduleSectionList.add( + GitChangelogApi.gitChangelogApiBuilder() + .withSettings(settings) + .getChangelog(useIntegrationIfConfigured)); + } catch (GitChangelogRepositoryException e) { + e.printStackTrace(); + } + } + } + + if (cachedFromCommit.isPresent()) { + settings.setFromCommit(cachedFromCommit.get()); + } + if (cachedToCommit.isPresent()) { + settings.setToCommit(cachedToCommit.get()); + } + if (cachedFromRef.isPresent()) { + settings.setFromRef(cachedFromRef.get()); + } + if (cachedToRef.isPresent()) { + settings.setToRef(cachedToRef.get()); + } + settings.setFromRepo(cachedFromRepo); + + return submoduleSections; + } +} diff --git a/src/main/java/se/bjurr/gitchangelog/internal/model/Transformer.java b/src/main/java/se/bjurr/gitchangelog/internal/model/Transformer.java index 7074edba..21fe4b05 100644 --- a/src/main/java/se/bjurr/gitchangelog/internal/model/Transformer.java +++ b/src/main/java/se/bjurr/gitchangelog/internal/model/Transformer.java @@ -16,18 +16,9 @@ import com.google.common.base.Predicate; import com.google.common.collect.Multimap; import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.regex.Matcher; -import se.bjurr.gitchangelog.api.model.Author; -import se.bjurr.gitchangelog.api.model.Commit; -import se.bjurr.gitchangelog.api.model.Issue; -import se.bjurr.gitchangelog.api.model.IssueType; -import se.bjurr.gitchangelog.api.model.SubmoduleSection; -import se.bjurr.gitchangelog.api.model.Tag; +import se.bjurr.gitchangelog.api.model.*; import se.bjurr.gitchangelog.internal.git.model.GitCommit; import se.bjurr.gitchangelog.internal.git.model.GitTag; import se.bjurr.gitchangelog.internal.settings.IssuesUtil; @@ -42,7 +33,8 @@ public Transformer(Settings settings) { this.settings = settings; } - public List toAuthors(List gitCommits) { + public List toAuthors( + List gitCommits, final HashMap> submoduleSections) { final Multimap commitsPerAuthor = index( gitCommits, @@ -59,7 +51,7 @@ public String apply(GitCommit input) { new Predicate() { @Override public boolean apply(String input) { - return toCommits(commitsPerAuthor.get(input)).size() > 0; + return toCommits(commitsPerAuthor.get(input), submoduleSections).size() > 0; } }); @@ -70,7 +62,8 @@ public boolean apply(String input) { @Override public Author apply(String input) { List gitCommitsOfSameAuthor = newArrayList(commitsPerAuthor.get(input)); - List commitsOfSameAuthor = toCommits(gitCommitsOfSameAuthor); + List commitsOfSameAuthor = + toCommits(gitCommitsOfSameAuthor, submoduleSections); return new Author( // commitsOfSameAuthor.get(0).getAuthorName(), // commitsOfSameAuthor.get(0).getAuthorEmailAddress(), // @@ -79,7 +72,8 @@ public Author apply(String input) { })); } - public List toCommits(Collection from) { + public List toCommits( + Collection from, final HashMap> submoduleSections) { Iterable filteredCommits = filter(from, ignoreCommits(settings)); return newArrayList( transform( @@ -87,25 +81,28 @@ public List toCommits(Collection from) { new Function() { @Override public Commit apply(GitCommit c) { - return toCommit(c); + return toCommit( + c, submoduleSections == null ? null : submoduleSections.getOrDefault(c, null)); } })); } - public List toIssues(List issues) { - Iterable issuesWithCommits = filterWithCommits(issues); + public List toIssues( + List issues, final HashMap> submoduleSections) { + Iterable issuesWithCommits = filterWithCommits(issues, submoduleSections); - return newArrayList(transform(issuesWithCommits, parsedIssueToIssue())); + return newArrayList(transform(issuesWithCommits, parsedIssueToIssue(submoduleSections))); } - public List toIssueTypes(List issues) { + public List toIssueTypes( + List issues, final HashMap> submoduleSections) { Map> issuesPerName = newTreeMap(); - for (ParsedIssue parsedIssue : filterWithCommits(issues)) { + for (ParsedIssue parsedIssue : filterWithCommits(issues, submoduleSections)) { if (!issuesPerName.containsKey(parsedIssue.getName())) { issuesPerName.put(parsedIssue.getName(), new ArrayList()); } - Issue transformedIssues = parsedIssueToIssue().apply(parsedIssue); + Issue transformedIssues = parsedIssueToIssue(submoduleSections).apply(parsedIssue); issuesPerName .get(parsedIssue.getName()) // .add(transformedIssues); @@ -121,7 +118,7 @@ public List toIssueTypes(List issues) { public List toTags( List gitTags, final List allParsedIssues, - final List> allSubmoduleSections) { + final HashMap> submoduleSections) { Iterable tags = transform( @@ -133,12 +130,10 @@ public Tag apply(GitTag input) { final String readableName = toReadableTagName(input.getName()); List parsedIssues = reduceParsedIssuesToOnlyGitCommits(allParsedIssues, gitCommits); - List submoduleSections = - reduceSubmoduleSectionsToOnlyGitTag(allSubmoduleSections, readableName); - List commits = toCommits(gitCommits); - List authors = toAuthors(gitCommits); - List issues = toIssues(parsedIssues); - List issueTypes = toIssueTypes(parsedIssues); + List commits = toCommits(gitCommits, submoduleSections); + List authors = toAuthors(gitCommits, submoduleSections); + List issues = toIssues(parsedIssues, submoduleSections); + List issueTypes = toIssueTypes(parsedIssues, submoduleSections); return new Tag( readableName, input.findAnnotation().orNull(), @@ -147,8 +142,7 @@ public Tag apply(GitTag input) { issues, issueTypes, input.getTagTime() != null ? format(input.getTagTime()) : "", - input.getTagTime() != null ? input.getTagTime().getTime() : -1, - submoduleSections); + input.getTagTime() != null ? input.getTagTime().getTime() : -1); } private List reduceParsedIssuesToOnlyGitCommits( @@ -175,22 +169,6 @@ private List reduceParsedIssuesToOnlyGitCommits( } return parsedIssues; } - - private List reduceSubmoduleSectionsToOnlyGitTag( - List> allSubmoduleSections, String tagName) { - List result = newArrayList(); - if (allSubmoduleSections == null) { - return null; - } - for (List submoduleSections : allSubmoduleSections) { - for (SubmoduleSection submoduleSection : submoduleSections) { - if (submoduleSection.getTagName().equals(tagName)) { - result.add(submoduleSection); - } - } - } - return result; - } }); tags = @@ -206,14 +184,15 @@ public boolean apply(Tag input) { return newArrayList(tags); } - private Iterable filterWithCommits(List issues) { + private Iterable filterWithCommits( + List issues, final HashMap> submoduleSections) { Iterable issuesWithCommits = filter( issues, new Predicate() { @Override public boolean apply(ParsedIssue input) { - return !toCommits(input.getGitCommits()).isEmpty(); + return !toCommits(input.getGitCommits(), submoduleSections).isEmpty(); } }); return issuesWithCommits; @@ -225,14 +204,15 @@ private String format(Date commitTime) { return df.format(commitTime); } - private Function parsedIssueToIssue() { + private Function parsedIssueToIssue( + final HashMap> submoduleSections) { return new Function() { @Override public Issue apply(ParsedIssue input) { List gitCommits = input.getGitCommits(); return new Issue( // - toCommits(gitCommits), // - toAuthors(gitCommits), // + toCommits(gitCommits, submoduleSections), // + toAuthors(gitCommits, submoduleSections), // input.getName(), // input.getTitle().or(""), // input.getIssue(), // @@ -256,7 +236,7 @@ private String removeIssuesFromString( return string; } - private Commit toCommit(GitCommit gitCommit) { + private Commit toCommit(GitCommit gitCommit, List submoduleSections) { return new Commit( // gitCommit.getAuthorName(), // gitCommit.getAuthorEmailAddress(), // @@ -267,7 +247,8 @@ private Commit toCommit(GitCommit gitCommit) { new IssuesUtil(this.settings).getIssues(), gitCommit.getMessage()), // gitCommit.getHash(), // - gitCommit.isMerge()); + gitCommit.isMerge(), + submoduleSections); } private String toReadableTagName(String input) { diff --git a/src/test/java/se/bjurr/gitchangelog/internal/model/CommitFilterTest.java b/src/test/java/se/bjurr/gitchangelog/internal/model/CommitFilterTest.java index 9224e651..59d11f41 100644 --- a/src/test/java/se/bjurr/gitchangelog/internal/model/CommitFilterTest.java +++ b/src/test/java/se/bjurr/gitchangelog/internal/model/CommitFilterTest.java @@ -57,7 +57,7 @@ public void before() throws Exception { @Test public void testThatFilterWithIgnoreCommitsWithMessageWorks() throws Exception { settings.setIgnoreCommitsIfMessageMatches(TEST_COMMIT_MESSAGE_PATTERN); - List transformedCommits = hashes(new Transformer(settings).toCommits(commits)); + List transformedCommits = hashes(new Transformer(settings).toCommits(commits, null)); assertThat(transformedCommits).contains(NONMATCHING_COMMIT_HASH); assertThat(transformedCommits).doesNotContain(MATCHING_COMMIT_1_HASH, MATCHING_COMMIT_2_HASH); } @@ -66,7 +66,7 @@ public void testThatFilterWithIgnoreCommitsWithMessageWorks() throws Exception { public void testThatFilterWithIgnoreCommitsOlderThanWorks() throws Exception { settings.setIgnoreCommitsIfMessageMatches(""); settings.setIgnoreCommitsIfOlderThan(date2017); - List transformedCommits = hashes(new Transformer(settings).toCommits(commits)); + List transformedCommits = hashes(new Transformer(settings).toCommits(commits, null)); assertThat(transformedCommits).doesNotContain(LATEST_2016_COMMIT_HASH); assertThat(transformedCommits) .contains(FIRST_2017_COMMIT_HASH, A_2017_COMMIT_HASH_MATCHING_MESSAGE_PATTERN); @@ -76,7 +76,7 @@ public void testThatFilterWithIgnoreCommitsOlderThanWorks() throws Exception { public void testThatFilterWithIgnoreCommitsWithMessageAndOlderThanWorks() throws Exception { settings.setIgnoreCommitsIfOlderThan(date2017); settings.setIgnoreCommitsIfMessageMatches(TEST_COMMIT_MESSAGE_PATTERN); - List transformedCommits = hashes(new Transformer(settings).toCommits(commits)); + List transformedCommits = hashes(new Transformer(settings).toCommits(commits, null)); assertThat(transformedCommits).contains(FIRST_2017_COMMIT_HASH); assertThat(transformedCommits) .doesNotContain(LATEST_2016_COMMIT_HASH, A_2017_COMMIT_HASH_MATCHING_MESSAGE_PATTERN); From c596fcddc66df59473e3de2c1915079d5bf6a0b2 Mon Sep 17 00:00:00 2001 From: Dmitry Mamchur Date: Tue, 24 Mar 2020 11:44:29 +0000 Subject: [PATCH 11/20] switch to hash key --- .../gitchangelog/api/GitChangelogApi.java | 2 +- .../internal/git/GitSubmoduleParser.java | 11 ++++++----- .../internal/model/Transformer.java | 19 +++++++++++-------- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java b/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java index ebfb2dae..8013b45d 100644 --- a/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java +++ b/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java @@ -474,7 +474,7 @@ private Changelog getChangelog(final GitRepo gitRepo, final boolean useIntegrati } final List tags = gitRepoData.getGitTags(); - HashMap> submoduleMap = null; + HashMap> submoduleMap = null; if (gitRepo.hasSubmodules()) { submoduleMap = new GitSubmoduleParser() diff --git a/src/main/java/se/bjurr/gitchangelog/internal/git/GitSubmoduleParser.java b/src/main/java/se/bjurr/gitchangelog/internal/git/GitSubmoduleParser.java index e04a6519..13106ff9 100644 --- a/src/main/java/se/bjurr/gitchangelog/internal/git/GitSubmoduleParser.java +++ b/src/main/java/se/bjurr/gitchangelog/internal/git/GitSubmoduleParser.java @@ -20,13 +20,13 @@ public class GitSubmoduleParser { public GitSubmoduleParser() {} - public HashMap> parseForSubmodules( + public HashMap> parseForSubmodules( final GitChangelogApi gitChangelogApi, final boolean useIntegrationIfConfigured, final GitRepo gitRepo, final List commits) { - HashMap> submoduleSections = new HashMap<>(); + HashMap> submoduleSections = new HashMap<>(); Pattern submoduleNamePattern = Pattern.compile( "(?m)^\\+{3} b/([\\w/\\s-]+)$\\n-Subproject commit (\\w+)$\\n\\+Subproject commit (\\w+)$"); @@ -57,10 +57,11 @@ public HashMap> parseForSubmodules( settings.setToRef(null); settings.setFromRepo(submodule.getDirectory()); - if (!submoduleSections.containsKey(commit)) { - submoduleSections.put(commit, new ArrayList<>()); + String commitHash = commit.getHash(); + if (!submoduleSections.containsKey(commitHash)) { + submoduleSections.put(commitHash, new ArrayList<>()); } - List submoduleSectionList = submoduleSections.get(commit); + List submoduleSectionList = submoduleSections.get(commitHash); try { submoduleSectionList.add( GitChangelogApi.gitChangelogApiBuilder() diff --git a/src/main/java/se/bjurr/gitchangelog/internal/model/Transformer.java b/src/main/java/se/bjurr/gitchangelog/internal/model/Transformer.java index 21fe4b05..0d78fe8c 100644 --- a/src/main/java/se/bjurr/gitchangelog/internal/model/Transformer.java +++ b/src/main/java/se/bjurr/gitchangelog/internal/model/Transformer.java @@ -34,7 +34,7 @@ public Transformer(Settings settings) { } public List toAuthors( - List gitCommits, final HashMap> submoduleSections) { + List gitCommits, final HashMap> submoduleSections) { final Multimap commitsPerAuthor = index( gitCommits, @@ -73,7 +73,7 @@ public Author apply(String input) { } public List toCommits( - Collection from, final HashMap> submoduleSections) { + Collection from, final HashMap> submoduleSections) { Iterable filteredCommits = filter(from, ignoreCommits(settings)); return newArrayList( transform( @@ -82,20 +82,23 @@ public List toCommits( @Override public Commit apply(GitCommit c) { return toCommit( - c, submoduleSections == null ? null : submoduleSections.getOrDefault(c, null)); + c, + submoduleSections == null + ? null + : submoduleSections.getOrDefault(c.getHash(), null)); } })); } public List toIssues( - List issues, final HashMap> submoduleSections) { + List issues, final HashMap> submoduleSections) { Iterable issuesWithCommits = filterWithCommits(issues, submoduleSections); return newArrayList(transform(issuesWithCommits, parsedIssueToIssue(submoduleSections))); } public List toIssueTypes( - List issues, final HashMap> submoduleSections) { + List issues, final HashMap> submoduleSections) { Map> issuesPerName = newTreeMap(); for (ParsedIssue parsedIssue : filterWithCommits(issues, submoduleSections)) { @@ -118,7 +121,7 @@ public List toIssueTypes( public List toTags( List gitTags, final List allParsedIssues, - final HashMap> submoduleSections) { + final HashMap> submoduleSections) { Iterable tags = transform( @@ -185,7 +188,7 @@ public boolean apply(Tag input) { } private Iterable filterWithCommits( - List issues, final HashMap> submoduleSections) { + List issues, final HashMap> submoduleSections) { Iterable issuesWithCommits = filter( issues, @@ -205,7 +208,7 @@ private String format(Date commitTime) { } private Function parsedIssueToIssue( - final HashMap> submoduleSections) { + final HashMap> submoduleSections) { return new Function() { @Override public Issue apply(ParsedIssue input) { From 524323394701e72904824fa4ec199fc70c314b02 Mon Sep 17 00:00:00 2001 From: Dmitry Mamchur Date: Wed, 25 Mar 2020 11:44:14 +0000 Subject: [PATCH 12/20] fix regex, simplify settings restoration code --- .../internal/git/GitSubmoduleParser.java | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/src/main/java/se/bjurr/gitchangelog/internal/git/GitSubmoduleParser.java b/src/main/java/se/bjurr/gitchangelog/internal/git/GitSubmoduleParser.java index 13106ff9..eefe7f10 100644 --- a/src/main/java/se/bjurr/gitchangelog/internal/git/GitSubmoduleParser.java +++ b/src/main/java/se/bjurr/gitchangelog/internal/git/GitSubmoduleParser.java @@ -29,7 +29,7 @@ public HashMap> parseForSubmodules( HashMap> submoduleSections = new HashMap<>(); Pattern submoduleNamePattern = Pattern.compile( - "(?m)^\\+{3} b/([\\w/\\s-]+)$\\n-Subproject commit (\\w+)$\\n\\+Subproject commit (\\w+)$"); + "(?m)^\\+{3} b/([\\w/\\s-]+)$\\n@.+\\n-Subproject commit (\\w+)$\\n\\+Subproject commit (\\w+)$"); Settings settings = gitChangelogApi.getSettings(); @@ -73,18 +73,10 @@ public HashMap> parseForSubmodules( } } - if (cachedFromCommit.isPresent()) { - settings.setFromCommit(cachedFromCommit.get()); - } - if (cachedToCommit.isPresent()) { - settings.setToCommit(cachedToCommit.get()); - } - if (cachedFromRef.isPresent()) { - settings.setFromRef(cachedFromRef.get()); - } - if (cachedToRef.isPresent()) { - settings.setToRef(cachedToRef.get()); - } + settings.setFromCommit(cachedFromCommit.orNull()); + settings.setToCommit(cachedToCommit.orNull()); + settings.setFromRef(cachedFromRef.orNull()); + settings.setToRef(cachedToRef.orNull()); settings.setFromRepo(cachedFromRepo); return submoduleSections; From d12b2c6573ff5f4fc7f09827b8cf97aa7e71d62d Mon Sep 17 00:00:00 2001 From: Dmitry Mamchur Date: Wed, 25 Mar 2020 11:50:19 +0000 Subject: [PATCH 13/20] remove extra logs --- src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java | 3 --- src/main/java/se/bjurr/gitchangelog/internal/git/GitRepo.java | 2 -- 2 files changed, 5 deletions(-) diff --git a/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java b/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java index 8013b45d..18585249 100644 --- a/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java +++ b/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java @@ -8,7 +8,6 @@ import static com.google.common.io.Files.createParentDirs; import static com.google.common.io.Files.write; import static com.google.common.io.Resources.getResource; -import static org.slf4j.LoggerFactory.getLogger; import static se.bjurr.gitchangelog.api.GitChangelogApiConstants.REF_MASTER; import static se.bjurr.gitchangelog.api.GitChangelogApiConstants.ZERO_COMMIT; import static se.bjurr.gitchangelog.internal.git.GitRepoDataHelper.removeCommitsWithoutIssue; @@ -30,7 +29,6 @@ import java.text.SimpleDateFormat; import java.util.*; import org.eclipse.jgit.lib.ObjectId; -import org.slf4j.Logger; import se.bjurr.gitchangelog.api.exceptions.GitChangelogIntegrationException; import se.bjurr.gitchangelog.api.exceptions.GitChangelogRepositoryException; import se.bjurr.gitchangelog.api.model.Changelog; @@ -48,7 +46,6 @@ import se.bjurr.gitchangelog.internal.settings.SettingsIssue; public class GitChangelogApi { - private static final Logger LOG = getLogger(GitChangelogApi.class); public static GitChangelogApi gitChangelogApiBuilder() { return new GitChangelogApi(); diff --git a/src/main/java/se/bjurr/gitchangelog/internal/git/GitRepo.java b/src/main/java/se/bjurr/gitchangelog/internal/git/GitRepo.java index 36369dae..7465f2ba 100644 --- a/src/main/java/se/bjurr/gitchangelog/internal/git/GitRepo.java +++ b/src/main/java/se/bjurr/gitchangelog/internal/git/GitRepo.java @@ -212,10 +212,8 @@ public String toString() { } private CanonicalTreeParser getTreeParser(RevCommit commit) { - LOG.info("getTreeParser for " + commit.toString()); RevTree revTree = commit.getTree(); if (revTree == null) { - LOG.info("revTree is null"); return null; } ObjectId treeId = commit.getTree().getId(); From 59f9c079a903d2e19025952146cba5ec1228d5f9 Mon Sep 17 00:00:00 2001 From: Dmitry Mamchur Date: Tue, 7 Apr 2020 10:53:21 +0100 Subject: [PATCH 14/20] return submodules as a list of changelogs --- .../gitchangelog/api/GitChangelogApi.java | 15 ++-- .../gitchangelog/api/model/Changelog.java | 7 ++ .../bjurr/gitchangelog/api/model/Commit.java | 9 +-- .../internal/git/GitSubmoduleParser.java | 78 ++++++++++++------- .../internal/model/Transformer.java | 61 ++++++--------- 5 files changed, 91 insertions(+), 79 deletions(-) diff --git a/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java b/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java index 18585249..209d430d 100644 --- a/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java +++ b/src/main/java/se/bjurr/gitchangelog/api/GitChangelogApi.java @@ -471,20 +471,21 @@ private Changelog getChangelog(final GitRepo gitRepo, final boolean useIntegrati } final List tags = gitRepoData.getGitTags(); - HashMap> submoduleMap = null; + List submodules = new ArrayList<>(); if (gitRepo.hasSubmodules()) { - submoduleMap = + submodules = new GitSubmoduleParser() .parseForSubmodules(this, useIntegrationIfConfigured, gitRepo, diff); } final Transformer transformer = new Transformer(this.settings); return new Changelog( // - transformer.toCommits(diff, submoduleMap), // - transformer.toTags(tags, issues, submoduleMap), // - transformer.toAuthors(diff, submoduleMap), // - transformer.toIssues(issues, submoduleMap), // - transformer.toIssueTypes(issues, submoduleMap), // + transformer.toCommits(diff), // + transformer.toTags(tags, issues), // + transformer.toAuthors(diff), // + transformer.toIssues(issues), // + transformer.toIssueTypes(issues), // + submodules, // gitRepoData.findOwnerName().orNull(), // gitRepoData.findRepoName().orNull()); } diff --git a/src/main/java/se/bjurr/gitchangelog/api/model/Changelog.java b/src/main/java/se/bjurr/gitchangelog/api/model/Changelog.java index 47b3a76e..7ef260a6 100644 --- a/src/main/java/se/bjurr/gitchangelog/api/model/Changelog.java +++ b/src/main/java/se/bjurr/gitchangelog/api/model/Changelog.java @@ -15,6 +15,7 @@ public class Changelog implements ICommits, IAuthors, IIssues, Serializable { private final List authors; private final List issues; private final List issueTypes; + private final List submodules; private final String ownerName; private final String repoName; @@ -24,6 +25,7 @@ public Changelog( List authors, List issues, List issueTypes, + List submodules, String ownerName, String repoName) { this.commits = checkNotNull(commits, "commits"); @@ -31,6 +33,7 @@ public Changelog( this.authors = checkNotNull(authors, "authors"); this.issues = checkNotNull(issues, "issues"); this.issueTypes = checkNotNull(issueTypes, "issueTypes"); + this.submodules = checkNotNull(submodules, "submodules"); this.ownerName = ownerName; this.repoName = repoName; } @@ -65,4 +68,8 @@ public List getTags() { public List getIssueTypes() { return issueTypes; } + + public List getSubmodules() { + return submodules; + } } diff --git a/src/main/java/se/bjurr/gitchangelog/api/model/Commit.java b/src/main/java/se/bjurr/gitchangelog/api/model/Commit.java index 0219253d..c5b46eca 100644 --- a/src/main/java/se/bjurr/gitchangelog/api/model/Commit.java +++ b/src/main/java/se/bjurr/gitchangelog/api/model/Commit.java @@ -77,7 +77,6 @@ static String toMessageTitle(String message) { private final String hashFull; private final Boolean merge; private final String message; - private final List submoduleSections; public Commit( String authorName, @@ -86,8 +85,7 @@ public Commit( Long commitTimeLong, String message, String hash, - Boolean merge, - List submoduleSections) { + Boolean merge) { this.authorName = checkNotNull(authorName, "authorName"); this.authorEmailAddress = checkNotNull(authorEmailAddress, "authorEmailAddress"); this.message = checkNotNull(message, "message").trim(); @@ -96,7 +94,6 @@ public Commit( this.hash = toHash(checkNotNull(hash, "hash")); this.hashFull = checkNotNull(hash, "hashFull"); this.merge = checkNotNull(merge, "merge"); - this.submoduleSections = submoduleSections; } public String getAuthorEmailAddress() { @@ -143,10 +140,6 @@ public Boolean isMerge() { return this.merge; } - public List getSubmoduleSections() { - return this.submoduleSections; - } - @Override public String toString() { return "hash: " + this.hash + " message: " + this.message; diff --git a/src/main/java/se/bjurr/gitchangelog/internal/git/GitSubmoduleParser.java b/src/main/java/se/bjurr/gitchangelog/internal/git/GitSubmoduleParser.java index eefe7f10..80b4cf7a 100644 --- a/src/main/java/se/bjurr/gitchangelog/internal/git/GitSubmoduleParser.java +++ b/src/main/java/se/bjurr/gitchangelog/internal/git/GitSubmoduleParser.java @@ -3,9 +3,7 @@ import static org.slf4j.LoggerFactory.getLogger; import com.google.common.base.Optional; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; +import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.slf4j.Logger; @@ -20,16 +18,17 @@ public class GitSubmoduleParser { public GitSubmoduleParser() {} - public HashMap> parseForSubmodules( + public List parseForSubmodules( final GitChangelogApi gitChangelogApi, final boolean useIntegrationIfConfigured, final GitRepo gitRepo, final List commits) { - HashMap> submoduleSections = new HashMap<>(); + List submodules = new ArrayList<>(); + Map submoduleEntries = new TreeMap<>(); Pattern submoduleNamePattern = Pattern.compile( - "(?m)^\\+{3} b/([\\w/\\s-]+)$\\n@.+\\n-Subproject commit (\\w+)$\\n\\+Subproject commit (\\w+)$"); + "(?m)^\\+{3} b/([\\w/\\s-]+)($\\n@.+)?\\n-Subproject commit (\\w+)$\\n\\+Subproject commit (\\w+)$"); Settings settings = gitChangelogApi.getSettings(); @@ -44,32 +43,41 @@ public HashMap> parseForSubmodules( Matcher submoduleMatch = submoduleNamePattern.matcher(diff); while (submoduleMatch.find()) { String submoduleName = submoduleMatch.group(1); - String previousSubmoduleHash = submoduleMatch.group(2); - String currentSubmoduleHash = submoduleMatch.group(3); + String previousSubmoduleHash = submoduleMatch.group(3); + String currentSubmoduleHash = submoduleMatch.group(4); GitRepo submodule = gitRepo.getSubmodule(submoduleName); + if (submodule == null) { continue; } - settings.setFromCommit(previousSubmoduleHash); - settings.setToCommit(currentSubmoduleHash); - settings.setFromRef(null); - settings.setToRef(null); - settings.setFromRepo(submodule.getDirectory()); + SubmoduleEntry submoduleEntry = + new SubmoduleEntry( + submoduleName, previousSubmoduleHash, currentSubmoduleHash, submodule); - String commitHash = commit.getHash(); - if (!submoduleSections.containsKey(commitHash)) { - submoduleSections.put(commitHash, new ArrayList<>()); - } - List submoduleSectionList = submoduleSections.get(commitHash); - try { - submoduleSectionList.add( - GitChangelogApi.gitChangelogApiBuilder() - .withSettings(settings) - .getChangelog(useIntegrationIfConfigured)); - } catch (GitChangelogRepositoryException e) { - e.printStackTrace(); + if (!submoduleEntries.containsKey(submoduleName)) { + submoduleEntries.put(submoduleName, submoduleEntry); } + + SubmoduleEntry existingEntry = submoduleEntries.getOrDefault(submoduleName, submoduleEntry); + existingEntry.previousSubmoduleHash = submoduleEntry.previousSubmoduleHash; + } + } + + for (Map.Entry submoduleEntry : submoduleEntries.entrySet()) { + settings.setFromCommit(submoduleEntry.getValue().previousSubmoduleHash); + settings.setToCommit(submoduleEntry.getValue().currentSubmoduleHash); + settings.setFromRef(null); + settings.setToRef(null); + settings.setFromRepo(submoduleEntry.getValue().gitRepo.getDirectory()); + + try { + submodules.add( + GitChangelogApi.gitChangelogApiBuilder() + .withSettings(settings) + .getChangelog(useIntegrationIfConfigured)); + } catch (GitChangelogRepositoryException e) { + e.printStackTrace(); } } @@ -79,6 +87,24 @@ public HashMap> parseForSubmodules( settings.setToRef(cachedToRef.orNull()); settings.setFromRepo(cachedFromRepo); - return submoduleSections; + return submodules; + } + + private class SubmoduleEntry { + public final String name; + public String previousSubmoduleHash; + public final String currentSubmoduleHash; + public final GitRepo gitRepo; + + public SubmoduleEntry( + final String name, + final String previousSubmoduleHash, + final String currentSubmoduleHash, + final GitRepo gitRepo) { + this.name = name; + this.previousSubmoduleHash = previousSubmoduleHash; + this.currentSubmoduleHash = currentSubmoduleHash; + this.gitRepo = gitRepo; + } } } diff --git a/src/main/java/se/bjurr/gitchangelog/internal/model/Transformer.java b/src/main/java/se/bjurr/gitchangelog/internal/model/Transformer.java index 0d78fe8c..90a759dd 100644 --- a/src/main/java/se/bjurr/gitchangelog/internal/model/Transformer.java +++ b/src/main/java/se/bjurr/gitchangelog/internal/model/Transformer.java @@ -33,8 +33,7 @@ public Transformer(Settings settings) { this.settings = settings; } - public List toAuthors( - List gitCommits, final HashMap> submoduleSections) { + public List toAuthors(List gitCommits) { final Multimap commitsPerAuthor = index( gitCommits, @@ -51,7 +50,7 @@ public String apply(GitCommit input) { new Predicate() { @Override public boolean apply(String input) { - return toCommits(commitsPerAuthor.get(input), submoduleSections).size() > 0; + return toCommits(commitsPerAuthor.get(input)).size() > 0; } }); @@ -62,8 +61,7 @@ public boolean apply(String input) { @Override public Author apply(String input) { List gitCommitsOfSameAuthor = newArrayList(commitsPerAuthor.get(input)); - List commitsOfSameAuthor = - toCommits(gitCommitsOfSameAuthor, submoduleSections); + List commitsOfSameAuthor = toCommits(gitCommitsOfSameAuthor); return new Author( // commitsOfSameAuthor.get(0).getAuthorName(), // commitsOfSameAuthor.get(0).getAuthorEmailAddress(), // @@ -72,8 +70,7 @@ public Author apply(String input) { })); } - public List toCommits( - Collection from, final HashMap> submoduleSections) { + public List toCommits(Collection from) { Iterable filteredCommits = filter(from, ignoreCommits(settings)); return newArrayList( transform( @@ -81,31 +78,25 @@ public List toCommits( new Function() { @Override public Commit apply(GitCommit c) { - return toCommit( - c, - submoduleSections == null - ? null - : submoduleSections.getOrDefault(c.getHash(), null)); + return toCommit(c); } })); } - public List toIssues( - List issues, final HashMap> submoduleSections) { - Iterable issuesWithCommits = filterWithCommits(issues, submoduleSections); + public List toIssues(List issues) { + Iterable issuesWithCommits = filterWithCommits(issues); - return newArrayList(transform(issuesWithCommits, parsedIssueToIssue(submoduleSections))); + return newArrayList(transform(issuesWithCommits, parsedIssueToIssue())); } - public List toIssueTypes( - List issues, final HashMap> submoduleSections) { + public List toIssueTypes(List issues) { Map> issuesPerName = newTreeMap(); - for (ParsedIssue parsedIssue : filterWithCommits(issues, submoduleSections)) { + for (ParsedIssue parsedIssue : filterWithCommits(issues)) { if (!issuesPerName.containsKey(parsedIssue.getName())) { issuesPerName.put(parsedIssue.getName(), new ArrayList()); } - Issue transformedIssues = parsedIssueToIssue(submoduleSections).apply(parsedIssue); + Issue transformedIssues = parsedIssueToIssue().apply(parsedIssue); issuesPerName .get(parsedIssue.getName()) // .add(transformedIssues); @@ -118,10 +109,7 @@ public List toIssueTypes( return issueTypes; } - public List toTags( - List gitTags, - final List allParsedIssues, - final HashMap> submoduleSections) { + public List toTags(List gitTags, final List allParsedIssues) { Iterable tags = transform( @@ -133,10 +121,10 @@ public Tag apply(GitTag input) { final String readableName = toReadableTagName(input.getName()); List parsedIssues = reduceParsedIssuesToOnlyGitCommits(allParsedIssues, gitCommits); - List commits = toCommits(gitCommits, submoduleSections); - List authors = toAuthors(gitCommits, submoduleSections); - List issues = toIssues(parsedIssues, submoduleSections); - List issueTypes = toIssueTypes(parsedIssues, submoduleSections); + List commits = toCommits(gitCommits); + List authors = toAuthors(gitCommits); + List issues = toIssues(parsedIssues); + List issueTypes = toIssueTypes(parsedIssues); return new Tag( readableName, input.findAnnotation().orNull(), @@ -187,15 +175,14 @@ public boolean apply(Tag input) { return newArrayList(tags); } - private Iterable filterWithCommits( - List issues, final HashMap> submoduleSections) { + private Iterable filterWithCommits(List issues) { Iterable issuesWithCommits = filter( issues, new Predicate() { @Override public boolean apply(ParsedIssue input) { - return !toCommits(input.getGitCommits(), submoduleSections).isEmpty(); + return !toCommits(input.getGitCommits()).isEmpty(); } }); return issuesWithCommits; @@ -207,15 +194,14 @@ private String format(Date commitTime) { return df.format(commitTime); } - private Function parsedIssueToIssue( - final HashMap> submoduleSections) { + private Function parsedIssueToIssue() { return new Function() { @Override public Issue apply(ParsedIssue input) { List gitCommits = input.getGitCommits(); return new Issue( // - toCommits(gitCommits, submoduleSections), // - toAuthors(gitCommits, submoduleSections), // + toCommits(gitCommits), // + toAuthors(gitCommits), // input.getName(), // input.getTitle().or(""), // input.getIssue(), // @@ -239,7 +225,7 @@ private String removeIssuesFromString( return string; } - private Commit toCommit(GitCommit gitCommit, List submoduleSections) { + private Commit toCommit(GitCommit gitCommit) { return new Commit( // gitCommit.getAuthorName(), // gitCommit.getAuthorEmailAddress(), // @@ -250,8 +236,7 @@ private Commit toCommit(GitCommit gitCommit, List submoduleSections) new IssuesUtil(this.settings).getIssues(), gitCommit.getMessage()), // gitCommit.getHash(), // - gitCommit.isMerge(), - submoduleSections); + gitCommit.isMerge()); } private String toReadableTagName(String input) { From e8b3dc905bfe102a1a4a147bce66986b9fd4ebcc Mon Sep 17 00:00:00 2001 From: Dmitry Mamchur Date: Tue, 7 Apr 2020 13:12:10 +0100 Subject: [PATCH 15/20] undo unnecessary changes --- src/main/java/se/bjurr/gitchangelog/api/model/Author.java | 2 +- src/main/java/se/bjurr/gitchangelog/api/model/Commit.java | 2 +- src/main/java/se/bjurr/gitchangelog/api/model/Issue.java | 2 +- .../java/se/bjurr/gitchangelog/api/model/IssueType.java | 2 +- src/main/java/se/bjurr/gitchangelog/api/model/Tag.java | 2 +- .../se/bjurr/gitchangelog/internal/model/Transformer.java | 3 +-- .../bjurr/gitchangelog/internal/model/CommitFilterTest.java | 6 +++--- 7 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/main/java/se/bjurr/gitchangelog/api/model/Author.java b/src/main/java/se/bjurr/gitchangelog/api/model/Author.java index 458f239a..dc70ca8a 100644 --- a/src/main/java/se/bjurr/gitchangelog/api/model/Author.java +++ b/src/main/java/se/bjurr/gitchangelog/api/model/Author.java @@ -5,7 +5,7 @@ import se.bjurr.gitchangelog.api.model.interfaces.ICommits; public class Author implements ICommits, Serializable { - private static final long serialVersionUID = -672028657732998143L; + private static final long serialVersionUID = -672028657732998142L; private final List commits; private final String authorName; private final String authorEmail; diff --git a/src/main/java/se/bjurr/gitchangelog/api/model/Commit.java b/src/main/java/se/bjurr/gitchangelog/api/model/Commit.java index c5b46eca..d81e93d9 100644 --- a/src/main/java/se/bjurr/gitchangelog/api/model/Commit.java +++ b/src/main/java/se/bjurr/gitchangelog/api/model/Commit.java @@ -10,7 +10,7 @@ import java.util.List; public class Commit implements Serializable { - private static final long serialVersionUID = 6622555148468372817L; + private static final long serialVersionUID = 6622555148468372816L; private static List notFirst(List stringList) { return stringList.subList(1, stringList.size()); diff --git a/src/main/java/se/bjurr/gitchangelog/api/model/Issue.java b/src/main/java/se/bjurr/gitchangelog/api/model/Issue.java index 27f3576d..05ae4f92 100644 --- a/src/main/java/se/bjurr/gitchangelog/api/model/Issue.java +++ b/src/main/java/se/bjurr/gitchangelog/api/model/Issue.java @@ -18,7 +18,7 @@ public class Issue implements ICommits, IAuthors, Serializable { - private static final long serialVersionUID = -7571341639024417200L; + private static final long serialVersionUID = -7571341639024417199L; private final List commits; private final List authors; /** Like JIRA, or GitHub. */ diff --git a/src/main/java/se/bjurr/gitchangelog/api/model/IssueType.java b/src/main/java/se/bjurr/gitchangelog/api/model/IssueType.java index 113175bf..9abf0c72 100644 --- a/src/main/java/se/bjurr/gitchangelog/api/model/IssueType.java +++ b/src/main/java/se/bjurr/gitchangelog/api/model/IssueType.java @@ -14,7 +14,7 @@ public class IssueType implements Serializable { - private static final long serialVersionUID = 8850522973130773607L; + private static final long serialVersionUID = 8850522973130773606L; private final String name; private final List issues; private final SettingsIssueType type; diff --git a/src/main/java/se/bjurr/gitchangelog/api/model/Tag.java b/src/main/java/se/bjurr/gitchangelog/api/model/Tag.java index bf475883..dbdd9739 100644 --- a/src/main/java/se/bjurr/gitchangelog/api/model/Tag.java +++ b/src/main/java/se/bjurr/gitchangelog/api/model/Tag.java @@ -9,7 +9,7 @@ import se.bjurr.gitchangelog.api.model.interfaces.IIssues; public class Tag implements ICommits, IAuthors, IIssues, Serializable { - private static final long serialVersionUID = 2140208294219785899L; + private static final long serialVersionUID = 2140208294219785889L; private final String annotation; private final List authors; private final List commits; diff --git a/src/main/java/se/bjurr/gitchangelog/internal/model/Transformer.java b/src/main/java/se/bjurr/gitchangelog/internal/model/Transformer.java index 90a759dd..fae028af 100644 --- a/src/main/java/se/bjurr/gitchangelog/internal/model/Transformer.java +++ b/src/main/java/se/bjurr/gitchangelog/internal/model/Transformer.java @@ -118,7 +118,6 @@ public List toTags(List gitTags, final List allParsedI @Override public Tag apply(GitTag input) { List gitCommits = input.getGitCommits(); - final String readableName = toReadableTagName(input.getName()); List parsedIssues = reduceParsedIssuesToOnlyGitCommits(allParsedIssues, gitCommits); List commits = toCommits(gitCommits); @@ -126,7 +125,7 @@ public Tag apply(GitTag input) { List issues = toIssues(parsedIssues); List issueTypes = toIssueTypes(parsedIssues); return new Tag( - readableName, + toReadableTagName(input.getName()), input.findAnnotation().orNull(), commits, authors, diff --git a/src/test/java/se/bjurr/gitchangelog/internal/model/CommitFilterTest.java b/src/test/java/se/bjurr/gitchangelog/internal/model/CommitFilterTest.java index 59d11f41..9224e651 100644 --- a/src/test/java/se/bjurr/gitchangelog/internal/model/CommitFilterTest.java +++ b/src/test/java/se/bjurr/gitchangelog/internal/model/CommitFilterTest.java @@ -57,7 +57,7 @@ public void before() throws Exception { @Test public void testThatFilterWithIgnoreCommitsWithMessageWorks() throws Exception { settings.setIgnoreCommitsIfMessageMatches(TEST_COMMIT_MESSAGE_PATTERN); - List transformedCommits = hashes(new Transformer(settings).toCommits(commits, null)); + List transformedCommits = hashes(new Transformer(settings).toCommits(commits)); assertThat(transformedCommits).contains(NONMATCHING_COMMIT_HASH); assertThat(transformedCommits).doesNotContain(MATCHING_COMMIT_1_HASH, MATCHING_COMMIT_2_HASH); } @@ -66,7 +66,7 @@ public void testThatFilterWithIgnoreCommitsWithMessageWorks() throws Exception { public void testThatFilterWithIgnoreCommitsOlderThanWorks() throws Exception { settings.setIgnoreCommitsIfMessageMatches(""); settings.setIgnoreCommitsIfOlderThan(date2017); - List transformedCommits = hashes(new Transformer(settings).toCommits(commits, null)); + List transformedCommits = hashes(new Transformer(settings).toCommits(commits)); assertThat(transformedCommits).doesNotContain(LATEST_2016_COMMIT_HASH); assertThat(transformedCommits) .contains(FIRST_2017_COMMIT_HASH, A_2017_COMMIT_HASH_MATCHING_MESSAGE_PATTERN); @@ -76,7 +76,7 @@ public void testThatFilterWithIgnoreCommitsOlderThanWorks() throws Exception { public void testThatFilterWithIgnoreCommitsWithMessageAndOlderThanWorks() throws Exception { settings.setIgnoreCommitsIfOlderThan(date2017); settings.setIgnoreCommitsIfMessageMatches(TEST_COMMIT_MESSAGE_PATTERN); - List transformedCommits = hashes(new Transformer(settings).toCommits(commits, null)); + List transformedCommits = hashes(new Transformer(settings).toCommits(commits)); assertThat(transformedCommits).contains(FIRST_2017_COMMIT_HASH); assertThat(transformedCommits) .doesNotContain(LATEST_2016_COMMIT_HASH, A_2017_COMMIT_HASH_MATCHING_MESSAGE_PATTERN); From 6dc2df0921b4641a46664205567d955261b79b13 Mon Sep 17 00:00:00 2001 From: Dmitry Mamchur Date: Wed, 9 Sep 2020 16:29:18 +0100 Subject: [PATCH 16/20] add submodule tests --- .../GitChangelogWithSubmodulesApiTest.java | 133 ++++++++++++++++++ src/test/resources/submodule-test-repo.zip | Bin 0 -> 86334 bytes .../templatetest/testSubmodules.mustache | 44 ++++++ .../testThatSubmoduleChangesAreListed.md | 63 +++++++++ ...angesAreNotListedWhenSubmoduleIsRemoved.md | 49 +++++++ 5 files changed, 289 insertions(+) create mode 100644 src/test/java/se/bjurr/gitchangelog/api/GitChangelogWithSubmodulesApiTest.java create mode 100644 src/test/resources/submodule-test-repo.zip create mode 100644 src/test/resources/templatetest/testSubmodules.mustache create mode 100644 src/test/resources/templatetest/testThatSubmoduleChangesAreListed.md create mode 100644 src/test/resources/templatetest/testThatSubmoduleChangesAreNotListedWhenSubmoduleIsRemoved.md diff --git a/src/test/java/se/bjurr/gitchangelog/api/GitChangelogWithSubmodulesApiTest.java b/src/test/java/se/bjurr/gitchangelog/api/GitChangelogWithSubmodulesApiTest.java new file mode 100644 index 00000000..571be19e --- /dev/null +++ b/src/test/java/se/bjurr/gitchangelog/api/GitChangelogWithSubmodulesApiTest.java @@ -0,0 +1,133 @@ +package se.bjurr.gitchangelog.api; + +import static com.google.common.base.Charsets.UTF_8; +import static com.google.common.io.Resources.getResource; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; +import static se.bjurr.gitchangelog.api.GitChangelogApi.gitChangelogApiBuilder; +import static se.bjurr.gitchangelog.api.GitChangelogApiConstants.ZERO_COMMIT; + +import com.google.common.io.Resources; + +import java.io.*; +import java.net.URL; + +import org.apache.commons.io.FileUtils; +import org.eclipse.jgit.api.Git; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; +import com.google.gson.GsonBuilder; + +public class GitChangelogWithSubmodulesApiTest { + private static final String REPOSITORY_PATH = "submodule-test-repo"; + private File gitRepoFile; + + @Before + public void before() { + + File fileZip = new File(Resources.getResource(String.format("%s.zip", REPOSITORY_PATH)).getFile()); + File destDir = fileZip.getParentFile(); + byte[] buffer = new byte[1024]; + try { + ZipInputStream zis = new ZipInputStream(new FileInputStream(fileZip)); + ZipEntry zipEntry = zis.getNextEntry(); + while (zipEntry != null) { + File newFile = new File(destDir, zipEntry.getName()); + if (zipEntry.isDirectory()) { + newFile.mkdirs(); + } else { + newFile.getParentFile().mkdirs(); + FileOutputStream fos = new FileOutputStream(newFile); + int len; + while ((len = zis.read(buffer)) > 0) { + fos.write(buffer, 0, len); + } + fos.close(); + } + zipEntry = zis.getNextEntry(); + } + zis.closeEntry(); + zis.close(); + } catch (FileNotFoundException e) { + fail("Could not find zipped repository"); + } catch (IOException e) { + fail("Could not unzip repository"); + } + this.gitRepoFile = new File(Resources.getResource(REPOSITORY_PATH).getFile()); + } + + @After + public void after() { + try { + FileUtils.deleteDirectory(new File(Resources.getResource(REPOSITORY_PATH).getFile())); + } catch (IOException e) { + fail("Could not cleanup repository folder"); + } + } + + @Test + public void testThatSubmoduleChangesAreListed() throws Exception { + final String expected = + Resources.toString(getResource("templatetest/testThatSubmoduleChangesAreListed.md"), UTF_8).trim(); + + final URL settingsFile = + getResource("settings/git-changelog-test-settings.json").toURI().toURL(); + final String templatePath = "templatetest/testSubmodules.mustache"; + + final String templateContent = Resources.toString(getResource(templatePath), UTF_8); + + final GitChangelogApi changelogApiBuilder = + gitChangelogApiBuilder() + .withSettings(settingsFile) + .withFromRepo(gitRepoFile.getAbsolutePath()) + .withFromCommit(ZERO_COMMIT) + .withToRef("master") + .withTemplatePath(templatePath); + + assertEquals( + "templateContent:\n" + + templateContent + + "\nContext:\n" + + toJson(changelogApiBuilder.getChangelog(true)), + expected, + changelogApiBuilder.render().trim()); + } + + @Test + public void testThatSubmoduleChangesAreNotListedWhenSubmoduleIsRemoved() throws Exception { + final String expected = + Resources.toString(getResource("templatetest/testThatSubmoduleChangesAreNotListedWhenSubmoduleIsRemoved.md"), UTF_8).trim(); + + final URL settingsFile = + getResource("settings/git-changelog-test-settings.json").toURI().toURL(); + final String templatePath = "templatetest/testSubmodules.mustache"; + + final String templateContent = Resources.toString(getResource(templatePath), UTF_8); + + Git git = Git.open(gitRepoFile); + git.checkout().setName("RemovedSubmodule").call(); + + final GitChangelogApi changelogApiBuilder = + gitChangelogApiBuilder() + .withSettings(settingsFile) + .withFromRepo(gitRepoFile.getAbsolutePath()) + .withFromCommit(ZERO_COMMIT) + .withToRef("RemovedSubmodule") + .withTemplatePath(templatePath); + + assertEquals( + "templateContent:\n" + + templateContent + + "\nContext:\n" + + toJson(changelogApiBuilder.getChangelog(true)), + expected, + changelogApiBuilder.render().trim()); + } + + private String toJson(final Object object) { + return new GsonBuilder().setPrettyPrinting().create().toJson(object); + } +} diff --git a/src/test/resources/submodule-test-repo.zip b/src/test/resources/submodule-test-repo.zip new file mode 100644 index 0000000000000000000000000000000000000000..3d298fbe63a55ff053622fec33f87a617813151f GIT binary patch literal 86334 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 literal 0 HcmV?d00001 diff --git a/src/test/resources/templatetest/testSubmodules.mustache b/src/test/resources/templatetest/testSubmodules.mustache new file mode 100644 index 00000000..2b2abef1 --- /dev/null +++ b/src/test/resources/templatetest/testSubmodules.mustache @@ -0,0 +1,44 @@ +# Git Changelog changelog + +Changelog of Git Changelog. +{{#tags}} + {{name}} + {{#issues}} + {{#hasLink}} + ## {{name}} [{{issue}}]({{link}}) {{title}} + {{/hasLink}} + {{^hasLink}} + ## {{name}} {{title}} + {{/hasLink}} + + {{#commits}} + ### {{authorName}} - {{commitTime}} + [{{hash}}](https://server/{{hash}}) + + {{{message}}} + + {{/commits}} + {{/issues}} +{{/tags}} +{{#submodules}} + {{repoName}} + {{#tags}} + {{name}} + {{#issues}} + {{#hasLink}} + ## {{name}} [{{issue}}]({{link}}) {{title}} + {{/hasLink}} + {{^hasLink}} + ## {{name}} {{title}} + {{/hasLink}} + + {{#commits}} + ### {{authorName}} - {{commitTime}} + [{{hash}}](https://server/{{hash}}) + + {{{message}}} + + {{/commits}} + {{/issues}} + {{/tags}} +{{/submodules}} \ No newline at end of file diff --git a/src/test/resources/templatetest/testThatSubmoduleChangesAreListed.md b/src/test/resources/templatetest/testThatSubmoduleChangesAreListed.md new file mode 100644 index 00000000..4204f769 --- /dev/null +++ b/src/test/resources/templatetest/testThatSubmoduleChangesAreListed.md @@ -0,0 +1,63 @@ +# Git Changelog changelog + +Changelog of Git Changelog. + No tag + ## No issue supplied + + ### nemui - 2020-09-09 10:02:16 + [ee3f3ad730f5727](https://server/ee3f3ad730f5727) + + update submodule hashes + + ### nemui - 2020-09-09 10:00:18 + [548afb9a6807ef7](https://server/548afb9a6807ef7) + + add submodule library-b + + ### nemui - 2020-09-09 09:57:19 + [36bc99ea0082346](https://server/36bc99ea0082346) + + changes both in the repository and in the submodule + + ### nemui - 2020-09-09 09:54:03 + [dceeed792cd595a](https://server/dceeed792cd595a) + + update submodule hashes + + ### nemui - 2020-09-09 09:49:39 + [ffabb2c14e905d8](https://server/ffabb2c14e905d8) + + add library-a + + ### nemui - 2020-09-09 09:48:43 + [96df4818b3f4fbd](https://server/96df4818b3f4fbd) + + update README + + library-a + No tag + ## No issue supplied + + ### Dmitry Mamchur - 2020-09-09 10:01:38 + [d348aa363c0e0a1](https://server/d348aa363c0e0a1) + + remove newline characters + + ### Dmitry Mamchur - 2020-09-09 09:56:19 + [ed44531560d0529](https://server/ed44531560d0529) + + add new lines + + ### Dmitry Mamchur - 2020-09-09 09:53:33 + [1320038ff746b37](https://server/1320038ff746b37) + + missing punctuation mark + + library-b + No tag + ## No issue supplied + + ### Dmitry Mamchur - 2020-09-09 10:01:57 + [bceaf8876328d47](https://server/bceaf8876328d47) + + add newline characters \ No newline at end of file diff --git a/src/test/resources/templatetest/testThatSubmoduleChangesAreNotListedWhenSubmoduleIsRemoved.md b/src/test/resources/templatetest/testThatSubmoduleChangesAreNotListedWhenSubmoduleIsRemoved.md new file mode 100644 index 00000000..e63cca7e --- /dev/null +++ b/src/test/resources/templatetest/testThatSubmoduleChangesAreNotListedWhenSubmoduleIsRemoved.md @@ -0,0 +1,49 @@ +# Git Changelog changelog + +Changelog of Git Changelog. + No tag + ## No issue supplied + + ### nemui - 2020-09-09 10:12:32 + [1f1fc961afa5926](https://server/1f1fc961afa5926) + + remove library-a submodule + + ### nemui - 2020-09-09 10:02:16 + [ee3f3ad730f5727](https://server/ee3f3ad730f5727) + + update submodule hashes + + ### nemui - 2020-09-09 10:00:18 + [548afb9a6807ef7](https://server/548afb9a6807ef7) + + add submodule library-b + + ### nemui - 2020-09-09 09:57:19 + [36bc99ea0082346](https://server/36bc99ea0082346) + + changes both in the repository and in the submodule + + ### nemui - 2020-09-09 09:54:03 + [dceeed792cd595a](https://server/dceeed792cd595a) + + update submodule hashes + + ### nemui - 2020-09-09 09:49:39 + [ffabb2c14e905d8](https://server/ffabb2c14e905d8) + + add library-a + + ### nemui - 2020-09-09 09:48:43 + [96df4818b3f4fbd](https://server/96df4818b3f4fbd) + + update README + + library-b + No tag + ## No issue supplied + + ### Dmitry Mamchur - 2020-09-09 10:01:57 + [bceaf8876328d47](https://server/bceaf8876328d47) + + add newline characters \ No newline at end of file From 1eb99942a95b1a203937dca5c4a74f7690253bbe Mon Sep 17 00:00:00 2001 From: Dmitry Mamchur Date: Wed, 9 Sep 2020 16:54:54 +0100 Subject: [PATCH 17/20] GitChangelogRepositoryException and an empty map for submodules --- .../gitchangelog/internal/git/GitRepo.java | 31 ++++++++----------- .../internal/git/GitSubmoduleParser.java | 4 +-- 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/src/main/java/se/bjurr/gitchangelog/internal/git/GitRepo.java b/src/main/java/se/bjurr/gitchangelog/internal/git/GitRepo.java index 7465f2ba..f8708215 100644 --- a/src/main/java/se/bjurr/gitchangelog/internal/git/GitRepo.java +++ b/src/main/java/se/bjurr/gitchangelog/internal/git/GitRepo.java @@ -46,7 +46,7 @@ public class GitRepo implements Closeable { public GitRepo() { this.repository = null; this.revWalk = null; - this.submodules = null; + this.submodules = new HashMap<>(); } public GitRepo(final File repo) throws GitChangelogRepositoryException { @@ -68,8 +68,8 @@ public GitRepo(final File repo) throws GitChangelogRepositoryException { this.revWalk = new RevWalk(this.repository); this.git = new Git(this.repository); + this.submodules = new HashMap<>(); if (SubmoduleWalk.containsGitModulesFile(repository)) { - this.submodules = new HashMap<>(); final SubmoduleWalk submoduleWalk = SubmoduleWalk.forIndex(repository); while (submoduleWalk.next()) { final Repository submoduleRepository = submoduleWalk.getRepository(); @@ -83,10 +83,7 @@ public GitRepo(final File repo) throws GitChangelogRepositoryException { submoduleRepository.close(); } } - } else { - this.submodules = null; } - } catch (final IOException e) { throw new GitChangelogRepositoryException( "Could not use GIT repo in " + repo.getAbsolutePath(), e); @@ -105,10 +102,9 @@ public void close() throws IOException { LOG.error(e.getMessage(), e); } } - if (submodules != null) { - for (Map.Entry submodule : submodules.entrySet()) { - submodule.getValue().close(); - } + + for (Map.Entry submodule : submodules.entrySet()) { + submodule.getValue().close(); } } @@ -164,22 +160,22 @@ public ObjectId getRef(final String fromRef) throws GitChangelogRepositoryExcept } public boolean hasSubmodules() { - return submodules != null && submodules.size() > 0; + return submodules.size() > 0; } public GitRepo getSubmodule(String submodulePath) { return submodules.getOrDefault(submodulePath, null); } - public String getDiff(String commitHash) { - RevCommit commit = null; - RevCommit prevCommit = null; + public String getDiff(String commitHash) throws GitChangelogRepositoryException { + RevCommit commit; + RevCommit prevCommit; try { commit = this.revWalk.parseCommit(getCommit(commitHash)); prevCommit = commit.getParentCount() > 0 ? commit.getParent(0) : null; } catch (GitChangelogRepositoryException | IOException e) { - e.printStackTrace(); + throw new GitChangelogRepositoryException("", e); } OutputStream outputStream = new ByteArrayOutputStream(); @@ -192,7 +188,7 @@ public String getDiff(String commitHash) { diffFormatter.format(diffFormatter.toFileHeader(entry)); } } catch (IOException e) { - e.printStackTrace(); + throw new GitChangelogRepositoryException("", e); } return outputStream.toString(); @@ -211,7 +207,7 @@ public String toString() { return "Repo: " + this.repository + "\n" + sb.toString(); } - private CanonicalTreeParser getTreeParser(RevCommit commit) { + private CanonicalTreeParser getTreeParser(RevCommit commit) throws GitChangelogRepositoryException{ RevTree revTree = commit.getTree(); if (revTree == null) { return null; @@ -221,9 +217,8 @@ private CanonicalTreeParser getTreeParser(RevCommit commit) { try { return new CanonicalTreeParser(null, reader, treeId); } catch (IOException e) { - e.printStackTrace(); + throw new GitChangelogRepositoryException("", e); } - return null; } private boolean addCommitToCurrentTag( diff --git a/src/main/java/se/bjurr/gitchangelog/internal/git/GitSubmoduleParser.java b/src/main/java/se/bjurr/gitchangelog/internal/git/GitSubmoduleParser.java index 80b4cf7a..55746333 100644 --- a/src/main/java/se/bjurr/gitchangelog/internal/git/GitSubmoduleParser.java +++ b/src/main/java/se/bjurr/gitchangelog/internal/git/GitSubmoduleParser.java @@ -22,7 +22,7 @@ public List parseForSubmodules( final GitChangelogApi gitChangelogApi, final boolean useIntegrationIfConfigured, final GitRepo gitRepo, - final List commits) { + final List commits) throws GitChangelogRepositoryException { List submodules = new ArrayList<>(); Map submoduleEntries = new TreeMap<>(); @@ -77,7 +77,7 @@ public List parseForSubmodules( .withSettings(settings) .getChangelog(useIntegrationIfConfigured)); } catch (GitChangelogRepositoryException e) { - e.printStackTrace(); + throw new GitChangelogRepositoryException("", e); } } From 319851f7f98a6fb3eac5904c53ad1f5ce731e95d Mon Sep 17 00:00:00 2001 From: Dmitry Mamchur Date: Wed, 9 Sep 2020 17:14:04 +0100 Subject: [PATCH 18/20] use clones of the Settings object instead of changing it back and forth --- build.gradle | 1 + .../internal/git/GitSubmoduleParser.java | 30 +++++++------------ 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/build.gradle b/build.gradle index 33b653a5..d104a6f3 100644 --- a/build.gradle +++ b/build.gradle @@ -26,6 +26,7 @@ dependencies { compile 'org.eclipse.jgit:org.eclipse.jgit:3.6.2.201501210735-r' compile 'com.github.spullara.mustache.java:compiler:0.8.18' compile 'org.gitlab:java-gitlab-api:4.1.0' + compile 'org.apache.commons:commons-lang3:3.9' compileOnly 'com.github.spotbugs:spotbugs-annotations:3.1.12' diff --git a/src/main/java/se/bjurr/gitchangelog/internal/git/GitSubmoduleParser.java b/src/main/java/se/bjurr/gitchangelog/internal/git/GitSubmoduleParser.java index 55746333..b4ae8010 100644 --- a/src/main/java/se/bjurr/gitchangelog/internal/git/GitSubmoduleParser.java +++ b/src/main/java/se/bjurr/gitchangelog/internal/git/GitSubmoduleParser.java @@ -3,6 +3,7 @@ import static org.slf4j.LoggerFactory.getLogger; import com.google.common.base.Optional; +import org.apache.commons.lang3.SerializationUtils; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -30,14 +31,6 @@ public List parseForSubmodules( Pattern.compile( "(?m)^\\+{3} b/([\\w/\\s-]+)($\\n@.+)?\\n-Subproject commit (\\w+)$\\n\\+Subproject commit (\\w+)$"); - Settings settings = gitChangelogApi.getSettings(); - - Optional cachedFromCommit = settings.getFromCommit(); - Optional cachedToCommit = settings.getToCommit(); - Optional cachedFromRef = settings.getFromRef(); - Optional cachedToRef = settings.getToRef(); - String cachedFromRepo = settings.getFromRepo(); - for (GitCommit commit : commits) { String diff = gitRepo.getDiff(commit.getHash()); Matcher submoduleMatch = submoduleNamePattern.matcher(diff); @@ -64,29 +57,26 @@ public List parseForSubmodules( } } + Settings settings = gitChangelogApi.getSettings(); for (Map.Entry submoduleEntry : submoduleEntries.entrySet()) { - settings.setFromCommit(submoduleEntry.getValue().previousSubmoduleHash); - settings.setToCommit(submoduleEntry.getValue().currentSubmoduleHash); - settings.setFromRef(null); - settings.setToRef(null); - settings.setFromRepo(submoduleEntry.getValue().gitRepo.getDirectory()); + Settings submoduleSettings = SerializationUtils.clone(settings); + + submoduleSettings.setFromCommit(submoduleEntry.getValue().previousSubmoduleHash); + submoduleSettings.setToCommit(submoduleEntry.getValue().currentSubmoduleHash); + submoduleSettings.setFromRef(null); + submoduleSettings.setToRef(null); + submoduleSettings.setFromRepo(submoduleEntry.getValue().gitRepo.getDirectory()); try { submodules.add( GitChangelogApi.gitChangelogApiBuilder() - .withSettings(settings) + .withSettings(submoduleSettings) .getChangelog(useIntegrationIfConfigured)); } catch (GitChangelogRepositoryException e) { throw new GitChangelogRepositoryException("", e); } } - settings.setFromCommit(cachedFromCommit.orNull()); - settings.setToCommit(cachedToCommit.orNull()); - settings.setFromRef(cachedFromRef.orNull()); - settings.setToRef(cachedToRef.orNull()); - settings.setFromRepo(cachedFromRepo); - return submodules; } From 3ea9223537a60f110fd0a216e2e96022325b4a49 Mon Sep 17 00:00:00 2001 From: Dmitry Mamchur Date: Thu, 10 Sep 2020 09:37:16 +0100 Subject: [PATCH 19/20] remove unused import --- .../se/bjurr/gitchangelog/internal/git/GitSubmoduleParser.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/se/bjurr/gitchangelog/internal/git/GitSubmoduleParser.java b/src/main/java/se/bjurr/gitchangelog/internal/git/GitSubmoduleParser.java index b4ae8010..90aabb4b 100644 --- a/src/main/java/se/bjurr/gitchangelog/internal/git/GitSubmoduleParser.java +++ b/src/main/java/se/bjurr/gitchangelog/internal/git/GitSubmoduleParser.java @@ -1,8 +1,6 @@ package se.bjurr.gitchangelog.internal.git; import static org.slf4j.LoggerFactory.getLogger; - -import com.google.common.base.Optional; import org.apache.commons.lang3.SerializationUtils; import java.util.*; import java.util.regex.Matcher; From 0179e7eb891a49ae6d021912eca47b7cb41dcd19 Mon Sep 17 00:00:00 2001 From: Dmitry Mamchur Date: Thu, 10 Sep 2020 15:45:21 +0100 Subject: [PATCH 20/20] formatting --- .../gitchangelog/internal/git/GitRepo.java | 3 +- .../internal/git/GitSubmoduleParser.java | 6 +- .../GitChangelogWithSubmodulesApiTest.java | 74 ++++++++++--------- 3 files changed, 45 insertions(+), 38 deletions(-) diff --git a/src/main/java/se/bjurr/gitchangelog/internal/git/GitRepo.java b/src/main/java/se/bjurr/gitchangelog/internal/git/GitRepo.java index f8708215..a63554de 100644 --- a/src/main/java/se/bjurr/gitchangelog/internal/git/GitRepo.java +++ b/src/main/java/se/bjurr/gitchangelog/internal/git/GitRepo.java @@ -207,7 +207,8 @@ public String toString() { return "Repo: " + this.repository + "\n" + sb.toString(); } - private CanonicalTreeParser getTreeParser(RevCommit commit) throws GitChangelogRepositoryException{ + private CanonicalTreeParser getTreeParser(RevCommit commit) + throws GitChangelogRepositoryException { RevTree revTree = commit.getTree(); if (revTree == null) { return null; diff --git a/src/main/java/se/bjurr/gitchangelog/internal/git/GitSubmoduleParser.java b/src/main/java/se/bjurr/gitchangelog/internal/git/GitSubmoduleParser.java index 90aabb4b..b9001850 100644 --- a/src/main/java/se/bjurr/gitchangelog/internal/git/GitSubmoduleParser.java +++ b/src/main/java/se/bjurr/gitchangelog/internal/git/GitSubmoduleParser.java @@ -1,10 +1,11 @@ package se.bjurr.gitchangelog.internal.git; import static org.slf4j.LoggerFactory.getLogger; -import org.apache.commons.lang3.SerializationUtils; + import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.apache.commons.lang3.SerializationUtils; import org.slf4j.Logger; import se.bjurr.gitchangelog.api.GitChangelogApi; import se.bjurr.gitchangelog.api.exceptions.GitChangelogRepositoryException; @@ -21,7 +22,8 @@ public List parseForSubmodules( final GitChangelogApi gitChangelogApi, final boolean useIntegrationIfConfigured, final GitRepo gitRepo, - final List commits) throws GitChangelogRepositoryException { + final List commits) + throws GitChangelogRepositoryException { List submodules = new ArrayList<>(); Map submoduleEntries = new TreeMap<>(); diff --git a/src/test/java/se/bjurr/gitchangelog/api/GitChangelogWithSubmodulesApiTest.java b/src/test/java/se/bjurr/gitchangelog/api/GitChangelogWithSubmodulesApiTest.java index 571be19e..a8ef4cde 100644 --- a/src/test/java/se/bjurr/gitchangelog/api/GitChangelogWithSubmodulesApiTest.java +++ b/src/test/java/se/bjurr/gitchangelog/api/GitChangelogWithSubmodulesApiTest.java @@ -8,18 +8,16 @@ import static se.bjurr.gitchangelog.api.GitChangelogApiConstants.ZERO_COMMIT; import com.google.common.io.Resources; - +import com.google.gson.GsonBuilder; import java.io.*; import java.net.URL; - +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; import org.apache.commons.io.FileUtils; import org.eclipse.jgit.api.Git; import org.junit.After; import org.junit.Before; import org.junit.Test; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; -import com.google.gson.GsonBuilder; public class GitChangelogWithSubmodulesApiTest { private static final String REPOSITORY_PATH = "submodule-test-repo"; @@ -28,8 +26,9 @@ public class GitChangelogWithSubmodulesApiTest { @Before public void before() { - File fileZip = new File(Resources.getResource(String.format("%s.zip", REPOSITORY_PATH)).getFile()); - File destDir = fileZip.getParentFile(); + File fileZip = + new File(Resources.getResource(String.format("%s.zip", REPOSITORY_PATH)).getFile()); + File destDir = fileZip.getParentFile(); byte[] buffer = new byte[1024]; try { ZipInputStream zis = new ZipInputStream(new FileInputStream(fileZip)); @@ -71,38 +70,43 @@ public void after() { @Test public void testThatSubmoduleChangesAreListed() throws Exception { final String expected = - Resources.toString(getResource("templatetest/testThatSubmoduleChangesAreListed.md"), UTF_8).trim(); + Resources.toString(getResource("templatetest/testThatSubmoduleChangesAreListed.md"), UTF_8) + .trim(); final URL settingsFile = - getResource("settings/git-changelog-test-settings.json").toURI().toURL(); + getResource("settings/git-changelog-test-settings.json").toURI().toURL(); final String templatePath = "templatetest/testSubmodules.mustache"; final String templateContent = Resources.toString(getResource(templatePath), UTF_8); final GitChangelogApi changelogApiBuilder = - gitChangelogApiBuilder() - .withSettings(settingsFile) - .withFromRepo(gitRepoFile.getAbsolutePath()) - .withFromCommit(ZERO_COMMIT) - .withToRef("master") - .withTemplatePath(templatePath); + gitChangelogApiBuilder() + .withSettings(settingsFile) + .withFromRepo(gitRepoFile.getAbsolutePath()) + .withFromCommit(ZERO_COMMIT) + .withToRef("master") + .withTemplatePath(templatePath); assertEquals( - "templateContent:\n" - + templateContent - + "\nContext:\n" - + toJson(changelogApiBuilder.getChangelog(true)), - expected, - changelogApiBuilder.render().trim()); + "templateContent:\n" + + templateContent + + "\nContext:\n" + + toJson(changelogApiBuilder.getChangelog(true)), + expected, + changelogApiBuilder.render().trim()); } @Test public void testThatSubmoduleChangesAreNotListedWhenSubmoduleIsRemoved() throws Exception { final String expected = - Resources.toString(getResource("templatetest/testThatSubmoduleChangesAreNotListedWhenSubmoduleIsRemoved.md"), UTF_8).trim(); + Resources.toString( + getResource( + "templatetest/testThatSubmoduleChangesAreNotListedWhenSubmoduleIsRemoved.md"), + UTF_8) + .trim(); final URL settingsFile = - getResource("settings/git-changelog-test-settings.json").toURI().toURL(); + getResource("settings/git-changelog-test-settings.json").toURI().toURL(); final String templatePath = "templatetest/testSubmodules.mustache"; final String templateContent = Resources.toString(getResource(templatePath), UTF_8); @@ -111,20 +115,20 @@ public void testThatSubmoduleChangesAreNotListedWhenSubmoduleIsRemoved() throws git.checkout().setName("RemovedSubmodule").call(); final GitChangelogApi changelogApiBuilder = - gitChangelogApiBuilder() - .withSettings(settingsFile) - .withFromRepo(gitRepoFile.getAbsolutePath()) - .withFromCommit(ZERO_COMMIT) - .withToRef("RemovedSubmodule") - .withTemplatePath(templatePath); + gitChangelogApiBuilder() + .withSettings(settingsFile) + .withFromRepo(gitRepoFile.getAbsolutePath()) + .withFromCommit(ZERO_COMMIT) + .withToRef("RemovedSubmodule") + .withTemplatePath(templatePath); assertEquals( - "templateContent:\n" - + templateContent - + "\nContext:\n" - + toJson(changelogApiBuilder.getChangelog(true)), - expected, - changelogApiBuilder.render().trim()); + "templateContent:\n" + + templateContent + + "\nContext:\n" + + toJson(changelogApiBuilder.getChangelog(true)), + expected, + changelogApiBuilder.render().trim()); } private String toJson(final Object object) {