Skip to content

Commit d513b55

Browse files
mildsunrisetargos
authored andcommitted
doc: improve markdown link checker
- Test link definitions too - Report all broken links in a file, not just the first one - Avoid use of workers (launching ~90 workers has substantial overhead, and in my 4-core machine it is slower than not using them at all) & other simplifications Refs: #32359 PR-URL: #32586 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 7d93a3f commit d513b55

File tree

1 file changed

+28
-48
lines changed

1 file changed

+28
-48
lines changed

tools/doc/checkLinks.js

+28-48
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,43 @@
11
'use strict';
22

33
const fs = require('fs');
4-
const { Worker, isMainThread, workerData: path } = require('worker_threads');
4+
const { extname, join, resolve } = require('path');
5+
const unified = require('unified');
6+
const { pathToFileURL } = require('url');
7+
const DIR = resolve(process.argv[2]);
8+
9+
console.log('Running Markdown link checker...');
10+
findMarkdownFilesRecursively(DIR);
511

612
function* getLinksRecursively(node) {
7-
if (
8-
(node.type === 'link' && !node.url.startsWith('#')) ||
9-
node.type === 'image'
10-
) {
13+
if (node.url && !node.url.startsWith('#')) {
1114
yield node;
1215
}
1316
for (const child of node.children || []) {
1417
yield* getLinksRecursively(child);
1518
}
1619
}
1720

18-
if (isMainThread) {
19-
const { extname, join, resolve } = require('path');
20-
const DIR = resolve(process.argv[2]);
21-
22-
console.log('Running Markdown link checker...');
23-
24-
async function* findMarkdownFilesRecursively(dirPath) {
25-
const fileNames = await fs.promises.readdir(dirPath);
26-
27-
for (const fileName of fileNames) {
28-
const path = join(dirPath, fileName);
29-
30-
const stats = await fs.promises.stat(path);
31-
if (
32-
stats.isDirectory() &&
33-
fileName !== 'api' &&
34-
fileName !== 'deps' &&
35-
fileName !== 'node_modules'
36-
) {
37-
yield* findMarkdownFilesRecursively(path);
38-
} else if (extname(fileName) === '.md') {
39-
yield path;
40-
}
21+
function findMarkdownFilesRecursively(dirPath) {
22+
const entries = fs.readdirSync(dirPath, { withFileTypes: true });
23+
24+
for (const entry of entries) {
25+
const path = join(dirPath, entry.name);
26+
27+
if (
28+
entry.isDirectory() &&
29+
entry.name !== 'api' &&
30+
entry.name !== 'deps' &&
31+
entry.name !== 'node_modules'
32+
) {
33+
findMarkdownFilesRecursively(path);
34+
} else if (entry.isFile() && extname(entry.name) === '.md') {
35+
checkFile(path);
4136
}
4237
}
38+
}
4339

44-
function errorHandler(error) {
45-
console.error(error);
46-
process.exitCode = 1;
47-
}
48-
49-
setImmediate(async () => {
50-
for await (const path of findMarkdownFilesRecursively(DIR)) {
51-
new Worker(__filename, { workerData: path }).on('error', errorHandler);
52-
}
53-
});
54-
} else {
55-
const unified = require('unified');
56-
const { pathToFileURL } = require('url');
57-
40+
function checkFile(path) {
5841
const tree = unified()
5942
.use(require('remark-parse'))
6043
.parse(fs.readFileSync(path));
@@ -63,12 +46,9 @@ if (isMainThread) {
6346
for (const node of getLinksRecursively(tree)) {
6447
const targetURL = new URL(node.url, base);
6548
if (targetURL.protocol === 'file:' && !fs.existsSync(targetURL)) {
66-
const error = new Error('Broken link in a Markdown document.');
67-
const { start } = node.position;
68-
error.stack =
69-
error.stack.substring(0, error.stack.indexOf('\n') + 5) +
70-
`at ${node.type} (${path}:${start.line}:${start.column})`;
71-
throw error;
49+
const { line, column } = node.position.start;
50+
console.error(`Broken link at ${path}:${line}:${column} (${node.url})`);
51+
process.exitCode = 1;
7252
}
7353
}
7454
}

0 commit comments

Comments
 (0)