From 7d525fdeccd85959065e7f982dab136aab8ddfa5 Mon Sep 17 00:00:00 2001 From: Steven Sheehy Date: Fri, 3 Mar 2023 16:50:13 -0600 Subject: [PATCH] Add an issue type filter Signed-off-by: Steven Sheehy --- .../ApplicationProperties.java | 36 +++++++++++++++- .../ChangelogSection.java | 18 ++++++-- .../ChangelogSections.java | 7 ++-- .../ApplicationPropertiesTests.java | 4 ++ .../ChangelogGeneratorTests.java | 42 ++++++++++++++++++- .../ChangelogSectionsTests.java | 16 +++---- .../output-with-issues-only | 10 +++++ .../output-with-pull-requests-only | 10 +++++ .../test-application.yml | 1 + 9 files changed, 128 insertions(+), 16 deletions(-) create mode 100644 src/test/resources/io/spring/githubchangeloggenerator/output-with-issues-only create mode 100644 src/test/resources/io/spring/githubchangeloggenerator/output-with-pull-requests-only diff --git a/src/main/java/io/spring/githubchangeloggenerator/ApplicationProperties.java b/src/main/java/io/spring/githubchangeloggenerator/ApplicationProperties.java index 27d1c93..d8f4cfa 100644 --- a/src/main/java/io/spring/githubchangeloggenerator/ApplicationProperties.java +++ b/src/main/java/io/spring/githubchangeloggenerator/ApplicationProperties.java @@ -35,6 +35,7 @@ * @author Phillip Webb * @author Mahendra Bishnoi * @author Gary Russell + * @author Steven Sheehy */ @ConfigurationProperties(prefix = "changelog") @ConstructorBinding @@ -142,11 +143,18 @@ public static class Section { */ private final Set labels; - public Section(String title, @DefaultValue("default") String group, IssueSort sort, Set labels) { + /** + * Whether issues, pull requests or both should be included in this section. + */ + private final IssueType type; + + public Section(String title, @DefaultValue("default") String group, IssueSort sort, Set labels, + @DefaultValue("ANY") IssueType type) { this.title = title; this.group = (group != null) ? group : "default"; this.sort = sort; this.labels = labels; + this.type = type; } public String getTitle() { @@ -165,6 +173,10 @@ public Set getLabels() { return this.labels; } + public IssueType getType() { + return this.type; + } + } /** @@ -352,4 +364,26 @@ public enum IssueSort { } + /** + * The type of changelog entry. + */ + public enum IssueType { + + /** + * Either issue or pull requests. + */ + ANY, + + /** + * GitHub issue. + */ + ISSUE, + + /** + * GitHub pull request. + */ + PULL_REQUEST + + } + } diff --git a/src/main/java/io/spring/githubchangeloggenerator/ChangelogSection.java b/src/main/java/io/spring/githubchangeloggenerator/ChangelogSection.java index d6449f8..a2bca90 100644 --- a/src/main/java/io/spring/githubchangeloggenerator/ChangelogSection.java +++ b/src/main/java/io/spring/githubchangeloggenerator/ChangelogSection.java @@ -24,6 +24,7 @@ import org.springframework.util.CollectionUtils; import io.spring.githubchangeloggenerator.ApplicationProperties.IssueSort; +import io.spring.githubchangeloggenerator.ApplicationProperties.IssueType; import io.spring.githubchangeloggenerator.github.payload.Issue; import io.spring.githubchangeloggenerator.github.payload.Label; @@ -31,6 +32,7 @@ * A single section of a changelog report. * * @author Phillip Webb + * @author Steven Sheehy */ class ChangelogSection { @@ -42,17 +44,20 @@ class ChangelogSection { private final Set labels; + private final IssueType type; + ChangelogSection(String title, String group, IssueSort sort, String... labels) { - this(title, group, sort, new LinkedHashSet<>(Arrays.asList(labels))); + this(title, group, sort, new LinkedHashSet<>(Arrays.asList(labels)), IssueType.ANY); } - ChangelogSection(String title, String group, IssueSort sort, Set labels) { + ChangelogSection(String title, String group, IssueSort sort, Set labels, IssueType type) { Assert.hasText(title, "Title must not be empty"); Assert.isTrue(!CollectionUtils.isEmpty(labels), "Labels must not be empty"); this.title = title; this.group = group; this.sort = sort; this.labels = labels; + this.type = type; } String getGroup() { @@ -67,7 +72,14 @@ boolean isMatchFor(Issue issue) { for (String candidate : this.labels) { for (Label label : issue.getLabels()) { if (label.getName().contains(candidate)) { - return true; + switch (this.type) { + case ISSUE: + return issue.getPullRequest() == null; + case PULL_REQUEST: + return issue.getPullRequest() != null; + default: + return true; + } } } } diff --git a/src/main/java/io/spring/githubchangeloggenerator/ChangelogSections.java b/src/main/java/io/spring/githubchangeloggenerator/ChangelogSections.java index 50c34d4..abd5333 100644 --- a/src/main/java/io/spring/githubchangeloggenerator/ChangelogSections.java +++ b/src/main/java/io/spring/githubchangeloggenerator/ChangelogSections.java @@ -36,6 +36,7 @@ * * @author Phillip Webb * @author Gary Russell + * @author Steven Sheehy */ class ChangelogSections { @@ -75,7 +76,7 @@ private List adapt(ApplicationProperties properties) { private ChangelogSection adapt(ApplicationProperties.Section propertySection) { return new ChangelogSection(propertySection.getTitle(), propertySection.getGroup(), propertySection.getSort(), - propertySection.getLabels()); + propertySection.getLabels(), propertySection.getType()); } Map> collate(List issues) { @@ -92,9 +93,9 @@ Map> collate(List issues) { private List getSections(Issue issue) { List result = new ArrayList<>(); - Set groupClaimes = new HashSet<>(); + Set groupClaims = new HashSet<>(); for (ChangelogSection section : this.sections) { - if (section.isMatchFor(issue) && groupClaimes.add(section.getGroup())) { + if (section.isMatchFor(issue) && groupClaims.add(section.getGroup())) { result.add(section); } } diff --git a/src/test/java/io/spring/githubchangeloggenerator/ApplicationPropertiesTests.java b/src/test/java/io/spring/githubchangeloggenerator/ApplicationPropertiesTests.java index 881ee0b..1c39fa7 100644 --- a/src/test/java/io/spring/githubchangeloggenerator/ApplicationPropertiesTests.java +++ b/src/test/java/io/spring/githubchangeloggenerator/ApplicationPropertiesTests.java @@ -26,6 +26,7 @@ import org.springframework.core.io.ClassPathResource; import io.spring.githubchangeloggenerator.ApplicationProperties.IssueSort; +import io.spring.githubchangeloggenerator.ApplicationProperties.IssueType; import io.spring.githubchangeloggenerator.ApplicationProperties.Section; import io.spring.githubchangeloggenerator.github.service.Repository; @@ -35,6 +36,7 @@ * Tests for {@link ApplicationProperties}. * * @author Phillip Webb + * @author Steven Sheehy */ class ApplicationPropertiesTests { @@ -54,10 +56,12 @@ void loadYaml() throws Exception { assertThat(sections.get(0).getLabels()).containsExactly("enhancement"); assertThat(sections.get(0).getGroup()).isEqualTo("default"); assertThat(sections.get(0).getSort()).isEqualTo(IssueSort.CREATED); + assertThat(sections.get(0).getType()).isEqualTo(IssueType.ISSUE); assertThat(sections.get(1).getTitle()).isEqualTo("Bugs"); assertThat(sections.get(1).getLabels()).containsExactly("bug"); assertThat(sections.get(1).getGroup()).isEqualTo("test"); assertThat(sections.get(1).getSort()).isNull(); + assertThat(sections.get(1).getType()).isEqualTo(IssueType.ANY); assertThat(properties.getIssues().getExcludes().getLabels()).containsExactly("hide"); assertThat(properties.getIssues().getSort()).isEqualTo(IssueSort.TITLE); assertThat(properties.getContributors().getTitle()).isEqualTo("Nice one!"); diff --git a/src/test/java/io/spring/githubchangeloggenerator/ChangelogGeneratorTests.java b/src/test/java/io/spring/githubchangeloggenerator/ChangelogGeneratorTests.java index 4b1f260..5d2ca62 100644 --- a/src/test/java/io/spring/githubchangeloggenerator/ChangelogGeneratorTests.java +++ b/src/test/java/io/spring/githubchangeloggenerator/ChangelogGeneratorTests.java @@ -39,6 +39,7 @@ import io.spring.githubchangeloggenerator.ApplicationProperties.ContributorsExclude; import io.spring.githubchangeloggenerator.ApplicationProperties.ExternalLink; import io.spring.githubchangeloggenerator.ApplicationProperties.IssueSort; +import io.spring.githubchangeloggenerator.ApplicationProperties.IssueType; import io.spring.githubchangeloggenerator.ApplicationProperties.Issues; import io.spring.githubchangeloggenerator.ApplicationProperties.IssuesExclude; import io.spring.githubchangeloggenerator.ApplicationProperties.PortedIssue; @@ -61,6 +62,7 @@ * @author Phillip Webb * @author Mahendra Bishnoi * @author Gary Russell + * @author Steven Sheehy */ class ChangelogGeneratorTests { @@ -297,7 +299,7 @@ void generateWhenEscapedMarkdownStylingIsInIssueTitleItIsNotEscapedAgain() throw void generateWhenSectionSortedByTitle() throws Exception { List
sections = new ArrayList<>(); Set labels = Collections.singleton("type: enhancement"); - sections.add(new Section("Enhancements", null, IssueSort.TITLE, labels)); + sections.add(new Section("Enhancements", null, IssueSort.TITLE, labels, IssueType.ANY)); ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.ID, sections, new Issues(null, null, null), null, null, false); this.generator = new ChangelogGenerator(this.service, properties); @@ -313,7 +315,7 @@ void generateWhenSectionSortedByTitle() throws Exception { void generateWhenAllIssuesSortedByTitle() throws Exception { List
sections = new ArrayList<>(); Set labels = Collections.singleton("type: enhancement"); - sections.add(new Section("Enhancements", null, null, labels)); + sections.add(new Section("Enhancements", null, null, labels, IssueType.ANY)); ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.ID, sections, new Issues(IssueSort.TITLE, null, null), null, null, false); this.generator = new ChangelogGenerator(this.service, properties); @@ -359,6 +361,42 @@ void generateWhenMultipleExternalLink() throws Exception { assertChangelog("23").hasContent(from("output-with-multiple-external-link")); } + @Test + void generateWhenIssuesOnly() throws Exception { + List
sections = new ArrayList<>(); + Set labels = Collections.singleton("type: enhancement"); + sections.add(new Section("Enhancements", null, IssueSort.TITLE, labels, IssueType.ISSUE)); + ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.ID, sections, + new Issues(null, null, null), null, null, false); + this.generator = new ChangelogGenerator(this.service, properties); + User contributor1 = createUser("contributor1"); + List issues = new ArrayList<>(); + issues.add(newIssue("Issue 1", "1", "issue-1-url", Type.ENHANCEMENT)); + issues.add(newIssue("Issue 2", "2", "issue-2-url", Type.ENHANCEMENT)); + issues.add(newPullRequest("PR 3", "3", Type.ENHANCEMENT, "pr-3-url", contributor1)); + issues.add(newPullRequest("PR 4", "4", Type.ENHANCEMENT, "pr-4-url", contributor1)); + given(this.service.getIssuesForMilestone(23, REPO)).willReturn(issues); + assertChangelog("23").hasContent(from("output-with-issues-only")); + } + + @Test + void generateWhenPullRequestsOnly() throws Exception { + List
sections = new ArrayList<>(); + Set labels = Collections.singleton("type: enhancement"); + sections.add(new Section("Enhancements", null, IssueSort.TITLE, labels, IssueType.PULL_REQUEST)); + ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.ID, sections, + new Issues(null, null, null), null, null, false); + this.generator = new ChangelogGenerator(this.service, properties); + User contributor1 = createUser("contributor1"); + List issues = new ArrayList<>(); + issues.add(newIssue("Issue 1", "1", "issue-1-url", Type.ENHANCEMENT)); + issues.add(newIssue("Issue 2", "2", "issue-2-url", Type.ENHANCEMENT)); + issues.add(newPullRequest("PR 3", "3", Type.ENHANCEMENT, "pr-3-url", contributor1)); + issues.add(newPullRequest("PR 4", "4", Type.ENHANCEMENT, "pr-4-url", contributor1)); + given(this.service.getIssuesForMilestone(23, REPO)).willReturn(issues); + assertChangelog("23").hasContent(from("output-with-pull-requests-only")); + } + private void setupGenerator(MilestoneReference id) { Set labels = new HashSet<>(Arrays.asList("duplicate", "wontfix")); PortedIssue forwardPort = new PortedIssue("status: forward-port", "Forward port of issue #(\\d+)"); diff --git a/src/test/java/io/spring/githubchangeloggenerator/ChangelogSectionsTests.java b/src/test/java/io/spring/githubchangeloggenerator/ChangelogSectionsTests.java index 1e70505..e76a283 100644 --- a/src/test/java/io/spring/githubchangeloggenerator/ChangelogSectionsTests.java +++ b/src/test/java/io/spring/githubchangeloggenerator/ChangelogSectionsTests.java @@ -25,6 +25,7 @@ import org.junit.jupiter.api.Test; +import io.spring.githubchangeloggenerator.ApplicationProperties.IssueType; import io.spring.githubchangeloggenerator.github.payload.Issue; import io.spring.githubchangeloggenerator.github.payload.Label; import io.spring.githubchangeloggenerator.github.service.Repository; @@ -37,6 +38,7 @@ * @author Eleftheria Stein * @author Phillip Webb * @author Gary Russell + * @author Steven Sheehy */ class ChangelogSectionsTests { @@ -65,9 +67,9 @@ void collateWhenNoCustomSectionsUsesDefaultSections() { @Test void collateWhenHasCustomSectionsUsesDefinedSections() { ApplicationProperties.Section breaksPassivitySection = new ApplicationProperties.Section(":rewind: Non-passive", - null, null, Collections.singleton("breaks-passivity")); + null, null, Collections.singleton("breaks-passivity"), IssueType.ANY); ApplicationProperties.Section bugsSection = new ApplicationProperties.Section(":lady_beetle: Bug Fixes", null, - null, Collections.singleton("bug")); + null, Collections.singleton("bug"), IssueType.ANY); List customSections = Arrays.asList(breaksPassivitySection, bugsSection); ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.TITLE, customSections, null, null, null, false); @@ -82,7 +84,7 @@ void collateWhenHasCustomSectionsUsesDefinedSections() { @Test void collateWhenHasCustomSectionsUsesDefinedSectionsAndDefault() { ApplicationProperties.Section breaksPassivitySection = new ApplicationProperties.Section(":rewind: Non-passive", - null, null, Collections.singleton("breaks-passivity")); + null, null, Collections.singleton("breaks-passivity"), IssueType.ANY); List customSections = Arrays.asList(breaksPassivitySection); ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.TITLE, customSections, null, null, null, true); @@ -124,9 +126,9 @@ void collateWithDefaultsDoesNotAddIssueToMultipleSections() { Issue highlight = createIssue("2", "highlight"); Issue bugAndHighlight = createIssue("3", "bug", "highlight"); ApplicationProperties.Section bugs = new ApplicationProperties.Section("Bugs", null, null, - Collections.singleton("bug")); + Collections.singleton("bug"), IssueType.ANY); ApplicationProperties.Section highlights = new ApplicationProperties.Section("Highlights", null, null, - Collections.singleton("highlight")); + Collections.singleton("highlight"), IssueType.ANY); List customSections = Arrays.asList(bugs, highlights); ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.TITLE, customSections, null, null, null, false); @@ -144,9 +146,9 @@ void collateWithGroupsAddsIssuePerGroup() { Issue highlight = createIssue("2", "highlight"); Issue bugAndHighlight = createIssue("3", "bug", "highlight"); ApplicationProperties.Section bugs = new ApplicationProperties.Section("Bugs", null, null, - Collections.singleton("bug")); + Collections.singleton("bug"), IssueType.ANY); ApplicationProperties.Section highlights = new ApplicationProperties.Section("Highlights", "highlights", null, - Collections.singleton("highlight")); + Collections.singleton("highlight"), IssueType.ANY); List customSections = Arrays.asList(bugs, highlights); ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.TITLE, customSections, null, null, null, false); diff --git a/src/test/resources/io/spring/githubchangeloggenerator/output-with-issues-only b/src/test/resources/io/spring/githubchangeloggenerator/output-with-issues-only new file mode 100644 index 0000000..4050d0c --- /dev/null +++ b/src/test/resources/io/spring/githubchangeloggenerator/output-with-issues-only @@ -0,0 +1,10 @@ +## Enhancements + +- Issue 1 [#1](issue-1-url) +- Issue 2 [#2](issue-2-url) + +## :heart: Contributors + +Thank you to all the contributors who worked on this release: + +@contributor1 diff --git a/src/test/resources/io/spring/githubchangeloggenerator/output-with-pull-requests-only b/src/test/resources/io/spring/githubchangeloggenerator/output-with-pull-requests-only new file mode 100644 index 0000000..c368a65 --- /dev/null +++ b/src/test/resources/io/spring/githubchangeloggenerator/output-with-pull-requests-only @@ -0,0 +1,10 @@ +## Enhancements + +- PR 3 [#3](pr-3-url) +- PR 4 [#4](pr-4-url) + +## :heart: Contributors + +Thank you to all the contributors who worked on this release: + +@contributor1 diff --git a/src/test/resources/io/spring/githubchangeloggenerator/test-application.yml b/src/test/resources/io/spring/githubchangeloggenerator/test-application.yml index b099ad7..b58f5cd 100644 --- a/src/test/resources/io/spring/githubchangeloggenerator/test-application.yml +++ b/src/test/resources/io/spring/githubchangeloggenerator/test-application.yml @@ -4,6 +4,7 @@ changelog: - title: ":star: New Features" labels: ["enhancement"] sort: "created" + type: ISSUE - title: "Bugs" labels: ["bug"] group: "test"