@@ -9,10 +9,20 @@ const conventionalChangelog = require('conventional-changelog');
9
9
const changelogCompare = require ( 'conventional-changelog-writer/lib/util' ) ;
10
10
const merge2 = require ( 'merge2' ) ;
11
11
12
+ /**
13
+ * Maps a commit note to a string that will be used to match notes of the
14
+ * given type in commit messages.
15
+ */
16
+ const enum CommitNote {
17
+ Deprecation = 'DEPRECATED' ,
18
+ BreakingChange = 'BREAKING CHANGE' ,
19
+ }
20
+
12
21
/** Interface that describes a package in the changelog. */
13
22
interface ChangelogPackage {
14
23
commits : any [ ] ;
15
24
breakingChanges : any [ ] ;
25
+ deprecations : any [ ] ;
16
26
}
17
27
18
28
/** Hardcoded order of packages shown in the changelog. */
@@ -41,6 +51,7 @@ export async function promptAndGenerateChangelog(changelogPath: string) {
41
51
* @param releaseName Name of the release that should show up in the changelog.
42
52
*/
43
53
export async function prependChangelogFromLatestTag ( changelogPath : string , releaseName : string ) {
54
+ const angularPresetWriterOptions = await require ( 'conventional-changelog-angular/writer-opts' ) ;
44
55
const outputStream : Readable = conventionalChangelog (
45
56
/* core options */ { preset : 'angular' } ,
46
57
/* context options */ { title : releaseName } ,
@@ -50,8 +61,9 @@ export async function prependChangelogFromLatestTag(changelogPath: string, relea
50
61
// name from the commit message.
51
62
headerPattern : / ^ ( \w * ) (?: \( (?: ( [ ^ / ] + ) \/ ) ? ( .* ) \) ) ? : ( .* ) $ / ,
52
63
headerCorrespondence : [ 'type' , 'package' , 'scope' , 'subject' ] ,
64
+ noteKeywords : [ CommitNote . BreakingChange , CommitNote . Deprecation ] ,
53
65
} ,
54
- /* writer options */ createChangelogWriterOptions ( changelogPath ) ) ;
66
+ /* writer options */ createChangelogWriterOptions ( changelogPath , angularPresetWriterOptions ) ) ;
55
67
56
68
// Stream for reading the existing changelog. This is necessary because we want to
57
69
// actually prepend the new changelog to the existing one.
@@ -93,7 +105,7 @@ export async function promptChangelogReleaseName(): Promise<string> {
93
105
* build the changelog from last major version to master's HEAD when a new major version is being
94
106
* published from the "master" branch.
95
107
*/
96
- function createChangelogWriterOptions ( changelogPath : string ) {
108
+ function createChangelogWriterOptions ( changelogPath : string , presetWriterOptions : any ) {
97
109
const existingChangelogContent = readFileSync ( changelogPath , 'utf8' ) ;
98
110
const commitSortFunction = changelogCompare . functionify ( [ 'type' , 'scope' , 'subject' ] ) ;
99
111
const allPackages = [ ...orderedChangelogPackages , ...excludedChangelogPackages ] ;
@@ -105,6 +117,14 @@ function createChangelogWriterOptions(changelogPath: string) {
105
117
mainTemplate : readFileSync ( join ( __dirname , 'changelog-root-template.hbs' ) , 'utf8' ) ,
106
118
commitPartial : readFileSync ( join ( __dirname , 'changelog-commit-template.hbs' ) , 'utf8' ) ,
107
119
120
+ // Overwrites the conventional-changelog-angular preset transform function. This is necessary
121
+ // because the Angular preset changes every commit note to a breaking change note. Since we
122
+ // have a custom note type for deprecations, we need to keep track of the original type.
123
+ transform : ( commit , context ) => {
124
+ commit . notes . forEach ( n => n . type = n . title ) ;
125
+ return presetWriterOptions . transform ( commit , context ) ;
126
+ } ,
127
+
108
128
// Specify a writer option that can be used to modify the content of a new changelog section.
109
129
// See: conventional-changelog/tree/master/packages/conventional-changelog-writer
110
130
finalizeContext : ( context : any ) => {
@@ -139,11 +159,21 @@ function createChangelogWriterOptions(changelogPath: string) {
139
159
const type = getTypeOfCommitGroupDescription ( group . title ) ;
140
160
141
161
if ( ! packageGroups [ packageName ] ) {
142
- packageGroups [ packageName ] = { commits : [ ] , breakingChanges : [ ] } ;
162
+ packageGroups [ packageName ] = { commits : [ ] , breakingChanges : [ ] , deprecations : [ ] } ;
143
163
}
144
164
const packageGroup = packageGroups [ packageName ] ;
145
165
146
- packageGroup . breakingChanges . push ( ...commit . notes ) ;
166
+ // Collect all notes of the commit. Either breaking change or deprecation notes.
167
+ commit . notes . forEach ( n => {
168
+ if ( n . type === CommitNote . Deprecation ) {
169
+ packageGroup . deprecations . push ( n ) ;
170
+ } else if ( n . type === CommitNote . BreakingChange ) {
171
+ packageGroup . breakingChanges . push ( n ) ;
172
+ } else {
173
+ throw Error ( `Found commit note that is not known: ${ JSON . stringify ( n , null , 2 ) } ` ) ;
174
+ }
175
+ } ) ;
176
+
147
177
packageGroup . commits . push ( { ...commit , type} ) ;
148
178
} ) ;
149
179
} ) ;
@@ -159,6 +189,7 @@ function createChangelogWriterOptions(changelogPath: string) {
159
189
title : pkgName ,
160
190
commits : packageGroup . commits . sort ( commitSortFunction ) ,
161
191
breakingChanges : packageGroup . breakingChanges ,
192
+ deprecations : packageGroup . deprecations ,
162
193
} ;
163
194
} ) ;
164
195
0 commit comments