UNPKG

12.6 kBMarkdownView Raw
1# [![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Dependency Status][daviddm-image]][daviddm-url] [![Coverage Status][coveralls-image]][coveralls-url]
2
3> Write logs based on conventional commits and templates
4
5
6## Install
7
8```sh
9$ npm install --save conventional-changelog-writer
10```
11
12
13## Usage
14
15```js
16var conventionalChangelogWriter = require('conventional-changelog-writer');
17
18conventionalChangelogWriter(context, options);
19```
20
21It returns a transform stream.
22
23It expects an object mode upstream that looks something like this:
24
25```js
26{ hash: '9b1aff905b638aa274a5fc8f88662df446d374bd',
27 header: 'feat(scope): broadcast $destroy event on scope destruction',
28 type: 'feat',
29 scope: 'scope',
30 subject: 'broadcast $destroy event on scope destruction',
31 body: null,
32 footer: 'Closes #1',
33 notes: [],
34 references: [ { action: 'Closes', owner: null, repository: null, issue: '1', raw: '#1' } ] }
35{ hash: '13f31602f396bc269076ab4d389cfd8ca94b20ba',
36 header: 'feat(ng-list): Allow custom separator',
37 type: 'feat',
38 scope: 'ng-list',
39 subject: 'Allow custom separator',
40 body: 'bla bla bla',
41 footer: 'BREAKING CHANGE: some breaking change',
42 notes: [ { title: 'BREAKING CHANGE', text: 'some breaking change' } ],
43 references: [] }
44```
45
46Each chunk should be a commit. Json object is also **valid**. Parts of the objects will be formatted and combined into a log based on the handlebars context, templates and options.
47
48The downstream might look something like this:
49
50```js
51<a name="0.0.1"></a>
52## 0.0.1 "this is a title" (2015-05-29)
53
54
55### Features
56
57* **ng-list:** Allow custom separator ([13f3160](https://github.com/a/b/commits/13f3160))
58* **scope:** broadcast $destroy event on scope destruction ([9b1aff9](https://github.com/a/b/commits/9b1aff9)), closes [#1](https://github.com/a/b/issues/1)
59
60
61### BREAKING CHANGES
62
63* some breaking change
64```
65
66
67## API
68
69### conventionalChangelogWriter([context, [options]])
70
71Returns a transform stream.
72
73#### context
74
75Variables that will be interpolated to the template. This object contains, but not limits to the following fields.
76
77##### version
78
79Type: `string`
80
81Version number of the up-coming release. If `version` is found in the last commit before generating logs, it will be overwritten.
82
83##### title
84
85Type: `string`
86
87##### isPatch
88
89Type: `boolean` Default: `semver.patch(context.version) !== 0`
90
91By default, this value is true if `version`'s patch is `0`.
92
93##### host
94
95Type: `string`
96
97The hosting website. Eg: `'https://github.com'` or `'https://bitbucket.org'`
98
99##### owner
100
101Type: `string`
102
103The owner of the repository. Eg: `'stevemao'`.
104
105##### repository
106
107Type: `string`
108
109The repository name on `host`. Eg: `'conventional-changelog-writer'`.
110
111##### repoUrl
112
113Type: `string`
114
115The whole repository url. Eg: `'https://github.com/conventional-changelog/conventional-changelog-writer'`.
116The should be used as a fallback when `context.repository` doesn't exist.
117
118##### linkReferences
119
120Type: `boolean` Default: `true` if (`context.repository` or `context.repoUrl`), `context.commit` and `context.issue` are truthy
121
122Should all references be linked?
123
124##### commit
125
126Type: `string` Default: `'commits'`
127
128Commit keyword in the url if `context.linkReferences === true`.
129
130##### issue
131
132Type: `string` Default: `'issues'`
133
134Issue or pull request keyword in the url if `context.linkReferences === true`.
135
136##### date
137
138Type: `string` Default: `dateFormat(new Date(), 'yyyy-mm-dd', true)`
139
140Default to formatted (`'yyyy-mm-dd'`) today's date. [dateformat](https://github.com/felixge/node-dateformat) is used for formatting the date. If `version` is found in the last commit, `committerDate` will overwrite this.
141
142#### options
143
144Type: `object`
145
146##### transform
147
148Type: `object` or `function` Default: get the first 7 digits of hash, and `committerDate` will be formatted as `'yyyy-mm-dd'`.
149
150Replace with new values in each commit.
151
152If this is an object, the keys are paths to a nested object property. the values can be a string (static) and a function (dynamic) with the old value and path passed as arguments. This value is merged with your own transform object.
153
154If this is a function, the commit chunk will be passed as the argument and the returned value would be the new commit object. This is a handy function if you can't provide a transform stream as an upstream of this one. If returns a falsy value this commit is ignored.
155
156a `raw` object that is originally poured form upstream is attached to `commit`.
157
158##### groupBy
159
160Type: `string` Default: `'type'`
161
162How to group the commits. EG: based on the same type. If this value is falsy, commits are not grouped.
163
164##### commitGroupsSort
165
166Type: `function`, `string` or `array`
167
168A compare function used to sort commit groups. If it's a string or array, it sorts on the property(ies) by `localeCompare`. Will not sort if this is a falsy value.
169
170The string can be a dot path to a nested object property.
171
172##### commitsSort
173
174Type: `function`, `string` or `array` Default: `'header'`
175
176A compare function used to sort commits. If it's a string or array, it sorts on the property(ies) by `localeCompare`. Will not sort if this is a falsy value.
177
178The string can be a dot path to a nested object property.
179
180##### noteGroupsSort
181
182Type: `function`, `string` or `array` Default: `'title'`
183
184A compare function used to sort note groups. If it's a string or array, it sorts on the property(ies) by `localeCompare`. Will not sort if this is a falsy value.
185
186The string can be a dot path to a nested object property.
187
188##### notesSort
189
190Type: `function`, `string` or `array` Default: `'text'`
191
192A compare function used to sort note groups. If it's a string or array, it sorts on the property(ies) by `localeCompare`. Will not sort if this is a falsy value.
193
194The string can be a dot path to a nested object property.
195
196##### generateOn
197
198Type: `function`, `string` or `any` Default: if `commit.version` is a valid semver.
199
200When the upstream finishes pouring the commits it will generate a block of logs if `doFlush` is `true`. However, you can generate more than one block based on this criteria (usually a version) even if there are still commits from the upstream.
201
202###### generateOn(commit, commits, context, options)
203
204####### commit
205
206Current commit.
207
208####### commits
209
210Current collected commits.
211
212####### context
213
214The generated context based on original input `context` and `options`.
215
216####### options
217
218Normalized options.
219
220**NOTE**: It checks on the transformed commit chunk instead of the original one (you can check on the original by access the `raw` object on the `commit`). However, if the transformed commit is ignored it falls back to the original commit.
221
222If this value is a `string`, it checks the existence of the field. Set to other type to disable it.
223
224##### finalizeContext
225
226Type: `function` Default: pass through
227
228Last chance to modify your context before generating a changelog.
229
230###### finalizeContext(context, options, commits, keyCommit)
231
232####### context
233
234The generated context based on original input `context` and `options`.
235
236####### options
237
238Normalized options.
239
240####### commits
241
242Filtered commits from your git metadata.
243
244####### keyCommit
245
246The commit that triggers to generate the log.
247
248##### debug
249
250Type: `function` Default: `function() {}`
251
252A function to get debug information.
253
254##### reverse
255
256Type: `boolean` Default: `false`
257
258The normal order means reverse chronological order. `reverse` order means chronological order. Are the commits from upstream in the reverse order? You should only worry about this when generating more than one blocks of logs based on `generateOn`. If you find the last commit is in the wrong block inverse this value.
259
260##### includeDetails
261
262Type: `boolean` Default: `false`
263
264If this value is `true`, instead of emitting strings of changelog, it emits objects containing the details the block.
265
266*NOTE:* The downstream must be in object mode if this is `true`.
267
268##### ignoreReverted
269
270Type: `boolean` Default: `true`
271
272If `true`, reverted commits will be ignored.
273
274##### doFlush
275
276Type: `boolean` Default: `true`
277
278If `true`, the stream will flush out the last bit of commits (could be empty) to changelog.
279
280##### mainTemplate
281
282Type: `string` Default: [template.hbs](templates/template.hbs)
283
284The main handlebars template.
285
286##### headerPartial
287
288Type: `string` Default: [header.hbs](templates/header.hbs)
289
290##### commitPartial
291
292Type: `string` Default: [commit.hbs](templates/commit.hbs)
293
294##### footerPartial
295
296Type: `string` Default: [footer.hbs](templates/footer.hbs)
297
298##### partials
299
300Type: `object`
301
302Partials that used in the main template, if any. The key should be the partial name and the value should be handlebars template strings. If you are using handlebars template files, read files by yourself.
303
304
305## Customization Guide
306
307It is possible to customize this the changelog to suit your needs. Templates are written in [handlebars](http://handlebarsjs.com). You can customize all partials or the whole template. Template variables are from either `upstream` or `context`. The following are a suggested way of defining variables.
308
309### upstream
310
311Variables in upstream are commit specific and should be used per commit. Eg: *commit date* and *commit username*. You can think of them as "local" or "isolate" variables. A "raw" commit message (original commit poured from upstream) is attached to `commit`. `transform` can be used to modify a commit.
312
313### context
314
315context should be module specific and can be used across the whole log. Thus these variables should not be related to any single commit and should be generic information of the module or all commits. Eg: *repository url* and *author names*, etc. You can think of them as "global" or "root" variables.
316
317Basically you can make your own templates and define all your template context. Extra context are based on commits from upstream and `options`. For more details, please checkout [handlebars](http://handlebarsjs.com) and the source code of this module. `finalizeContext` can be used at last to modify context before generating a changelog.
318
319
320## CLI
321
322```sh
323$ npm install --global conventional-changelog-writer
324$ conventional-changelog-writer --help # for more details
325```
326
327It works with [Line Delimited JSON](http://en.wikipedia.org/wiki/Line_Delimited_JSON).
328
329If you have commits.ldjson
330
331```js
332{"hash":"9b1aff905b638aa274a5fc8f88662df446d374bd","header":"feat(ngMessages): provide support for dynamic message resolution","type":"feat","scope":"ngMessages","subject":"provide support for dynamic message resolution","body":"Prior to this fix it was impossible to apply a binding to a the ngMessage directive to represent the name of the error.","footer":"BREAKING CHANGE: The `ngMessagesInclude` attribute is now its own directive and that must be placed as a **child** element within the element with the ngMessages directive.\nCloses #10036\nCloses #9338","notes":[{"title":"BREAKING CHANGE","text":"The `ngMessagesInclude` attribute is now its own directive and that must be placed as a **child** element within the element with the ngMessages directive."}],"references":[{"action":"Closes","owner",null,"repository":null,"issue":"10036","raw":"#10036"},{"action":"Closes","owner":null,"repository":null,"issue":"9338","raw":"#9338"}]}
333```
334
335And you run
336
337```sh
338$ conventional-changelog-writer commits.ldjson -o options.js
339```
340
341The output might look something like this
342
343```md
344<a name="1.0.0"></a>
345# 1.0.0 (2015-04-09)
346
347
348### Features
349
350* **ngMessages:** provide support for dynamic message resolution 9b1aff9, closes #10036 #9338
351
352
353### BREAKING CHANGES
354
355* The `ngMessagesInclude` attribute is now its own directive and that must be placed as a **child** element within the element with the ngMessages directive.
356```
357
358It is printed to stdout.
359
360
361## License
362
363MIT © [Steve Mao](https://github.com/stevemao)
364
365
366[npm-image]: https://badge.fury.io/js/conventional-changelog-writer.svg
367[npm-url]: https://npmjs.org/package/conventional-changelog-writer
368[travis-image]: https://travis-ci.org/conventional-changelog/conventional-changelog-writer.svg?branch=master
369[travis-url]: https://travis-ci.org/conventional-changelog/conventional-changelog-writer
370[daviddm-image]: https://david-dm.org/conventional-changelog/conventional-changelog-writer.svg?theme=shields.io
371[daviddm-url]: https://david-dm.org/conventional-changelog/conventional-changelog-writer
372[coveralls-image]: https://coveralls.io/repos/conventional-changelog/conventional-changelog-writer/badge.svg
373[coveralls-url]: https://coveralls.io/r/conventional-changelog/conventional-changelog-writer