mirror of https://github.com/FOME-Tech/wiki.git
Validate links to md files (#153)
This commit is contained in:
parent
de961db2e9
commit
858aa44554
|
@ -11,7 +11,7 @@
|
|||
"lint:fix": "biome format --write . && biome check --apply .",
|
||||
"lint:fix:unsafe": "biome check . --apply-unsafe .",
|
||||
"lint:ts": "tsc",
|
||||
"lint:links": "node scripts/linkValidator.js",
|
||||
"lint:links": "node scripts/linkValidator.js 'docs/**/*.md?(x)'",
|
||||
"lint:md": "npx markdownlint-cli docs",
|
||||
"lint:biome": "biome check .",
|
||||
"swizzle": "docusaurus swizzle",
|
||||
|
|
|
@ -1,27 +1,71 @@
|
|||
/*
|
||||
* usage:
|
||||
* note: Windows path separator used below! (to avoid error with parsing of this comment block)
|
||||
* " node .\scripts\linkValidator.js 'docs\**\*.md?(x)' "
|
||||
*
|
||||
* for testing:
|
||||
* "node linkValidator.js .\linkValidator.test.md"
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const glob = require('glob');
|
||||
|
||||
const red = (text) => `\x1b[31m${text}\x1b[0m`;
|
||||
|
||||
/**
|
||||
* Check whether links are not staring with "wiki.fome.tech"
|
||||
* @param {Array<string>} files - List of file names to check
|
||||
*/
|
||||
const validateAbsoluteUrls = (files) => {
|
||||
const wikiUrl = 'wiki.fome.tech';
|
||||
const regexPattern = new RegExp(`\\]\\((https|http):\\/\\/${wikiUrl}`, 'i');
|
||||
/** @type {Array<{ errType: string, fileName: string, lineContent: string, lineNo: number }>} */
|
||||
const errors = [];
|
||||
const wikiUrl = 'wiki.fome.tech';
|
||||
|
||||
/** @type {Array<{ fileName: string, lineContent: string, lineNo: number }>} */
|
||||
const errors = [];
|
||||
const validateDocRules = (files) => {
|
||||
/**
|
||||
* Check whether links are adhering to custom rules
|
||||
* @param {Array<string>} files - List of file names to check
|
||||
*/
|
||||
|
||||
console.log('Validating absolute URLs...');
|
||||
let fileMatchIndicator = '';
|
||||
if (files.length === 0) {
|
||||
console.log('UsageError: no files qualify!');
|
||||
process.exit(1);
|
||||
}
|
||||
if (files.length > 1) {
|
||||
fileMatchIndicator = `${files.length} files`;
|
||||
} else {
|
||||
fileMatchIndicator = files[0];
|
||||
}
|
||||
console.log(`Validating rules for URL links in: ${fileMatchIndicator}`);
|
||||
|
||||
// * Check whether links are not staring with "https://wiki.fome.tech"
|
||||
// Note: dynamic javascript string interpolation is used here (see https://www.crstin.com/js-regex-interpolation/)
|
||||
const regexPatternDynAbsLink = new RegExp(`\\]\\((https|http):\\/\\/${wikiUrl}`, 'i');
|
||||
// hint: test static regex via https://regex101.com
|
||||
// * Check whether links are not using a "numbered prefix" like "(/01-blah)"
|
||||
const regexPatternStatNumPrefix = new RegExp(/\(.*\/\d\d\-.*\)/, 'i');
|
||||
// * Check whether links are not markdown links, meaning ending with .md or .mdx like "(/01-blah.md)"
|
||||
const regexPatternStatMdLink = new RegExp(/\(.*\.(md|mdx)\)/, 'i');
|
||||
|
||||
files.forEach((fileName) => {
|
||||
const lines = fs.readFileSync(fileName, 'utf8').split('\n');
|
||||
|
||||
lines.forEach((line) => {
|
||||
if (regexPattern.test(line)) {
|
||||
if (regexPatternDynAbsLink.test(line)) {
|
||||
errors.push({
|
||||
errType: 'AbsLink',
|
||||
fileName,
|
||||
lineContent: line,
|
||||
lineNo: lines.indexOf(line) + 1,
|
||||
});
|
||||
}
|
||||
if (regexPatternStatMdLink.test(line)) {
|
||||
errors.push({
|
||||
errType: 'MdLink',
|
||||
fileName,
|
||||
lineContent: line,
|
||||
lineNo: lines.indexOf(line) + 1,
|
||||
});
|
||||
}
|
||||
if (regexPatternStatNumPrefix.test(line)) {
|
||||
errors.push({
|
||||
errType: 'NumPrefix',
|
||||
fileName,
|
||||
lineContent: line,
|
||||
lineNo: lines.indexOf(line) + 1,
|
||||
|
@ -29,29 +73,36 @@ const validateAbsoluteUrls = (files) => {
|
|||
}
|
||||
});
|
||||
});
|
||||
|
||||
if (errors.length > 0) {
|
||||
console.log('❌ Failed\n');
|
||||
console.log(red(`Absolute URLs to "${wikiUrl}" found in the following files:\n`));
|
||||
errors.forEach((error) => {
|
||||
console.log(`[${error.fileName}:${error.lineNo}] ${error.lineContent.trim()}`);
|
||||
});
|
||||
|
||||
process.exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Load all md and mdx files from / docs and process them
|
||||
*/
|
||||
const main = () => {
|
||||
const files = glob.sync('docs/**/*.md?(x)');
|
||||
// ToDo: add try + catch?
|
||||
const args = process.argv.slice(2);
|
||||
const files = glob.sync(args[0]);
|
||||
|
||||
// process
|
||||
validateAbsoluteUrls(files);
|
||||
// validateRelativeUrls(files);
|
||||
validateDocRules(files);
|
||||
|
||||
console.log('✅ Ok');
|
||||
if (errors.length === 0) {
|
||||
console.log('✅ Ok');
|
||||
} else {
|
||||
console.log('❌ Failed\n');
|
||||
console.log(red(`Number of Errors found: ${errors.length}`));
|
||||
errors.forEach((error) => {
|
||||
console.log(
|
||||
`[${error.fileName}]` +
|
||||
`[Line:${error.lineNo}]` +
|
||||
`[errType:${error.errType}]` +
|
||||
`"${error.lineContent.trim()}"`,
|
||||
);
|
||||
});
|
||||
|
||||
process.exit(2);
|
||||
}
|
||||
};
|
||||
|
||||
// main
|
||||
main();
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
# Tests for linkValidator.js
|
||||
|
||||
## 1. test case prevented by markdownlint MD034/no-bare-urls
|
||||
|
||||
[T] (https://wikiXfome.tech/01-test.md)
|
||||
|
||||
## 2. test case prevented by markdownlint MD034/no-bare-urls
|
||||
|
||||
blah (https://wiki.fome.tech/01-test.md)
|
||||
|
||||
## 3. test case expected: MdLink + AbsLink + NumPrefix
|
||||
|
||||
[T](https://wiki.fome.tech/01-test.md)
|
||||
|
||||
## 4. test case expected: false positive AbsLink
|
||||
|
||||
[T](https://wikiXfome.tech/test) # note: false positive, but extreme unlikely to hit in real world
|
||||
|
||||
## 5. test case expected: MdLink + NumPrefix
|
||||
|
||||
(/01-test.md)
|
||||
|
||||
## 6. test case expected: MdLink
|
||||
|
||||
(test.md)
|
||||
|
||||
## 7. test case expected: MdLink
|
||||
|
||||
(test.md) blah
|
||||
|
||||
## 8. test case expected: MdLink
|
||||
|
||||
blah (test.md) blah
|
||||
|
||||
## 9. test case expected: MdLink
|
||||
|
||||
(../test.mdx)
|
||||
|
||||
## 10. test case expected: no error
|
||||
|
||||
(T)(test.jpg)
|
||||
|
||||
## 11. test case expected: no error
|
||||
|
||||
(T)(../../test)
|
||||
|
||||
## 12. test case expected: NumPrefix
|
||||
|
||||
(/01-test)
|
Loading…
Reference in New Issue