mirror of
https://github.com/sass/sass.git
synced 2024-09-21 02:27:30 +00:00
parent
61914f67dc
commit
c074df5a41
6
package-lock.json
generated
6
package-lock.json
generated
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
1
tool/types/markdown-link-check.d.ts
vendored
1
tool/types/markdown-link-check.d.ts
vendored
@ -10,6 +10,7 @@ declare module 'markdown-link-check' {
|
||||
link: string;
|
||||
status: string;
|
||||
statusCode: number;
|
||||
err: string | null;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user