mirror of
https://github.com/DavidAnson/markdownlint.git
synced 2025-09-22 05:40:48 +02:00
Lint large test repos in parallel (via worker threads) for shorter run times.
This commit is contained in:
parent
446fe901c3
commit
e447db33c9
5 changed files with 68 additions and 6 deletions
44
test/markdownlint-test-parallel.js
Normal file
44
test/markdownlint-test-parallel.js
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
// @ts-check
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// eslint-disable-next-line n/no-unsupported-features/node-builtins
|
||||||
|
const { availableParallelism } = require("node:os");
|
||||||
|
const { Worker } = require("node:worker_threads");
|
||||||
|
const markdownlintSync = require("../lib/markdownlint").sync;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lint specified Markdown files (using multiple threads).
|
||||||
|
*
|
||||||
|
* @param {import("../lib/markdownlint").Options} options Configuration options.
|
||||||
|
* @returns {Promise<import("../lib/markdownlint").LintResults>} Results object.
|
||||||
|
*/
|
||||||
|
function markdownlintParallel(options) {
|
||||||
|
const workerCount = availableParallelism();
|
||||||
|
const files = options.files || [];
|
||||||
|
const chunkSize = Math.ceil(files.length / workerCount);
|
||||||
|
const promises = [];
|
||||||
|
for (let i = 0; i < workerCount; i++) {
|
||||||
|
promises.push(new Promise((resolve, reject) => {
|
||||||
|
const workerData = {
|
||||||
|
...options,
|
||||||
|
"files": files.slice(i * chunkSize, (i + 1) * chunkSize)
|
||||||
|
}
|
||||||
|
const worker = new Worker(__filename.replace(/parallel\.js$/, "worker.js"), { workerData });
|
||||||
|
worker.on("message", resolve);
|
||||||
|
worker.on("error", reject);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
return Promise.all(promises).then((workerResults) => {
|
||||||
|
const combinedResults = markdownlintSync(null);
|
||||||
|
for (const workerResult of workerResults) {
|
||||||
|
// eslint-disable-next-line guard-for-in
|
||||||
|
for (const result in workerResult) {
|
||||||
|
combinedResults[result] = workerResult[result];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return combinedResults;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = markdownlintParallel;
|
|
@ -10,5 +10,5 @@ test("https://github.com/dotnet/docs", (t) => {
|
||||||
const rootDir = "./test-repos/dotnet-docs";
|
const rootDir = "./test-repos/dotnet-docs";
|
||||||
const globPatterns = [ join(rootDir, "**/*.md") ];
|
const globPatterns = [ join(rootDir, "**/*.md") ];
|
||||||
const configPath = join(rootDir, ".markdownlint-cli2.jsonc");
|
const configPath = join(rootDir, ".markdownlint-cli2.jsonc");
|
||||||
return lintTestRepo(t, globPatterns, configPath);
|
return lintTestRepo(t, globPatterns, configPath, true);
|
||||||
});
|
});
|
||||||
|
|
|
@ -10,5 +10,5 @@ test("https://github.com/mdn/content", (t) => {
|
||||||
const rootDir = "./test-repos/mdn-content";
|
const rootDir = "./test-repos/mdn-content";
|
||||||
const globPatterns = [ join(rootDir, "**/*.md") ];
|
const globPatterns = [ join(rootDir, "**/*.md") ];
|
||||||
const configPath = join(rootDir, ".markdownlint-cli2.jsonc");
|
const configPath = join(rootDir, ".markdownlint-cli2.jsonc");
|
||||||
return lintTestRepo(t, globPatterns, configPath);
|
return lintTestRepo(t, globPatterns, configPath, true);
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
const { join } = require("node:path").posix;
|
const { join } = require("node:path").posix;
|
||||||
const jsoncParser = require("jsonc-parser");
|
const jsoncParser = require("jsonc-parser");
|
||||||
const jsYaml = require("js-yaml");
|
const jsYaml = require("js-yaml");
|
||||||
const markdownlint = require("../lib/markdownlint");
|
const { markdownlint, readConfig } = require("../lib/markdownlint").promises;
|
||||||
|
const markdownlintParallel = require("./markdownlint-test-parallel");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lints a test repository.
|
* Lints a test repository.
|
||||||
|
@ -13,9 +14,10 @@ const markdownlint = require("../lib/markdownlint");
|
||||||
* @param {Object} t Test instance.
|
* @param {Object} t Test instance.
|
||||||
* @param {string[]} globPatterns Array of files to in/exclude.
|
* @param {string[]} globPatterns Array of files to in/exclude.
|
||||||
* @param {string} configPath Path to config file.
|
* @param {string} configPath Path to config file.
|
||||||
|
* @param {boolean} [parallel] True to lint in parallel.
|
||||||
* @returns {Promise} Test result.
|
* @returns {Promise} Test result.
|
||||||
*/
|
*/
|
||||||
async function lintTestRepo(t, globPatterns, configPath) {
|
async function lintTestRepo(t, globPatterns, configPath, parallel) {
|
||||||
t.plan(1);
|
t.plan(1);
|
||||||
const { globby } = await import("globby");
|
const { globby } = await import("globby");
|
||||||
const jsoncParse = (json) => {
|
const jsoncParse = (json) => {
|
||||||
|
@ -25,7 +27,7 @@ async function lintTestRepo(t, globPatterns, configPath) {
|
||||||
const yamlParse = (yaml) => jsYaml.load(yaml);
|
const yamlParse = (yaml) => jsYaml.load(yaml);
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
globby(globPatterns),
|
globby(globPatterns),
|
||||||
markdownlint.promises.readConfig(configPath, [ jsoncParse, yamlParse ])
|
readConfig(configPath, [ jsoncParse, yamlParse ])
|
||||||
]).then((globbyAndReadConfigResults) => {
|
]).then((globbyAndReadConfigResults) => {
|
||||||
const [ files, rawConfig ] = globbyAndReadConfigResults;
|
const [ files, rawConfig ] = globbyAndReadConfigResults;
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
|
@ -37,7 +39,7 @@ async function lintTestRepo(t, globPatterns, configPath) {
|
||||||
v
|
v
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
return markdownlint.promises.markdownlint({
|
return (parallel ? markdownlintParallel : markdownlint)({
|
||||||
files,
|
files,
|
||||||
config
|
config
|
||||||
}).then((results) => {
|
}).then((results) => {
|
||||||
|
|
16
test/markdownlint-test-worker.js
Normal file
16
test/markdownlint-test-worker.js
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
// @ts-check
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const { parentPort, workerData } = require("node:worker_threads");
|
||||||
|
const markdownlint = require("../lib/markdownlint").promises.markdownlint;
|
||||||
|
|
||||||
|
// eslint-disable-next-line unicorn/prefer-top-level-await
|
||||||
|
markdownlint(workerData).then((lintResults) => {
|
||||||
|
// @ts-ignore
|
||||||
|
parentPort.
|
||||||
|
// eslint-disable-next-line unicorn/require-post-message-target-origin
|
||||||
|
postMessage(lintResults);
|
||||||
|
// eslint-disable-next-line n/no-process-exit
|
||||||
|
process.exit();
|
||||||
|
});
|
Loading…
Add table
Add a link
Reference in a new issue