UNPKG

4.54 kBJavaScriptView Raw
1'use strict'
2
3const addStream = require('add-stream')
4const gitRawCommits = require('git-raw-commits')
5const conventionalCommitsParser = require('conventional-commits-parser')
6const conventionalChangelogWriter = require('conventional-changelog-writer')
7const _ = require('lodash')
8const stream = require('stream')
9const through = require('through2')
10const shell = require('shelljs')
11
12const mergeConfig = require('./lib/merge-config')
13function conventionalChangelog (options, context, gitRawCommitsOpts, parserOpts, writerOpts, gitRawExecOpts) {
14 writerOpts = writerOpts || {}
15
16 const readable = new stream.Readable({
17 objectMode: writerOpts.includeDetails
18 })
19 readable._read = function () { }
20
21 let commitsErrorThrown = false
22
23 let commitsStream = new stream.Readable({
24 objectMode: true
25 })
26 commitsStream._read = function () { }
27
28 function commitsRange (from, to) {
29 return gitRawCommits(_.merge({}, gitRawCommitsOpts, {
30 from: from,
31 to: to
32 }))
33 .on('error', function (err) {
34 if (!commitsErrorThrown) {
35 setImmediate(commitsStream.emit.bind(commitsStream), 'error', err)
36 commitsErrorThrown = true
37 }
38 })
39 }
40
41 mergeConfig(options, context, gitRawCommitsOpts, parserOpts, writerOpts, gitRawExecOpts)
42 .then(function (data) {
43 options = data.options
44 context = data.context
45 gitRawCommitsOpts = data.gitRawCommitsOpts
46 parserOpts = data.parserOpts
47 writerOpts = data.writerOpts
48 gitRawExecOpts = data.gitRawExecOpts
49
50 if (shell.exec('git rev-parse --verify HEAD', { silent: true }).code === 0) {
51 let reverseTags = context.gitSemverTags.slice(0).reverse()
52 reverseTags.push('HEAD')
53
54 if (gitRawCommitsOpts.from) {
55 if (reverseTags.indexOf(gitRawCommitsOpts.from) !== -1) {
56 reverseTags = reverseTags.slice(reverseTags.indexOf(gitRawCommitsOpts.from))
57 } else {
58 reverseTags = [gitRawCommitsOpts.from, 'HEAD']
59 }
60 }
61
62 let streams = reverseTags.map((to, i) => {
63 const from = i > 0
64 ? reverseTags[i - 1]
65 : ''
66 return commitsRange(from, to)
67 })
68
69 if (gitRawCommitsOpts.from) {
70 streams = streams.splice(1)
71 }
72
73 if (gitRawCommitsOpts.reverse) {
74 streams.reverse()
75 }
76
77 streams.reduce((prev, next) => next.pipe(addStream(prev)))
78 .on('data', function (data) {
79 setImmediate(commitsStream.emit.bind(commitsStream), 'data', data)
80 })
81 .on('end', function () {
82 setImmediate(commitsStream.emit.bind(commitsStream), 'end')
83 })
84 } else {
85 commitsStream = gitRawCommits(gitRawCommitsOpts, gitRawExecOpts)
86 }
87
88 commitsStream
89 .on('error', function (err) {
90 err.message = 'Error in git-raw-commits: ' + err.message
91 setImmediate(readable.emit.bind(readable), 'error', err)
92 })
93 .pipe(conventionalCommitsParser(parserOpts))
94 .on('error', function (err) {
95 err.message = 'Error in conventional-commits-parser: ' + err.message
96 setImmediate(readable.emit.bind(readable), 'error', err)
97 })
98 // it would be better if `gitRawCommits` could spit out better formatted data
99 // so we don't need to transform here
100 .pipe(through.obj(function (chunk, enc, cb) {
101 try {
102 options.transform.call(this, chunk, cb)
103 } catch (err) {
104 cb(err)
105 }
106 }))
107 .on('error', function (err) {
108 err.message = 'Error in options.transform: ' + err.message
109 setImmediate(readable.emit.bind(readable), 'error', err)
110 })
111 .pipe(conventionalChangelogWriter(context, writerOpts))
112 .on('error', function (err) {
113 err.message = 'Error in conventional-changelog-writer: ' + err.message
114 setImmediate(readable.emit.bind(readable), 'error', err)
115 })
116 .pipe(through({
117 objectMode: writerOpts.includeDetails
118 }, function (chunk, enc, cb) {
119 try {
120 readable.push(chunk)
121 } catch (err) {
122 setImmediate(function () {
123 throw err
124 })
125 }
126
127 cb()
128 }, function (cb) {
129 readable.push(null)
130
131 cb()
132 }))
133 })
134 .catch(function (err) {
135 setImmediate(readable.emit.bind(readable), 'error', err)
136 })
137
138 return readable
139}
140
141module.exports = conventionalChangelog