Feat: Ensure markdown formatting (#34547)
<!-- Please follow this checklist and put an x in each of the boxes, like this: [x]. It will ensure that our team takes your pull request seriously. --> - [x] I have read [freeCodeCamp's contribution guidelines](https://github.com/freeCodeCamp/freeCodeCamp/blob/master/CONTRIBUTING.md). - [x] My pull request has a descriptive title (not a vague title like `Update index.md`) - [x] My pull request targets the `master` branch of freeCodeCamp. Closes #34535
This commit is contained in:
committed by
mrugesh mohapatra
parent
6685494344
commit
2d3c2efa2a
77
tools/scripts/ci/ensure-challenge-formatting.js
Normal file
77
tools/scripts/ci/ensure-challenge-formatting.js
Normal file
@ -0,0 +1,77 @@
|
||||
const readdirp = require('readdirp-walk');
|
||||
const { has, isEmpty, isNumber } = require('lodash');
|
||||
const ora = require('ora');
|
||||
|
||||
const { parseMarkdown } = require('../../challenge-md-parser');
|
||||
const { challengeRoot, checkFrontmatter } = require('./md-testing-utils');
|
||||
|
||||
const scrimbaUrlRE = /^https:\/\/scrimba\.com\//;
|
||||
const requiredProps = ['title', 'id', 'challengeType'];
|
||||
|
||||
const spinner = ora('Checking challenge markdown formatting').start();
|
||||
|
||||
readdirp({ root: challengeRoot, directoryFilter: '!_meta' })
|
||||
.on('data', file =>
|
||||
Promise.all([
|
||||
isChallengeParseable(file),
|
||||
checkFrontmatter(file, {
|
||||
validator: challengeFrontmatterValidator(file)
|
||||
})
|
||||
]).catch(err => {
|
||||
console.info(`
|
||||
the following error occured when testing
|
||||
|
||||
${file.fullPath}
|
||||
|
||||
`);
|
||||
console.error(err);
|
||||
// eslint-disable-next-line no-process-exit
|
||||
process.exit(1);
|
||||
})
|
||||
)
|
||||
.on('end', () => spinner.stop());
|
||||
|
||||
const challengeFrontmatterValidator = file => frontmatter => {
|
||||
const { fullPath } = file;
|
||||
|
||||
const hasRequiredProperties = requiredProps
|
||||
.map(
|
||||
prop =>
|
||||
has(frontmatter, prop) &&
|
||||
(!isEmpty(frontmatter[prop]) || isNumber(frontmatter[prop]))
|
||||
)
|
||||
.every(bool => bool);
|
||||
|
||||
if (!hasRequiredProperties) {
|
||||
console.log(`${fullPath} is missing required frontmatter
|
||||
|
||||
${JSON.stringify(frontmatter, null, 2)}
|
||||
|
||||
Required properties are: ${JSON.stringify(requiredProps, null, 2)}
|
||||
|
||||
`);
|
||||
}
|
||||
const { videoUrl } = frontmatter;
|
||||
|
||||
let validVideoUrl = false;
|
||||
if (isEmpty(videoUrl)) {
|
||||
validVideoUrl = true;
|
||||
} else {
|
||||
validVideoUrl = scrimbaUrlRE.test(videoUrl);
|
||||
|
||||
if (!validVideoUrl) {
|
||||
console.log(`
|
||||
${fullPath} contains an invalid videoUrl
|
||||
`);
|
||||
}
|
||||
}
|
||||
return hasRequiredProperties && validVideoUrl;
|
||||
};
|
||||
|
||||
function isChallengeParseable(file) {
|
||||
const { stat, fullPath } = file;
|
||||
if (!stat.isFile() || (/_meta/).test(fullPath)) {
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
return parseMarkdown(fullPath);
|
||||
}
|
Reference in New Issue
Block a user