From d513b558918dbb82cc59aec7422ab8dc8c36ac7e Mon Sep 17 00:00:00 2001 From: Alba Mendez Date: Tue, 31 Mar 2020 18:59:29 +0200 Subject: [PATCH] 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: https://github.com/nodejs/node/pull/32359 PR-URL: https://github.com/nodejs/node/pull/32586 Reviewed-By: Anna Henningsen Reviewed-By: Colin Ihrig Reviewed-By: James M Snell --- tools/doc/checkLinks.js | 76 +++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 48 deletions(-) diff --git a/tools/doc/checkLinks.js b/tools/doc/checkLinks.js index dc5e6e1573abee..e97eb65abebf6e 100644 --- a/tools/doc/checkLinks.js +++ b/tools/doc/checkLinks.js @@ -1,13 +1,16 @@ 'use strict'; const fs = require('fs'); -const { Worker, isMainThread, workerData: path } = require('worker_threads'); +const { extname, join, resolve } = require('path'); +const unified = require('unified'); +const { pathToFileURL } = require('url'); +const DIR = resolve(process.argv[2]); + +console.log('Running Markdown link checker...'); +findMarkdownFilesRecursively(DIR); function* getLinksRecursively(node) { - if ( - (node.type === 'link' && !node.url.startsWith('#')) || - node.type === 'image' - ) { + if (node.url && !node.url.startsWith('#')) { yield node; } for (const child of node.children || []) { @@ -15,46 +18,26 @@ function* getLinksRecursively(node) { } } -if (isMainThread) { - const { extname, join, resolve } = require('path'); - const DIR = resolve(process.argv[2]); - - console.log('Running Markdown link checker...'); - - async function* findMarkdownFilesRecursively(dirPath) { - const fileNames = await fs.promises.readdir(dirPath); - - for (const fileName of fileNames) { - const path = join(dirPath, fileName); - - const stats = await fs.promises.stat(path); - if ( - stats.isDirectory() && - fileName !== 'api' && - fileName !== 'deps' && - fileName !== 'node_modules' - ) { - yield* findMarkdownFilesRecursively(path); - } else if (extname(fileName) === '.md') { - yield path; - } +function findMarkdownFilesRecursively(dirPath) { + const entries = fs.readdirSync(dirPath, { withFileTypes: true }); + + for (const entry of entries) { + const path = join(dirPath, entry.name); + + if ( + entry.isDirectory() && + entry.name !== 'api' && + entry.name !== 'deps' && + entry.name !== 'node_modules' + ) { + findMarkdownFilesRecursively(path); + } else if (entry.isFile() && extname(entry.name) === '.md') { + checkFile(path); } } +} - function errorHandler(error) { - console.error(error); - process.exitCode = 1; - } - - setImmediate(async () => { - for await (const path of findMarkdownFilesRecursively(DIR)) { - new Worker(__filename, { workerData: path }).on('error', errorHandler); - } - }); -} else { - const unified = require('unified'); - const { pathToFileURL } = require('url'); - +function checkFile(path) { const tree = unified() .use(require('remark-parse')) .parse(fs.readFileSync(path)); @@ -63,12 +46,9 @@ if (isMainThread) { for (const node of getLinksRecursively(tree)) { const targetURL = new URL(node.url, base); if (targetURL.protocol === 'file:' && !fs.existsSync(targetURL)) { - const error = new Error('Broken link in a Markdown document.'); - const { start } = node.position; - error.stack = - error.stack.substring(0, error.stack.indexOf('\n') + 5) + - `at ${node.type} (${path}:${start.line}:${start.column})`; - throw error; + const { line, column } = node.position.start; + console.error(`Broken link at ${path}:${line}:${column} (${node.url})`); + process.exitCode = 1; } } }