1 | #!/usr/bin/env node
|
2 | 'use strict'
|
3 |
|
4 | var addStream = require('add-stream')
|
5 | var conventionalChangelog = require('conventional-changelog')
|
6 | var fs = require('fs')
|
7 | var meow = require('meow')
|
8 | var tempfile = require('tempfile')
|
9 | var _ = require('lodash')
|
10 | var resolve = require('path').resolve
|
11 |
|
12 | var cli = meow(`
|
13 | Usage
|
14 | conventional-changelog
|
15 |
|
16 | Example
|
17 | conventional-changelog -i CHANGELOG.md --same-file
|
18 |
|
19 | Options
|
20 | -i, --infile Read the CHANGELOG from this file
|
21 |
|
22 | -o, --outfile Write the CHANGELOG to this file
|
23 | If unspecified, it prints to stdout
|
24 |
|
25 | -s, --same-file Outputting to the infile so you don't need to specify the same file as outfile
|
26 |
|
27 | -p, --preset Name of the preset you want to use. Must be one of the following:
|
28 | angular, atom, codemirror, ember, eslint, express, jquery, jscs or jshint
|
29 |
|
30 | -k, --pkg A filepath of where your package.json is located
|
31 | Default is the closest package.json from cwd
|
32 |
|
33 | -a, --append Should the newer release be appended to the older release
|
34 | Default: false
|
35 |
|
36 | -r, --release-count How many releases to be generated from the latest
|
37 | If 0, the whole changelog will be regenerated and the outfile will be overwritten
|
38 | Default: 1
|
39 |
|
40 | -u, --output-unreleased Output unreleased changelog
|
41 |
|
42 | -v, --verbose Verbose output. Use this for debugging
|
43 | Default: false
|
44 |
|
45 | -n, --config A filepath of your config script
|
46 | Example of a config script: https://github.com/conventional-changelog/conventional-changelog-angular/blob/master/index.js
|
47 |
|
48 | -c, --context A filepath of a json that is used to define template variables
|
49 | -l, --lerna-package Generate a changelog for a specific lerna package (:pkg-name@1.0.0)
|
50 | -t, --tag-prefix Tag prefix to consider when reading the tags
|
51 | --commit-path Generate a changelog scoped to a specific directory
|
52 | `, {
|
53 | flags: {
|
54 | infile: {
|
55 | alias: `i`
|
56 | },
|
57 | outfile: {
|
58 | alias: `o`
|
59 | },
|
60 | 'same-file': {
|
61 | alias: `s`
|
62 | },
|
63 | preset: {
|
64 | alias: `p`
|
65 | },
|
66 | pkg: {
|
67 | alias: `k`
|
68 | },
|
69 | append: {
|
70 | alias: `a`
|
71 | },
|
72 | 'release-count': {
|
73 | alias: `r`
|
74 | },
|
75 | 'output-unreleased': {
|
76 | alias: `u`
|
77 | },
|
78 | verbose: {
|
79 | alias: `v`
|
80 | },
|
81 | config: {
|
82 | alias: `n`
|
83 | },
|
84 | context: {
|
85 | alias: `c`
|
86 | },
|
87 | 'lerna-package': {
|
88 | alias: `l`
|
89 | },
|
90 | 'tag-prefix': {
|
91 | alias: `t`
|
92 | }
|
93 | }
|
94 | })
|
95 |
|
96 | var config
|
97 | var flags = cli.flags
|
98 | var infile = flags.infile
|
99 | var outfile = flags.outfile
|
100 | var sameFile = flags.sameFile
|
101 | var append = flags.append
|
102 | var releaseCount = flags.releaseCount
|
103 |
|
104 | if (infile && infile === outfile) {
|
105 | sameFile = true
|
106 | } else if (sameFile) {
|
107 | if (infile) {
|
108 | outfile = infile
|
109 | } else {
|
110 | console.error('infile must be provided if same-file flag presents.')
|
111 | process.exit(1)
|
112 | }
|
113 | }
|
114 |
|
115 | var options = _.omit({
|
116 | preset: flags.preset,
|
117 | pkg: {
|
118 | path: flags.pkg
|
119 | },
|
120 | append: append,
|
121 | releaseCount: releaseCount,
|
122 | outputUnreleased: flags.outputUnreleased,
|
123 | lernaPackage: flags.lernaPackage,
|
124 | tagPrefix: flags.tagPrefix
|
125 | }, _.isUndefined)
|
126 |
|
127 | if (flags.verbose) {
|
128 | options.debug = console.info.bind(console)
|
129 | options.warn = console.warn.bind(console)
|
130 | }
|
131 |
|
132 | var templateContext
|
133 |
|
134 | var outStream
|
135 |
|
136 | try {
|
137 | if (flags.context) {
|
138 | templateContext = require(resolve(process.cwd(), flags.context))
|
139 | }
|
140 |
|
141 | if (flags.config) {
|
142 | config = require(resolve(process.cwd(), flags.config))
|
143 | options.config = config
|
144 | } else {
|
145 | config = {}
|
146 | }
|
147 | } catch (err) {
|
148 | console.error('Failed to get file. ' + err)
|
149 | process.exit(1)
|
150 | }
|
151 |
|
152 | var gitRawCommitsOpts = _.merge({}, config.gitRawCommitsOpts || {})
|
153 | if (flags.commitPath) gitRawCommitsOpts.path = flags.commitPath
|
154 |
|
155 | var changelogStream = conventionalChangelog(options, templateContext, gitRawCommitsOpts, config.parserOpts, config.writerOpts)
|
156 | .on('error', function (err) {
|
157 | if (flags.verbose) {
|
158 | console.error(err.stack)
|
159 | } else {
|
160 | console.error(err.toString())
|
161 | }
|
162 | process.exit(1)
|
163 | })
|
164 |
|
165 | function noInputFile () {
|
166 | if (outfile) {
|
167 | outStream = fs.createWriteStream(outfile)
|
168 | } else {
|
169 | outStream = process.stdout
|
170 | }
|
171 |
|
172 | changelogStream
|
173 | .pipe(outStream)
|
174 | }
|
175 |
|
176 | if (infile && releaseCount !== 0) {
|
177 | var readStream = fs.createReadStream(infile)
|
178 | .on('error', function () {
|
179 | if (flags.verbose) {
|
180 | console.warn('infile does not exist.')
|
181 | }
|
182 |
|
183 | if (sameFile) {
|
184 | noInputFile()
|
185 | }
|
186 | })
|
187 |
|
188 | if (sameFile) {
|
189 | if (options.append) {
|
190 | changelogStream
|
191 | .pipe(fs.createWriteStream(outfile, {
|
192 | flags: 'a'
|
193 | }))
|
194 | } else {
|
195 | var tmp = tempfile()
|
196 |
|
197 | changelogStream
|
198 | .pipe(addStream(readStream))
|
199 | .pipe(fs.createWriteStream(tmp))
|
200 | .on('finish', function () {
|
201 | fs.createReadStream(tmp)
|
202 | .pipe(fs.createWriteStream(outfile))
|
203 | })
|
204 | }
|
205 | } else {
|
206 | if (outfile) {
|
207 | outStream = fs.createWriteStream(outfile)
|
208 | } else {
|
209 | outStream = process.stdout
|
210 | }
|
211 |
|
212 | var stream
|
213 |
|
214 | if (options.append) {
|
215 | stream = readStream
|
216 | .pipe(addStream(changelogStream))
|
217 | } else {
|
218 | stream = changelogStream
|
219 | .pipe(addStream(readStream))
|
220 | }
|
221 |
|
222 | stream
|
223 | .pipe(outStream)
|
224 | }
|
225 | } else {
|
226 | noInputFile()
|
227 | }
|