index.js 5.6 KB

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