-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcli.js
executable file
·141 lines (120 loc) · 4.02 KB
/
cli.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#!/usr/bin/env node
'use strict'
const { createReadStream, createWriteStream } = require('fs')
const { resolve } = require('path')
const { Readable } = require('stream')
const addStream = require('add-stream')
const chalk = require('chalk')
const del = require('del')
const pickBy = require('lodash.pickby')
const meow = require('meow')
const tempy = require('tempy')
const { ensureExists, fail, generate, notify } = require('.')
const help = chalk`
{bold Usage:} {yellow changelog} (...options)
{bold Options:}
-i, --in-file <file> Read the changelog from this file (default: changelog.md)
-f, --first-release Generate the changelog for the first time
-o, --out-file <file> Write the changelog to this file (default: changelog.md)
-s, --same-file Overwrite the input file (default: true)
-k, --pkg <path> Path to a specific package.json (default: nearest package.json)
-a, --append Whether the generated block should be appended
-r, --release-count <#> Number of releases to be generated from the latest
-V, --verbose Whether to output more logs
-c, --context <path> Path to a JSON file that is used to define template variables
-l, --lerna-package <name> Generate a changelog for a specific lerna package (:[email protected])
--commit-path <directory> Generate a changelog scoped to a specific directory
-h, --help Show this help message
-v, --version Output the {yellow changelog} version number
\n
`
const { flags } = meow({
description: false,
help,
flags: {
append: { type: 'boolean', alias: 'a' },
context: { type: 'string', alias: 'c' },
firstRelease: { type: 'boolean', alias: 'f' },
help: { type: 'boolean', alias: 'h' },
inFile: { type: 'string', alias: 'i', default: 'changelog.md' },
pkg: { type: 'string', alias: 'k' },
lernaPackage: { type: 'string', alias: 'l' },
outFile: { type: 'string', alias: 'o' },
releaseCount: { type: 'number', alias: 'r' },
sameFile: { type: 'boolean', alias: 's', default: true },
verbose: { type: 'boolean', alias: 'V' },
version: { type: 'boolean', alias: 'v' }
}
})
const {
append,
context,
inFile,
lernaPackage,
pkg,
sameFile,
verbose
} = flags
const outFile = sameFile ? (flags.outFile || inFile) : flags.outFile
const releaseCount = flags.firstRelease ? 0 : flags.releaseCount
const options = pickBy({
pkg: {
path: pkg
},
append,
releaseCount,
lernaPackage
}, v => v !== undefined)
if (verbose) {
options.warn = console.warn.bind(console)
}
let templateContext
const outputError = error => {
if (verbose) {
console.error(chalk.grey(error.stack))
} else {
console.error(chalk.red(error.toString()))
}
process.exit(1)
}
if (context) {
try {
templateContext = require(resolve(process.cwd(), context))
} catch (e) {
outputError(e)
}
}
const commitPath = flags.commitPath ? { path: flags.commitPath } : {}
const changelogStream = generate(options, templateContext, commitPath)
.on('error', e => {
if (e.message.includes('ambiguous argument \'HEAD\'')) {
fail('Could not fetch commits. Is this a new repository?')
}
outputError(e)
})
ensureExists(inFile)
let readStream = null
if (releaseCount !== 0) {
readStream = createReadStream(inFile).on('error', outputError)
} else {
readStream = new Readable()
readStream.push(null)
}
if (options.append) {
changelogStream
.pipe(createWriteStream(outFile, { flags: 'a' }))
.on('finish', () => notify('appended changes to {}', [outFile]))
} else {
const tmp = tempy.file({ extension: 'md' })
changelogStream
.pipe(addStream(readStream))
.pipe(createWriteStream(tmp))
.on('finish', () => {
createReadStream(tmp)
.pipe(createWriteStream(outFile))
.on('finish', () => {
notify('output changes to {}', [outFile])
del.sync(tmp, { force: true })
})
})
}