From 7491578403a5a35464772c730854c3a5169c0de7 Mon Sep 17 00:00:00 2001 From: Robert Kieffer Date: Wed, 4 May 2022 04:09:07 -1000 Subject: [PATCH] feat: add `disablePluginRule` flag for render() options (#3701) Co-authored-by: Edward Hartwell Goose --- packages/less/bin/lessc | 21 ++++++++++++++++++--- packages/less/src/less-browser/utils.js | 2 +- packages/less/src/less-node/lessc-helper.js | 1 + packages/less/src/less/parser/parser.js | 16 +++++++++++++--- packages/less/test/index.js | 1 + packages/less/test/less-test.js | 18 ++++++++++++++++++ 6 files changed, 52 insertions(+), 7 deletions(-) diff --git a/packages/less/bin/lessc b/packages/less/bin/lessc index 2a7427a18..c11c9bf2b 100755 --- a/packages/less/bin/lessc +++ b/packages/less/bin/lessc @@ -1,4 +1,7 @@ #!/usr/bin/env node + +/* eslint indent: [2, 2, {"SwitchCase": 1}] */ + "use strict"; var path = require('path'); @@ -87,6 +90,12 @@ function render() { output = path.resolve(process.cwd(), output); } + if (options.disablePluginRule && queuePlugins.length > 0) { + console.error('--plugin and --disable-plugin-rule may not be used at the same time'); + process.exitCode = 1; + return; + } + if (options.sourceMap) { sourceMapOptions.sourceMapInputFilename = input; @@ -113,6 +122,7 @@ function render() { var mapDir = path.dirname(mapFilename); var outputDir = path.dirname(output); // find the path from the map to the output file + // eslint-disable-next-line max-len sourceMapOptions.sourceMapOutputFilename = path.join(path.relative(mapDir, outputDir), path.basename(output)); // make the sourcemap filename point to the sourcemap relative to the css file output directory sourceMapOptions.sourceMapFilename = path.join(path.relative(outputDir, mapDir), path.basename(sourceMapOptions.sourceMapFullFilename)); @@ -180,8 +190,8 @@ function render() { var filename = sourceMapOptions.sourceMapFullFilename; ensureDirectory(filename); - //To fix https://github.com/less/less.js/issues/3646 - output=output.toString(); + // To fix https://github.com/less/less.js/issues/3646 + output = output.toString(); fs.writeFile(filename, output, 'utf8', function (err) { if (err) { @@ -444,7 +454,8 @@ function processPluginQueue() { break; case 'no-js': - console.error('The "--no-js" argument is deprecated, as inline JavaScript ' + 'is disabled by default. Use "--js" to enable inline JavaScript (not recommended).'); + // eslint-disable-next-line max-len + console.error('The "--no-js" argument is deprecated, as inline JavaScript is disabled by default. Use "--js" to enable inline JavaScript (not recommended).'); break; case 'include-path': @@ -629,6 +640,10 @@ function processPluginQueue() { }); break; + case 'disable-plugin-rule': + options.disablePluginRule = true; + break; + default: queuePlugins.push({ name: arg, diff --git a/packages/less/src/less-browser/utils.js b/packages/less/src/less-browser/utils.js index 42a1b442e..039f1d595 100644 --- a/packages/less/src/less-browser/utils.js +++ b/packages/less/src/less-browser/utils.js @@ -9,7 +9,7 @@ export function extractId(href) { } export function addDataAttr(options, tag) { - if(!tag) return; // in case of tag is null or undefined + if (!tag) {return;} // in case of tag is null or undefined for (const opt in tag.dataset) { if (tag.dataset.hasOwnProperty(opt)) { if (opt === 'env' || opt === 'dumpLineNumbers' || opt === 'rootpath' || opt === 'errorReporting') { diff --git a/packages/less/src/less-node/lessc-helper.js b/packages/less/src/less-node/lessc-helper.js index 3aadb5478..e2c1c7c64 100644 --- a/packages/less/src/less-node/lessc-helper.js +++ b/packages/less/src/less-node/lessc-helper.js @@ -67,6 +67,7 @@ const lessc_helper = { console.log(' --plugin=less-plugin-clean-css or just --clean-css'); console.log(' specify options afterwards e.g. --plugin=less-plugin-clean-css="advanced"'); console.log(' or --clean-css="advanced"'); + console.log(' --disable-plugin-rule Disallow @plugin statements'); console.log(''); console.log('-------------------------- Deprecated ----------------'); console.log(' -sm=on|off Legacy parens-only math. Use --math'); diff --git a/packages/less/src/less/parser/parser.js b/packages/less/src/less/parser/parser.js index c7a65cb07..d1f70debf 100644 --- a/packages/less/src/less/parser/parser.js +++ b/packages/less/src/less/parser/parser.js @@ -149,12 +149,22 @@ const Parser = function Parser(context, imports, fileInfo) { // parse: function (str, callback, additionalData) { let root; - let error = null; + let err = null; let globalVars; let modifyVars; let ignored; let preText = ''; + // Optionally disable @plugin parsing + if (additionalData && additionalData.disablePluginRule) { + parsers.plugin = function() { + var dir = parserInput.$re(/^@plugin?\s+/); + if (dir) { + error('@plugin statements are not allowed when disablePluginRule is set to true'); + } + } + }; + globalVars = (additionalData && additionalData.globalVars) ? `${Parser.serializeVars(additionalData.globalVars)}\n` : ''; modifyVars = (additionalData && additionalData.modifyVars) ? `\n${Parser.serializeVars(additionalData.modifyVars)}` : ''; @@ -226,7 +236,7 @@ const Parser = function Parser(context, imports, fileInfo) { } } - error = new LessError({ + err = new LessError({ type: 'Parse', message, index: endInfo.furthest, @@ -235,7 +245,7 @@ const Parser = function Parser(context, imports, fileInfo) { } const finish = e => { - e = error || e || imports.error; + e = err || e || imports.error; if (e) { if (!(e instanceof LessError)) { diff --git a/packages/less/test/index.js b/packages/less/test/index.js index 880d57ddd..2a5803034 100644 --- a/packages/less/test/index.js +++ b/packages/less/test/index.js @@ -88,6 +88,7 @@ lessTester.testSyncronous({syncImport: true}, '_main/import'); lessTester.testSyncronous({syncImport: true}, '_main/plugin'); lessTester.testSyncronous({syncImport: true}, 'math/strict/css'); lessTester.testNoOptions(); +lessTester.testDisablePluginRule(); lessTester.testJSImport(); lessTester.finished(); diff --git a/packages/less/test/less-test.js b/packages/less/test/less-test.js index ad7d6d7f9..67627d987 100644 --- a/packages/less/test/less-test.js +++ b/packages/less/test/less-test.js @@ -563,6 +563,23 @@ module.exports = function() { }; } + function testDisablePluginRule() { + less.render( + '@plugin "../../plugin/some_plugin";', + {disablePluginRule: true}, + function(err) { + // TODO: Need a better way of identifing exactly which error is thrown. Checking + // text like this tends to be rather brittle. + const EXPECTED = '@plugin statements are not allowed when disablePluginRule is set to true'; + if (!err || String(err).indexOf(EXPECTED) < 0) { + fail('ERROR: Expected "' + EXPECTED + '" error'); + return; + } + ok(stylize('OK\n', 'green')); + } + ); + } + return { runTestSet: runTestSet, runTestSetNormalOnly: runTestSetNormalOnly, @@ -575,6 +592,7 @@ module.exports = function() { testImportRedirect: testImportRedirect, testEmptySourcemap: testEmptySourcemap, testNoOptions: testNoOptions, + testDisablePluginRule: testDisablePluginRule, testJSImport: testJSImport, finished: finished };