Fix the link checker test

Closes #3541
This commit is contained in:
Natalie Weizenbaum 2023-04-12 16:36:44 -07:00
parent 61914f67dc
commit c074df5a41
4 changed files with 47 additions and 24 deletions

6
package-lock.json generated
View File

@ -4,6 +4,7 @@
"requires": true,
"packages": {
"": {
"name": "sass",
"dependencies": {
"@types/diff": "^5.0.1",
"@types/glob": "^7.1.4",
@ -12,6 +13,7 @@
"diff": "^5.0.0",
"glob": "^7.2.0",
"immutable": "^4.0.0",
"indent-string": "^4.0.0",
"markdown-link-check": "git+https://sassbot@github.com/nex3/markdown-link-check.git#check-references",
"markdown-toc": "^1.2.0",
"prettier": "^2.4.1",
@ -2256,7 +2258,6 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
"integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
"dev": true,
"engines": {
"node": ">=8"
}
@ -6414,8 +6415,7 @@
"indent-string": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
"integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
"dev": true
"integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg=="
},
"inflight": {
"version": "1.0.6",

View File

@ -25,6 +25,7 @@
"diff": "^5.0.0",
"glob": "^7.2.0",
"immutable": "^4.0.0",
"indent-string": "^4.0.0",
"markdown-link-check": "git+https://sassbot@github.com/nex3/markdown-link-check.git#check-references",
"markdown-toc": "^1.2.0",
"prettier": "^2.4.1",

View File

@ -6,6 +6,7 @@ import * as linkCheck from 'markdown-link-check';
import markdownToc = require('markdown-toc');
import * as path from 'path';
import {fileURLToPath, pathToFileURL, URL} from 'url';
import * as indentString from 'indent-string';
if (process.env.CI) colors.enable();
@ -25,40 +26,62 @@ function getToc(file: string): string {
return toc;
}
function pathIsWithin(child: string, parent: string): boolean {
const relative = path.relative(parent, child);
return !relative.startsWith('../');
}
function flagDeadLink(link: string): void {
console.error(`${colors.red(colors.bold('Dead:'))} ${link}`);
process.exitCode = 1;
}
function verifyLinkCheckResults(
file: string,
results: linkCheck.Result[]
): void {
const toc = getToc(file);
for (const result of results) {
const url = new URL(result.link, pathToFileURL(file));
// A link to another file.
if (url.protocol === 'file:' && !result.link.match(/ \(.*\)$/)) {
const target = fileURLToPath(url);
if (!fs.existsSync(target)) throw Error(`Missing file: ${result.link}`);
if (url.hash === '') return;
if (getToc(target).includes(url.hash)) return;
throw Error(`Dead: ${result.link}`);
}
// A link to a section within this file.
if (result.link.match(/^#/)) {
if (toc.includes(result.link)) return;
throw Error(`Dead: ${result.link}`);
if (!fs.existsSync(target)) {
flagDeadLink(result.link);
} else if (url.hash !== '' && !getToc(target).includes(`(${url.hash})`)) {
flagDeadLink(result.link);
} else if (
result.link.includes('../spec/') &&
pathIsWithin(file, 'spec')
) {
console.error(
`${colors.yellow(colors.bold('Unnecessary ../spec:'))} ${result.link}`
);
process.exitCode = 1;
}
continue;
}
// A link to an external website.
switch (result.status) {
case 'dead':
if (result.statusCode === 500) {
console.log(colors.yellow(`Server error on target: ${result.link}`));
return;
console.error(
colors.yellow(`Server error on target: ${result.link}`)
);
} else {
flagDeadLink(result.link);
}
throw Error(`Dead: ${result.link}`);
break;
case 'error':
throw Error(`Error: ${result.link}`);
console.error(
`${colors.red(colors.bold('Error:'))} ${result.link}` +
(result.err
? '\n' + indentString(result.err.toString(), 1, {indent: '| '})
: '')
);
process.exitCode = 1;
}
}
}
@ -72,7 +95,7 @@ function runLinkCheck(
markdownLinkCheck(
fs.readFileSync(file).toString(),
{
baseUrl: '',
baseUrl: pathToFileURL(file).toString(),
// If Github rate limit is reached, wait 60s and try again.
retryOn429: true,
// Twitter links consistently fail.
@ -97,13 +120,11 @@ function runLinkCheck(
(async () => {
for (const file of files) {
console.log('Checking links in ' + file);
console.log(colors.grey('Checking links in ' + file));
try {
await runLinkCheck(file, {rateLimit: 500});
} catch (error) {
console.log(
colors.red(error instanceof Error ? error.message : `${error}`)
);
console.error(error);
process.exitCode = 1;
}
}

View File

@ -10,6 +10,7 @@ declare module 'markdown-link-check' {
link: string;
status: string;
statusCode: number;
err: string | null;
}
}