Skip to content

Commit 9746cd5

Browse files
committed
Allow setting of a default prefix for headings.
Fixes gh-56
1 parent fa4e574 commit 9746cd5

File tree

5 files changed

+89
-26
lines changed

5 files changed

+89
-26
lines changed

src/main/java/io/spring/githubchangeloggenerator/ApplicationProperties.java

+13-1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,12 @@ public class ApplicationProperties {
4949
*/
5050
private final MilestoneReference milestoneReference;
5151

52+
/**
53+
* The default prefix for headings and titles - typically this contains the header
54+
* markdown e.g., "## ".
55+
*/
56+
private final String defaultTitlePrefix;
57+
5258
/**
5359
* Section definitions in the order that they should appear.
5460
*/
@@ -70,10 +76,12 @@ public class ApplicationProperties {
7076
private final List<ExternalLink> externalLinks;
7177

7278
public ApplicationProperties(Repository repository, @DefaultValue("title") MilestoneReference milestoneReference,
73-
List<Section> sections, Issues issues, Contributors contributors, List<ExternalLink> externalLinks) {
79+
@DefaultValue("## ") String defaultTitlePrefix, List<Section> sections, Issues issues,
80+
Contributors contributors, List<ExternalLink> externalLinks) {
7481
Assert.notNull(repository, "Repository must not be null");
7582
this.repository = repository;
7683
this.milestoneReference = milestoneReference;
84+
this.defaultTitlePrefix = defaultTitlePrefix;
7785
this.sections = (sections != null) ? sections : Collections.emptyList();
7886
this.issues = (issues != null) ? issues : new Issues(null, null, null);
7987
this.contributors = (contributors != null) ? contributors : new Contributors(null, null);
@@ -88,6 +96,10 @@ public MilestoneReference getMilestoneReference() {
8896
return this.milestoneReference;
8997
}
9098

99+
public String getDefaultTitlePrefix() {
100+
return this.defaultTitlePrefix;
101+
}
102+
91103
public List<Section> getSections() {
92104
return this.sections;
93105
}

src/main/java/io/spring/githubchangeloggenerator/ChangelogGenerator.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ public class ChangelogGenerator {
6363

6464
private final MilestoneReference milestoneReference;
6565

66+
private final String defaultTitlePrefix;
67+
6668
private final IssueSort sort;
6769

6870
private final Set<String> excludeLabels;
@@ -81,6 +83,7 @@ public ChangelogGenerator(GitHubService service, ApplicationProperties propertie
8183
this.service = service;
8284
this.repository = properties.getRepository();
8385
this.milestoneReference = properties.getMilestoneReference();
86+
this.defaultTitlePrefix = properties.getDefaultTitlePrefix();
8487
this.sort = properties.getIssues().getSort();
8588
this.excludeLabels = properties.getIssues().getExcludes().getLabels();
8689
this.excludeContributors = properties.getContributors().getExclude().getNames();
@@ -146,7 +149,7 @@ private void addSectionContent(StringBuilder content, Map<ChangelogSection, List
146149
sectionIssues.forEach((section, issues) -> {
147150
sort(section.getSort(), issues);
148151
content.append((content.length() != 0) ? String.format("%n") : "");
149-
content.append("## ").append(section).append(String.format("%n%n"));
152+
content.append(this.defaultTitlePrefix).append(section).append(String.format("%n%n"));
150153
issues.stream().map(this::getFormattedIssue).forEach(content::append);
151154
});
152155
}
@@ -199,7 +202,7 @@ private boolean isIncludedContributor(User user) {
199202
}
200203

201204
private void addContributorsContent(StringBuilder content, Set<User> contributors) {
202-
content.append(String.format("%n## "));
205+
content.append(String.format("%n%s", this.defaultTitlePrefix));
203206
content.append((this.contributorsTitle != null) ? this.contributorsTitle : ":heart: Contributors");
204207
content.append(String.format("%n%nWe'd like to thank all the contributors who worked on this release!%n%n"));
205208
contributors.stream().map(this::formatContributors).forEach(content::append);
@@ -210,7 +213,7 @@ private String formatContributors(User c) {
210213
}
211214

212215
private void addExternalLinksContent(StringBuilder content, List<ExternalLink> externalLinks) {
213-
content.append(String.format("## "));
216+
content.append(this.defaultTitlePrefix);
214217
content.append(String.format("External Links%n%n"));
215218
externalLinks.stream().map(this::formatExternalLinks).forEach(content::append);
216219
}

src/test/java/io/spring/githubchangeloggenerator/ChangelogGeneratorTests.java

+39-10
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ void generateWhenHasExcludedContributors() throws Exception {
140140
issues.add(newPullRequest("Enhancement 1", "1", Type.ENHANCEMENT, "enhancement-1-url", contributor1));
141141
issues.add(newPullRequest("Enhancement 2", "2", Type.ENHANCEMENT, "enhancement-2-url", contributor2));
142142
given(this.service.getIssuesForMilestone(23, REPO)).willReturn(issues);
143-
ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.ID, null, null,
143+
ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.ID, "## ", null, null,
144144
new Contributors(null, new ContributorsExclude(Collections.singleton("contributor1"))), null);
145145
this.generator = new ChangelogGenerator(this.service, properties);
146146
assertChangelog("23").hasContent(from("output-with-excluded-contributors"));
@@ -154,7 +154,7 @@ void generateWhenHasAllContributorsExcluded() throws Exception {
154154
issues.add(newPullRequest("Enhancement 1", "1", Type.ENHANCEMENT, "enhancement-1-url", contributor1));
155155
issues.add(newPullRequest("Enhancement 2", "2", Type.ENHANCEMENT, "enhancement-2-url", contributor2));
156156
given(this.service.getIssuesForMilestone(23, REPO)).willReturn(issues);
157-
ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.ID, null, null,
157+
ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.ID, "## ", null, null,
158158
new Contributors(null, new ContributorsExclude(Collections.singleton("*"))), null);
159159
this.generator = new ChangelogGenerator(this.service, properties);
160160
assertChangelog("23").hasContent(from("output-with-all-contributors-excluded"));
@@ -224,7 +224,7 @@ void generateWhenSectionSortedByTitle() throws Exception {
224224
List<Section> sections = new ArrayList<>();
225225
Set<String> labels = Collections.singleton("type: enhancement");
226226
sections.add(new Section("Enhancements", null, IssueSort.TITLE, labels));
227-
ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.ID, sections,
227+
ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.ID, "## ", sections,
228228
new Issues(null, null, null), null, null);
229229
this.generator = new ChangelogGenerator(this.service, properties);
230230
List<Issue> issues = new ArrayList<>();
@@ -240,7 +240,7 @@ void generateWhenAllIssuesSortedByTitle() throws Exception {
240240
List<Section> sections = new ArrayList<>();
241241
Set<String> labels = Collections.singleton("type: enhancement");
242242
sections.add(new Section("Enhancements", null, null, labels));
243-
ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.ID, sections,
243+
ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.ID, "## ", sections,
244244
new Issues(IssueSort.TITLE, null, null), null, null);
245245
this.generator = new ChangelogGenerator(this.service, properties);
246246
List<Issue> issues = new ArrayList<>();
@@ -257,7 +257,7 @@ void generateWhenHasCustomContributorsTitle() throws Exception {
257257
List<Issue> issues = new ArrayList<>();
258258
issues.add(newPullRequest("Bug 1", "1", Type.BUG, "bug-1-url", contributor1));
259259
given(this.service.getIssuesForMilestone(23, REPO)).willReturn(issues);
260-
ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.ID, null, null,
260+
ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.ID, "## ", null, null,
261261
new Contributors(":heart: Teamwork", null), null);
262262
this.generator = new ChangelogGenerator(this.service, properties);
263263
assertChangelog("23").hasContent(from("output-with-custom-contributors-title"));
@@ -267,8 +267,8 @@ void generateWhenHasCustomContributorsTitle() throws Exception {
267267
void generateWhenOneExternalLink() throws Exception {
268268
List<ExternalLink> externalLinks = new ArrayList<>();
269269
externalLinks.add(new ExternalLink("Release Notes Link 1", "url1"));
270-
ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.ID, null, null, null,
271-
externalLinks);
270+
ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.ID, "## ", null, null,
271+
null, externalLinks);
272272
this.generator = new ChangelogGenerator(this.service, properties);
273273
assertChangelog("23").hasContent(from("output-with-one-external-link"));
274274
}
@@ -279,18 +279,47 @@ void generateWhenMultipleExternalLink() throws Exception {
279279
externalLinks.add(new ExternalLink("Release Notes Link 1", "url1"));
280280
externalLinks.add(new ExternalLink("Release Notes Link 2", "url2"));
281281
externalLinks.add(new ExternalLink("Release Notes Link 3", "url3"));
282-
ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.ID, null, null, null,
283-
externalLinks);
282+
ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.ID, "## ", null, null,
283+
null, externalLinks);
284284
this.generator = new ChangelogGenerator(this.service, properties);
285285
assertChangelog("23").hasContent(from("output-with-multiple-external-link"));
286286
}
287287

288+
@Test
289+
void generateWithCustomDefaultTitlePrefix() throws Exception {
290+
User contributor1 = createUser("contributor1", "contributor1-github-url");
291+
User contributor2 = createUser("contributor2", "contributor2-github-url");
292+
293+
List<Issue> issues = new ArrayList<>();
294+
issues.add(newPullRequest("Enhancement 1", "1", Type.ENHANCEMENT, "enhancement-1-url", contributor1));
295+
issues.add(newPullRequest("Enhancement 2", "2", Type.ENHANCEMENT, "enhancement-2-url", contributor2));
296+
issues.add(newIssue("Enhancement c", "1", "enhancement-1-url", Type.ENHANCEMENT));
297+
issues.add(newIssue("Enhancement z", "2", "enhancement-2-url", Type.ENHANCEMENT));
298+
issues.add(newIssue("enHAncEMent a", "3", "enhancement-3-url", Type.ENHANCEMENT));
299+
given(this.service.getIssuesForMilestone(23, REPO)).willReturn(issues);
300+
301+
List<Section> sections = new ArrayList<>();
302+
Set<String> labels = Collections.singleton("type: enhancement");
303+
sections.add(new Section("Enhancements", null, IssueSort.TITLE, labels));
304+
305+
List<ExternalLink> externalLinks = new ArrayList<>();
306+
externalLinks.add(new ExternalLink("Release Notes Link 1", "url1"));
307+
externalLinks.add(new ExternalLink("Release Notes Link 2", "url2"));
308+
externalLinks.add(new ExternalLink("Release Notes Link 3", "url3"));
309+
310+
ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.ID, "== ", sections,
311+
new Issues(IssueSort.TITLE, null, null), new Contributors(null, null), externalLinks);
312+
this.generator = new ChangelogGenerator(this.service, properties);
313+
314+
assertChangelog("23").hasContent(from("output-with-custom-title-prefix"));
315+
}
316+
288317
private void setupGenerator(MilestoneReference id) {
289318
Set<String> labels = new HashSet<>(Arrays.asList("duplicate", "wontfix"));
290319
PortedIssue forwardPort = new PortedIssue("status: forward-port", "Forward port of issue #(\\d+)");
291320
PortedIssue cherryPick = new PortedIssue("status: back-port", "Back port of issue #(\\d+)");
292321
Set<PortedIssue> portedIssues = new HashSet<>(Arrays.asList(forwardPort, cherryPick));
293-
ApplicationProperties properties = new ApplicationProperties(REPO, id, null,
322+
ApplicationProperties properties = new ApplicationProperties(REPO, id, "## ", null,
294323
new Issues(null, new IssuesExclude(labels), portedIssues), null, null);
295324
this.generator = new ChangelogGenerator(this.service, properties);
296325
}

src/test/java/io/spring/githubchangeloggenerator/ChangelogSectionsTests.java

+12-12
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ void collateWhenNoCustomSectionsUsesDefaultSections() {
4646
Issue bug = createIssue("2", "bug");
4747
Issue documentation = createIssue("3", "documentation");
4848
Issue dependencyUpgrade = createIssue("4", "dependency-upgrade");
49-
ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.TITLE, null, null, null,
50-
null);
49+
ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.TITLE, "## ", null, null,
50+
null, null);
5151
ChangelogSections sections = new ChangelogSections(properties);
5252
Map<ChangelogSection, List<Issue>> collated = sections
5353
.collate(Arrays.asList(enhancement, bug, documentation, dependencyUpgrade));
@@ -67,8 +67,8 @@ void collateWhenHasCustomSectionsUsesDefinedSections() {
6767
ApplicationProperties.Section bugsSection = new ApplicationProperties.Section(":beetle: Bug Fixes", null, null,
6868
Collections.singleton("bug"));
6969
List<ApplicationProperties.Section> customSections = Arrays.asList(breaksPassivitySection, bugsSection);
70-
ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.TITLE, customSections,
71-
null, null, null);
70+
ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.TITLE, "## ",
71+
customSections, null, null, null);
7272
ChangelogSections sections = new ChangelogSections(properties);
7373
Issue bug = createIssue("1", "bug");
7474
Issue nonPassive = createIssue("1", "breaks-passivity");
@@ -80,8 +80,8 @@ void collateWhenHasCustomSectionsUsesDefinedSections() {
8080
@Test
8181
void collateWhenNoIssuesInSectionExcludesSection() {
8282
Issue bug = createIssue("1", "bug");
83-
ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.TITLE, null, null, null,
84-
null);
83+
ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.TITLE, "## ", null, null,
84+
null, null);
8585
ChangelogSections sections = new ChangelogSections(properties);
8686
Map<ChangelogSection, List<Issue>> collated = sections.collate(Collections.singletonList(bug));
8787
Map<String, List<Issue>> bySection = getBySection(collated);
@@ -92,8 +92,8 @@ void collateWhenNoIssuesInSectionExcludesSection() {
9292
void collateWhenIssueDoesNotMatchAnySectionLabelThenExcludesIssue() {
9393
Issue bug = createIssue("1", "bug");
9494
Issue nonPassive = createIssue("2", "non-passive");
95-
ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.TITLE, null, null, null,
96-
null);
95+
ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.TITLE, "## ", null, null,
96+
null, null);
9797
ChangelogSections sections = new ChangelogSections(properties);
9898
Map<ChangelogSection, List<Issue>> collated = sections.collate(Arrays.asList(bug, nonPassive));
9999
Map<String, List<Issue>> bySection = getBySection(collated);
@@ -111,8 +111,8 @@ void collateWithDefaultsDoesNotAddIssueToMultipleSections() {
111111
ApplicationProperties.Section highlights = new ApplicationProperties.Section("Highlights", null, null,
112112
Collections.singleton("highlight"));
113113
List<ApplicationProperties.Section> customSections = Arrays.asList(bugs, highlights);
114-
ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.TITLE, customSections,
115-
null, null, null);
114+
ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.TITLE, "## ",
115+
customSections, null, null, null);
116116
ChangelogSections sections = new ChangelogSections(properties);
117117
Map<ChangelogSection, List<Issue>> collated = sections.collate(Arrays.asList(bug, highlight, bugAndHighlight));
118118
Map<String, List<Issue>> bySection = getBySection(collated);
@@ -131,8 +131,8 @@ void collateWithGroupsAddsIssuePerGroup() {
131131
ApplicationProperties.Section highlights = new ApplicationProperties.Section("Highlights", "highlights", null,
132132
Collections.singleton("highlight"));
133133
List<ApplicationProperties.Section> customSections = Arrays.asList(bugs, highlights);
134-
ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.TITLE, customSections,
135-
null, null, null);
134+
ApplicationProperties properties = new ApplicationProperties(REPO, MilestoneReference.TITLE, "## ",
135+
customSections, null, null, null);
136136
ChangelogSections sections = new ChangelogSections(properties);
137137
Map<ChangelogSection, List<Issue>> collated = sections.collate(Arrays.asList(bug, highlight, bugAndHighlight));
138138
Map<String, List<Issue>> bySection = getBySection(collated);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
== Enhancements
2+
3+
- Enhancement 1 [#1](enhancement-1-url)
4+
- Enhancement 2 [#2](enhancement-2-url)
5+
- enHAncEMent a [#3](enhancement-3-url)
6+
- Enhancement c [#1](enhancement-1-url)
7+
- Enhancement z [#2](enhancement-2-url)
8+
9+
== :heart: Contributors
10+
11+
We'd like to thank all the contributors who worked on this release!
12+
13+
- [@contributor1](contributor1-github-url)
14+
- [@contributor2](contributor2-github-url)
15+
== External Links
16+
17+
- [Release Notes Link 1](url1)
18+
- [Release Notes Link 2](url2)
19+
- [Release Notes Link 3](url3)

0 commit comments

Comments
 (0)