You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
84 lines
2.8 KiB
84 lines
2.8 KiB
const Changelog = require('./changelog');
|
|
const { unreleased } = require('./constants');
|
|
|
|
function truncated(line) {
|
|
return line.length > 80 ? `${line.slice(0, 80)}...` : line;
|
|
}
|
|
|
|
/**
|
|
* Constructs a Changelog instance that represents the given changelog, which
|
|
* is parsed for release and change informatino.
|
|
* @param {Object} options
|
|
* @param {string} options.changelogContent - The changelog to parse
|
|
* @param {string} options.repoUrl - The GitHub repository URL for the current
|
|
* project.
|
|
* @returns {Changelog} A changelog instance that reflects the changelog text
|
|
* provided.
|
|
*/
|
|
function parseChangelog({ changelogContent, repoUrl }) {
|
|
const changelogLines = changelogContent.split('\n');
|
|
const changelog = new Changelog({ repoUrl });
|
|
|
|
const unreleasedHeaderIndex = changelogLines.indexOf(`## [${unreleased}]`);
|
|
if (unreleasedHeaderIndex === -1) {
|
|
throw new Error(`Failed to find ${unreleased} header`);
|
|
}
|
|
const unreleasedLinkReferenceDefinition = changelogLines.findIndex((line) => {
|
|
return line.startsWith(`[${unreleased}]: `);
|
|
});
|
|
if (unreleasedLinkReferenceDefinition === -1) {
|
|
throw new Error(`Failed to find ${unreleased} link reference definition`);
|
|
}
|
|
|
|
const contentfulChangelogLines = changelogLines
|
|
.slice(unreleasedHeaderIndex + 1, unreleasedLinkReferenceDefinition)
|
|
.filter((line) => line !== '');
|
|
|
|
let mostRecentRelease;
|
|
let mostRecentCategory;
|
|
for (const line of contentfulChangelogLines) {
|
|
if (line.startsWith('## [')) {
|
|
const results = line.match(
|
|
/^## \[(\d+\.\d+\.\d+)\](?: - (\d\d\d\d-\d\d-\d\d))?(?: \[(\w+)\])?/u,
|
|
);
|
|
if (results === null) {
|
|
throw new Error(`Malformed release header: '${truncated(line)}'`);
|
|
}
|
|
mostRecentRelease = results[1];
|
|
mostRecentCategory = undefined;
|
|
const date = results[2];
|
|
const status = results[3];
|
|
changelog.addRelease({
|
|
addToStart: false,
|
|
date,
|
|
status,
|
|
version: mostRecentRelease,
|
|
});
|
|
} else if (line.startsWith('### ')) {
|
|
const results = line.match(/^### (\w+)$\b/u);
|
|
if (results === null) {
|
|
throw new Error(`Malformed category header: '${truncated(line)}'`);
|
|
}
|
|
mostRecentCategory = results[1];
|
|
} else if (line.startsWith('- ')) {
|
|
if (mostRecentCategory === undefined) {
|
|
throw new Error(`Category missing for change: '${truncated(line)}'`);
|
|
}
|
|
const description = line.slice(2);
|
|
changelog.addChange({
|
|
addToStart: false,
|
|
category: mostRecentCategory,
|
|
description,
|
|
version: mostRecentRelease,
|
|
});
|
|
} else if (mostRecentRelease === null) {
|
|
continue;
|
|
} else {
|
|
throw new Error(`Unrecognized line: '${truncated(line)}'`);
|
|
}
|
|
}
|
|
|
|
return changelog;
|
|
}
|
|
|
|
module.exports = { parseChangelog };
|
|
|