conventional-changelog.js 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. const { EOL } = require('os')
  2. const fs = require('fs')
  3. const { Plugin } = require('release-it')
  4. const conventionalChangelog = require('conventional-changelog')
  5. const concat = require('concat-stream')
  6. const prependFile = require('prepend-file')
  7. class ConventionalChangelog extends Plugin {
  8. getInitialOptions(options, namespace) {
  9. options[namespace].tagName = options.git.tagName
  10. return options[namespace]
  11. }
  12. async bump(version) {
  13. this.setContext({ version })
  14. const { previousTag, currentTag } = await this.getConventionalConfig()
  15. this.setContext({ previousTag, currentTag })
  16. const changelog = await this.generateChangelog()
  17. this.setContext({ changelog })
  18. }
  19. async getConventionalConfig() {
  20. const version = this.getContext('version')
  21. const previousTag = this.config.getContext('latestTag')
  22. const tagTemplate =
  23. this.options.tagName || ((previousTag || '').match(/^v/) ? 'v${version}' : '${version}')
  24. const currentTag = tagTemplate.replace('${version}', version)
  25. return { version, previousTag, currentTag }
  26. }
  27. getChangelogStream(options = {}) {
  28. const { version, previousTag, currentTag } = this.getContext()
  29. return conventionalChangelog(
  30. Object.assign(options, this.options),
  31. { version, previousTag, currentTag },
  32. {
  33. debug: this.config.isDebug ? this.debug : null,
  34. }
  35. )
  36. }
  37. generateChangelog(options) {
  38. return new Promise((resolve, reject) => {
  39. const resolver = result => resolve(result.toString().trim())
  40. const changelogStream = this.getChangelogStream(options)
  41. changelogStream.pipe(concat(resolver))
  42. changelogStream.on('error', reject)
  43. })
  44. }
  45. async writeChangelog() {
  46. const { infile } = this.options
  47. let { changelog } = this.getContext()
  48. let hasInfile = false
  49. try {
  50. fs.accessSync(infile)
  51. hasInfile = true
  52. } catch (err) {
  53. this.debug(err)
  54. }
  55. if (!hasInfile) {
  56. changelog = await this.generateChangelog({ releaseCount: 0 })
  57. this.debug({ changelog })
  58. }
  59. await prependFile(infile, changelog + EOL + EOL)
  60. if (!hasInfile) {
  61. await this.exec(`git add ${infile}`)
  62. }
  63. }
  64. async beforeRelease() {
  65. const { infile } = this.options
  66. const { isDryRun } = this.config
  67. this.log.exec(`Writing changelog to ${infile}`, isDryRun)
  68. if (infile && !isDryRun) {
  69. await this.writeChangelog()
  70. }
  71. }
  72. }
  73. module.exports = ConventionalChangelog