generated from MetaMask/metamask-module-template
-
-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
The validate command will validate the formatting of the changelog. If the `--rc` flag is used, it will also ensure that the current version is included as a release header, and that there are no unreleased changes. The CLI command displays a rudimentary diff if formatting problems are detected. This can be improved later with colours, and with highlighting within each line to show what has changed. It also doesn't yet highlight whitespace changes. The validation logic is also exposed via the API as a function called `validateChangelog`. It doesn't include the fancy diff output, but it does throw an error with all of the required information for someone to construct the same output. Tests have been added to comprehensively test the changelog validation. Closes #11
- Loading branch information
Showing
8 changed files
with
681 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
const diff = require('diff'); | ||
|
||
/** | ||
* Generates a diff between two multi-line strings. The resulting diff shows | ||
* any changes using '-' and '+' to indicate the "old" and "new" version | ||
* respectively, and includes 2 lines of unchanged content around each changed | ||
* section where possible. | ||
* @param {string} before - The string representing the base for the comparison. | ||
* @param {string} after - The string representing the changes being compared. | ||
* @returns {string} The genereated text diff | ||
*/ | ||
function generateDiff(before, after) { | ||
const changes = diff.diffLines(before, after); | ||
const diffLines = []; | ||
const preceedingContext = []; | ||
for (const { added, removed, value } of changes) { | ||
const lines = value.split('\n'); | ||
// remove trailing newline | ||
lines.pop(); | ||
if (added || removed) { | ||
if (preceedingContext.length) { | ||
diffLines.push(...preceedingContext); | ||
preceedingContext.splice(0, preceedingContext.length); | ||
} | ||
diffLines.push(...lines.map((line) => `${added ? '+' : '-'}${line}`)); | ||
} else { | ||
// If a changed line has been included already, add up to 2 lines of context | ||
if (diffLines.length) { | ||
diffLines.push(...lines.slice(0, 2).map((line) => ` ${line}`)); | ||
lines.splice(0, 2); | ||
} | ||
// stash last 2 lines for context in case there is another change | ||
if (lines.length) { | ||
preceedingContext.push(...lines.slice(-2)); | ||
} | ||
} | ||
} | ||
return diffLines.join('\n'); | ||
} | ||
|
||
module.exports = { generateDiff }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,11 @@ | ||
const { updateChangelog } = require('./updateChangelog'); | ||
const { | ||
ChangelogFormattingError, | ||
validateChangelog, | ||
} = require('./validateChangelog'); | ||
|
||
module.exports = { | ||
ChangelogFormattingError, | ||
updateChangelog, | ||
validateChangelog, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
const { parseChangelog } = require('./parseChangelog'); | ||
|
||
/** | ||
* @typedef {import('./constants.js').Version} Version | ||
*/ | ||
|
||
/** | ||
* Represents a formatting error in a changelog. | ||
*/ | ||
class ChangelogFormattingError extends Error { | ||
/** | ||
* @param {Object} options | ||
* @param {string} options.validChangelog - The string contents of the well- | ||
* formatted changelog. | ||
* @param {string} options.invalidChangelog - The string contents of the | ||
* malformed changelog. | ||
*/ | ||
constructor({ validChangelog, invalidChangelog }) { | ||
super('Changelog is not well-formatted'); | ||
this.data = { | ||
validChangelog, | ||
invalidChangelog, | ||
}; | ||
} | ||
} | ||
|
||
/** | ||
* Validates that a changelog is well-formatted. | ||
* @param {Object} options | ||
* @param {string} options.changelogContent - The current changelog | ||
* @param {Version} options.currentVersion - The current version | ||
* @param {string} options.repoUrl - The GitHub repository URL for the current | ||
* project. | ||
* @param {boolean} options.isReleaseCandidate - Denotes whether the current | ||
* project is in the midst of release preparation or not. If this is set, this | ||
* command will also ensure the current version is represented in the | ||
* changelog with a release header, and that there are no unreleased changes | ||
* present. | ||
*/ | ||
function validateChangelog({ | ||
changelogContent, | ||
currentVersion, | ||
repoUrl, | ||
isReleaseCandidate, | ||
}) { | ||
const changelog = parseChangelog({ changelogContent, repoUrl }); | ||
|
||
// Ensure release header exists, if necessary | ||
if ( | ||
isReleaseCandidate && | ||
!changelog | ||
.getReleases() | ||
.find((release) => release.version === currentVersion) | ||
) { | ||
throw new Error( | ||
`Current version missing from changelog: '${currentVersion}'`, | ||
); | ||
} | ||
|
||
const hasUnreleasedChanges = changelog.getUnreleasedChanges().length !== 0; | ||
if (isReleaseCandidate && hasUnreleasedChanges) { | ||
throw new Error('Unreleased changes present in the changelog'); | ||
} | ||
|
||
const validChangelog = changelog.toString(); | ||
if (validChangelog !== changelogContent) { | ||
throw new ChangelogFormattingError({ | ||
validChangelog, | ||
invalidChangelog: changelogContent, | ||
}); | ||
} | ||
} | ||
|
||
module.exports = { validateChangelog, ChangelogFormattingError }; |
Oops, something went wrong.