From e9392b862e6bc0e78147f131d4207d6a1efb5b01 Mon Sep 17 00:00:00 2001 From: Aleksandr Veselov Date: Sat, 28 Jul 2018 21:41:57 +0300 Subject: [PATCH 1/4] Fix bad module resolution (#42) (#43) * Fixes issue #42 --- .gitignore | 2 ++ markdownlint.js | 12 ++++++++++-- .../node_modules/test-rule-package/index.js | 10 ++++++++++ .../test-rule-package/package.json | 6 ++++++ .../custom-rules/relative-to-cwd/package.json | 1 + test/test.js | 19 +++++++++++++++++++ 6 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 test/custom-rules/relative-to-cwd/node_modules/test-rule-package/index.js create mode 100644 test/custom-rules/relative-to-cwd/node_modules/test-rule-package/package.json create mode 100644 test/custom-rules/relative-to-cwd/package.json diff --git a/.gitignore b/.gitignore index f524bcd5..5658f8a4 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,8 @@ build/Release # Dependency directory # https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git node_modules +# Keep it for test +!test/custom-rules/relative-to-cwd/node_modules # Optional npm cache directory .npm diff --git a/markdownlint.js b/markdownlint.js index e747c193..d9fc2ce5 100755 --- a/markdownlint.js +++ b/markdownlint.js @@ -4,6 +4,7 @@ var fs = require('fs'); var path = require('path'); +var Module = require('module'); var program = require('commander'); var getStdin = require('get-stdin'); var jsYaml = require('js-yaml'); @@ -141,8 +142,15 @@ function loadCustomRuleFromFile(filepath) { function tryResolvePath(filepath) { try { if (path.basename(filepath) === filepath && path.extname(filepath) === '') { - // Looks like a package name - return require.resolve(filepath); + // Looks like a package name, resolve it relative to cwd + // Get list of directories, where requested module can be. + var paths = Module._nodeModulePaths(process.cwd()); + paths = paths.concat(Module.globalPaths); + if (require.resolve.paths) { + // Node >= 8.9.0 + return require.resolve(filepath, {paths: paths}); + } + return Module._resolveFilename(filepath, {paths: paths}); } // Maybe it is a path to package installed locally return require.resolve(path.join(process.cwd(), filepath)); diff --git a/test/custom-rules/relative-to-cwd/node_modules/test-rule-package/index.js b/test/custom-rules/relative-to-cwd/node_modules/test-rule-package/index.js new file mode 100644 index 00000000..b7502a0a --- /dev/null +++ b/test/custom-rules/relative-to-cwd/node_modules/test-rule-package/index.js @@ -0,0 +1,10 @@ +module.exports = { + names: ['test-rule-package'], + description: 'Test rule package relative to cwd broken', + tags: ['test'], + function: (params, onError) => { + onError({ + lineNumber: 1 + }); + } +}; diff --git a/test/custom-rules/relative-to-cwd/node_modules/test-rule-package/package.json b/test/custom-rules/relative-to-cwd/node_modules/test-rule-package/package.json new file mode 100644 index 00000000..0914709b --- /dev/null +++ b/test/custom-rules/relative-to-cwd/node_modules/test-rule-package/package.json @@ -0,0 +1,6 @@ +{ + "name": "test-rule-package", + "main": "./index.js", + "version": "0.0.1", + "private": true +} \ No newline at end of file diff --git a/test/custom-rules/relative-to-cwd/package.json b/test/custom-rules/relative-to-cwd/package.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/test/custom-rules/relative-to-cwd/package.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/test/test.js b/test/test.js index 651c8258..81dacf68 100644 --- a/test/test.js +++ b/test/test.js @@ -394,6 +394,25 @@ test('Custom rule from node_modules package loaded', async t => { } }); +test('Custom rule from node_modules package loaded relative to cwd', async t => { + try { + var input = '# Input'; + await execa(path.resolve('..', 'markdownlint.js'), + ['--rules', 'test-rule-package', '--stdin'], { + input, + cwd: path.join(__dirname, 'custom-rules', 'relative-to-cwd') + }); + t.fail(); + } catch (err) { + const expected = [ + 'stdin: 1: test-rule-package Test rule package relative to cwd broken', + '' + ].join('\n'); + t.true(err.stdout === ''); + t.true(err.stderr === expected); + } +}); + test('Custom rule from package loaded', async t => { try { var input = '# Input'; From c523277027791fd685e055d5aca363eb6851b15a Mon Sep 17 00:00:00 2001 From: David Anson Date: Sat, 28 Jul 2018 15:48:05 -0700 Subject: [PATCH 2/4] Return error code/message for invalid custom rules (fixes #41). --- markdownlint.js | 30 +++++++++++++++++++----------- test/test.js | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/markdownlint.js b/markdownlint.js index d9fc2ce5..bfab58f9 100755 --- a/markdownlint.js +++ b/markdownlint.js @@ -130,15 +130,6 @@ program program.parse(process.argv); -function loadCustomRuleFromFile(filepath) { - try { - return require(filepath.absolute); - } catch (err) { - console.error('Cannot load custom rule from ' + filepath.original + ': ' + err.message); - process.exit(3); - } -} - function tryResolvePath(filepath) { try { if (path.basename(filepath) === filepath && path.extname(filepath) === '') { @@ -159,10 +150,27 @@ function tryResolvePath(filepath) { } } +function loadCustomRules(rules) { + return flatten(rules.map(function (rule) { + try { + var resolvedPath = [tryResolvePath(rule)]; + var fileList = prepareFileList(resolvedPath, ['js']).map(function (filepath) { + return require(filepath.absolute); + }); + if (fileList.length === 0) { + throw new Error('No such rule'); + } + return fileList; + } catch (err) { + console.error('Cannot load custom rule ' + rule + ': ' + err.message); + process.exit(3); + } + })); +} + var files = prepareFileList(program.args, ['md', 'markdown']); var ignores = prepareFileList(program.ignore, ['md', 'markdown']); -var customRuleFiles = program.rules.map(tryResolvePath); -var customRules = prepareFileList(customRuleFiles, ['js']).map(loadCustomRuleFromFile); +var customRules = loadCustomRules(program.rules); var diff = differenceWith(files, ignores, function (a, b) { return a.absolute === b.absolute; }).map(function (paths) { diff --git a/test/test.js b/test/test.js index 81dacf68..3dd04929 100644 --- a/test/test.js +++ b/test/test.js @@ -448,3 +448,22 @@ test('Custom rule from several packages loaded', async t => { t.true(err.stderr === expected); } }); + +test('Invalid custom rule name reports error', async t => { + try { + var input = '# Input'; + await execa('../markdownlint.js', [ + '--rules', 'test-rule-package', + '--rules', 'invalid-package', + '--stdin' + ], {input}); + t.fail(); + } catch (err) { + const expected = [ + 'Cannot load custom rule invalid-package: No such rule', + '' + ].join('\n'); + t.true(err.stdout === ''); + t.true(err.stderr === expected); + } +}); From 9b304cc0716938504c2804cd5fa75b527e5b9855 Mon Sep 17 00:00:00 2001 From: David Anson Date: Sat, 28 Jul 2018 16:01:15 -0700 Subject: [PATCH 3/4] Update markdownlint dependency to 0.11.0. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1f24565c..1ef45d9f 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "js-yaml": "~3.11.0", "lodash.differencewith": "~4.5.0", "lodash.flatten": "~4.4.0", - "markdownlint": "~0.10.0", + "markdownlint": "~0.11.0", "rc": "~1.2.7" }, "devDependencies": { From 1b9623f8768dd7182d6dc1d89f454b04501e0a85 Mon Sep 17 00:00:00 2001 From: David Anson Date: Sat, 28 Jul 2018 21:25:55 -0700 Subject: [PATCH 4/4] Bump version 0.12.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1ef45d9f..52a3a7ed 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "markdownlint-cli", - "version": "0.11.0", + "version": "0.12.0", "description": "MarkdownLint Command Line Interface", "main": "markdownlint.js", "bin": {