diff --git a/README.md b/README.md index 0737708..6a6f47c 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,13 @@ When combined with a watching task (such as [grunt-contrib-watch][watch]), even ## Options +### `threads` + +* Type: `Number`, `Boolean`, `String` +* Default: `auto`, which is the number of threads -1 + +Use this option to control the number of threads that grunt-htmllint will use when validating a big number of files. This will spawn as many Java processes as the number of threads. + ### `ignore` * Type: `Array`, `String`, or `RegExp` diff --git a/lib/htmllint.js b/lib/htmllint.js index bbdcd9c..0ffc10b 100644 --- a/lib/htmllint.js +++ b/lib/htmllint.js @@ -16,9 +16,22 @@ const MAX_CHARS = 5000; // https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback const MAX_BUFFER = 20_000 * 1024; -// eslint-disable-next-line unicorn/explicit-length-check -const CPUS = os.cpus() && os.cpus().length; -const THREADS = CPUS > 2 ? CPUS - 1 : 1; +function getThreads(options) { + // eslint-disable-next-line unicorn/explicit-length-check + const cpus = os.cpus() && os.cpus().length; + const defaultThreads = cpus > 2 ? cpus - 1 : 1; + const { threads } = options; + + if (threads === 'auto' || threads === '' || Boolean(threads) === true) { + return defaultThreads; + } + + if (threads <= 1 || Boolean(threads) === false) { + return 1; + } + + return threads; +} // Replace left/right quotation marks with normal quotation marks function normalizeQuotationMarks(string) { @@ -135,8 +148,9 @@ function htmllint(config, done) { const files = config.files.map(file => path.normalize(file)); const chunks = chunkify(files, MAX_CHARS); + const threads = getThreads(config); - async.mapLimit(chunks, THREADS, (chunk, cb) => { + async.mapLimit(chunks, threads, (chunk, cb) => { const args = javaArgs(java, chunk, config); execFile('java', args, { maxBuffer: MAX_BUFFER, shell: true }, (error, stdout, stderr) => { diff --git a/tasks/html.js b/tasks/html.js index 872dc4c..867db1b 100644 --- a/tasks/html.js +++ b/tasks/html.js @@ -21,7 +21,8 @@ module.exports = function(grunt) { force: false, absoluteFilePathsForReporter: false, errorlevels: ['info', 'warning', 'error'], - noLangDetect: false + noLangDetect: false, + threads: 'auto' }); const { force } = options; let { reporterOutput } = options;