| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 | const fs = require("fs");const util = require("util");const exec = util.promisify(require("child_process").exec);const excalidrawDir = `${__dirname}/../src/packages/excalidraw`;const excalidrawPackage = `${excalidrawDir}/package.json`;const pkg = require(excalidrawPackage);const lastVersion = pkg.version;const existingChangeLog = fs.readFileSync(  `${excalidrawDir}/CHANGELOG.md`,  "utf8",);const supportedTypes = ["feat", "fix", "style", "refactor", "perf", "build"];const headerForType = {  feat: "Features",  fix: "Fixes",  style: "Styles",  refactor: " Refactor",  perf: "Performance",  build: "Build",};const badCommits = [];const getCommitHashForLastVersion = async () => {  try {    const commitMessage = `"release @excalidraw/excalidraw@${lastVersion}"`;    const { stdout } = await exec(      `git log --format=format:"%H" --grep=${commitMessage}`,    );    return stdout;  } catch (error) {    console.error(error);  }};const getLibraryCommitsSinceLastRelease = async () => {  const commitHash = await getCommitHashForLastVersion();  const { stdout } = await exec(    `git log --pretty=format:%s ${commitHash}...master`,  );  const commitsSinceLastRelease = stdout.split("\n");  const commitList = {};  supportedTypes.forEach((type) => {    commitList[type] = [];  });  commitsSinceLastRelease.forEach((commit) => {    const indexOfColon = commit.indexOf(":");    const type = commit.slice(0, indexOfColon);    if (!supportedTypes.includes(type)) {      return;    }    const messageWithoutType = commit.slice(indexOfColon + 1).trim();    const messageWithCapitalizeFirst =      messageWithoutType.charAt(0).toUpperCase() + messageWithoutType.slice(1);    const prMatch = commit.match(/\(#([0-9]*)\)/);    if (prMatch) {      const prNumber = prMatch[1];      // return if the changelog already contains the pr number which would happen for package updates      if (existingChangeLog.includes(prNumber)) {        return;      }      const prMarkdown = `[#${prNumber}](https://github.com/excalidraw/excalidraw/pull/${prNumber})`;      const messageWithPRLink = messageWithCapitalizeFirst.replace(        /\(#[0-9]*\)/,        prMarkdown,      );      commitList[type].push(messageWithPRLink);    } else {      badCommits.push(commit);      commitList[type].push(messageWithCapitalizeFirst);    }  });  console.info("Bad commits:", badCommits);  return commitList;};const updateChangelog = async (nextVersion) => {  const commitList = await getLibraryCommitsSinceLastRelease();  let changelogForLibrary =    "## Excalidraw Library\n\n**_This section lists the updates made to the excalidraw library and will not affect the integration._**\n\n";  supportedTypes.forEach((type) => {    if (commitList[type].length) {      changelogForLibrary += `### ${headerForType[type]}\n\n`;      const commits = commitList[type];      commits.forEach((commit) => {        changelogForLibrary += `- ${commit}\n\n`;      });    }  });  changelogForLibrary += "---\n";  const lastVersionIndex = existingChangeLog.indexOf(`## ${lastVersion}`);  let updatedContent =    existingChangeLog.slice(0, lastVersionIndex) +    changelogForLibrary +    existingChangeLog.slice(lastVersionIndex);  const currentDate = new Date().toISOString().slice(0, 10);  const newVersion = `## ${nextVersion} (${currentDate})`;  updatedContent = updatedContent.replace(`## Unreleased`, newVersion);  fs.writeFileSync(`${excalidrawDir}/CHANGELOG.md`, updatedContent, "utf8");};module.exports = updateChangelog;
 |