UNPKG

5.91 kBJavaScriptView Raw
1'use strict'
2
3const dateFormat = require('dateformat')
4const { Transform } = require('stream')
5const { join } = require('path')
6const { readFileSync } = require('fs')
7const { valid: semverValid } = require('semver')
8const util = require('./lib/util')
9
10function conventionalChangelogWriterInit (context, options) {
11 context = {
12 commit: 'commits',
13 issue: 'issues',
14 date: dateFormat(new Date(), 'yyyy-mm-dd', true),
15 ...context
16 }
17
18 if (typeof context.linkReferences !== 'boolean' && (context.repository || context.repoUrl) && context.commit && context.issue) {
19 context.linkReferences = true
20 }
21
22 options = {
23 groupBy: 'type',
24 commitsSort: 'header',
25 noteGroupsSort: 'title',
26 notesSort: 'text',
27 generateOn: function (commit) {
28 return semverValid(commit.version)
29 },
30 finalizeContext: function (context) {
31 return context
32 },
33 debug: function () {},
34 reverse: false,
35 includeDetails: false,
36 ignoreReverted: true,
37 doFlush: true,
38 mainTemplate: readFileSync(join(__dirname, 'templates/template.hbs'), 'utf-8'),
39 headerPartial: readFileSync(join(__dirname, 'templates/header.hbs'), 'utf-8'),
40 commitPartial: readFileSync(join(__dirname, 'templates/commit.hbs'), 'utf-8'),
41 footerPartial: readFileSync(join(__dirname, 'templates/footer.hbs'), 'utf-8'),
42 ...options
43 }
44
45 if (!options.transform || typeof options.transform === 'object') {
46 options.transform = {
47 hash: function (hash) {
48 if (typeof hash === 'string') {
49 return hash.substring(0, 7)
50 }
51 },
52 header: function (header) {
53 return header.substring(0, 100)
54 },
55 committerDate: function (date) {
56 if (!date) {
57 return
58 }
59
60 return dateFormat(date, 'yyyy-mm-dd', true)
61 },
62 ...options.transform
63 }
64 }
65
66 let generateOn = options.generateOn
67 if (typeof generateOn === 'string') {
68 generateOn = function (commit) {
69 return typeof commit[options.generateOn] !== 'undefined'
70 }
71 } else if (typeof generateOn !== 'function') {
72 generateOn = function () {
73 return false
74 }
75 }
76
77 options.commitGroupsSort = util.functionify(options.commitGroupsSort)
78 options.commitsSort = util.functionify(options.commitsSort)
79 options.noteGroupsSort = util.functionify(options.noteGroupsSort)
80 options.notesSort = util.functionify(options.notesSort)
81
82 return { context, options, generateOn }
83}
84
85function conventionalChangelogWriterParseStream (context, options) {
86 let generateOn
87 ({ context, options, generateOn } = conventionalChangelogWriterInit(context, options))
88 let commits = []
89 let neverGenerated = true
90 let savedKeyCommit
91 let firstRelease = true
92
93 return new Transform({
94 objectMode: true,
95 highWaterMark: 16,
96 transform (chunk, _enc, cb) {
97 try {
98 let result
99 const commit = util.processCommit(chunk, options.transform, context)
100 const keyCommit = commit || chunk
101
102 // previous blocks of logs
103 if (options.reverse) {
104 if (commit) {
105 commits.push(commit)
106 }
107
108 if (generateOn(keyCommit, commits, context, options)) {
109 neverGenerated = false
110 result = util.generate(options, commits, context, keyCommit)
111 if (options.includeDetails) {
112 this.push({
113 log: result,
114 keyCommit: keyCommit
115 })
116 } else {
117 this.push(result)
118 }
119
120 commits = []
121 }
122 } else {
123 if (generateOn(keyCommit, commits, context, options)) {
124 neverGenerated = false
125 result = util.generate(options, commits, context, savedKeyCommit)
126
127 if (!firstRelease || options.doFlush) {
128 if (options.includeDetails) {
129 this.push({
130 log: result,
131 keyCommit: savedKeyCommit
132 })
133 } else {
134 this.push(result)
135 }
136 }
137
138 firstRelease = false
139 commits = []
140 savedKeyCommit = keyCommit
141 }
142
143 if (commit) {
144 commits.push(commit)
145 }
146 }
147
148 cb()
149 } catch (err) {
150 cb(err)
151 }
152 },
153 flush (cb) {
154 if (!options.doFlush && (options.reverse || neverGenerated)) {
155 cb(null)
156 return
157 }
158
159 try {
160 const result = util.generate(options, commits, context, savedKeyCommit)
161
162 if (options.includeDetails) {
163 this.push({
164 log: result,
165 keyCommit: savedKeyCommit
166 })
167 } else {
168 this.push(result)
169 }
170
171 cb()
172 } catch (err) {
173 cb(err)
174 }
175 }
176 })
177}
178
179/*
180 * Given an array of commits, returns a string representing a CHANGELOG entry.
181 */
182conventionalChangelogWriterParseStream.parseArray = (rawCommits, context, options) => {
183 let generateOn
184 rawCommits = [...rawCommits];
185 ({ context, options, generateOn } = conventionalChangelogWriterInit(context, options))
186 let commits = []
187 let savedKeyCommit
188 if (options.reverse) {
189 rawCommits.reverse()
190 }
191 const entries = []
192 for (const rawCommit of rawCommits) {
193 const commit = util.processCommit(rawCommit, options.transform, context)
194 const keyCommit = commit || rawCommit
195 if (generateOn(keyCommit, commits, context, options)) {
196 entries.push(util.generate(options, commits, context, savedKeyCommit))
197 savedKeyCommit = keyCommit
198 commits = []
199 }
200 if (commit) {
201 commits.push(commit)
202 }
203 }
204 if (options.reverse) {
205 entries.reverse()
206 return util.generate(options, commits, context, savedKeyCommit) + entries.join('')
207 } else {
208 return entries.join('') + util.generate(options, commits, context, savedKeyCommit)
209 }
210}
211
212module.exports = conventionalChangelogWriterParseStream