update-changelog.js 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. "use strict";
  2. const conventionalChangelogCore = require("conventional-changelog-core");
  3. const fs = require("fs-extra");
  4. const getStream = require("get-stream");
  5. const log = require("npmlog");
  6. const { BLANK_LINE, CHANGELOG_HEADER, EOL } = require("./constants");
  7. const { getChangelogConfig } = require("./get-changelog-config");
  8. const { makeBumpOnlyFilter } = require("./make-bump-only-filter");
  9. const { readExistingChangelog } = require("./read-existing-changelog");
  10. module.exports.updateChangelog = updateChangelog;
  11. /**
  12. * @param {import("@lerna/package").Package} pkg
  13. * @param {import("..").ChangelogType} type
  14. * @param {import("..").BaseChangelogOptions & { version?: string }} commandOptions
  15. */
  16. function updateChangelog(pkg, type, { changelogPreset, rootPath, tagPrefix = "v", version }) {
  17. log.silly(type, "for %s at %s", pkg.name, pkg.location);
  18. return getChangelogConfig(changelogPreset, rootPath).then((config) => {
  19. const options = {};
  20. const context = {}; // pass as positional because cc-core's merge-config is wack
  21. // cc-core mutates input :P
  22. if (config.conventionalChangelog) {
  23. // "new" preset API
  24. options.config = Object.assign({}, config.conventionalChangelog);
  25. } else {
  26. // "old" preset API
  27. options.config = Object.assign({}, config);
  28. }
  29. // NOTE: must pass as positional argument due to weird bug in merge-config
  30. const gitRawCommitsOpts = Object.assign({}, options.config.gitRawCommitsOpts);
  31. if (type === "root") {
  32. context.version = version;
  33. // preserve tagPrefix because cc-core can't find the currentTag otherwise
  34. context.currentTag = `${tagPrefix}${version}`;
  35. // root changelogs are only enabled in fixed mode, and need the proper tag prefix
  36. options.tagPrefix = tagPrefix;
  37. } else {
  38. // "fixed" or "independent"
  39. gitRawCommitsOpts.path = pkg.location;
  40. options.pkg = { path: pkg.manifestLocation };
  41. if (type === "independent") {
  42. options.lernaPackage = pkg.name;
  43. } else {
  44. // only fixed mode can have a custom tag prefix
  45. options.tagPrefix = tagPrefix;
  46. // preserve tagPrefix because cc-core can't find the currentTag otherwise
  47. context.currentTag = `${tagPrefix}${pkg.version}`;
  48. }
  49. }
  50. // generate the markdown for the upcoming release.
  51. const changelogStream = conventionalChangelogCore(options, context, gitRawCommitsOpts);
  52. return Promise.all([
  53. getStream(changelogStream).then(makeBumpOnlyFilter(pkg)),
  54. readExistingChangelog(pkg),
  55. ]).then(([newEntry, [changelogFileLoc, changelogContents]]) => {
  56. log.silly(type, "writing new entry: %j", newEntry);
  57. const content = [CHANGELOG_HEADER, newEntry, changelogContents].join(BLANK_LINE);
  58. return fs.writeFile(changelogFileLoc, content.trim() + EOL).then(() => {
  59. log.verbose(type, "wrote", changelogFileLoc);
  60. return {
  61. logPath: changelogFileLoc,
  62. newEntry,
  63. };
  64. });
  65. });
  66. });
  67. }