From 2b23e6ffe52b689ccf7d817d4b63370e3136e8aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=20Erik=20St=C3=B8wer?= Date: Mon, 16 Oct 2017 19:11:09 +0200 Subject: [PATCH] Update: Resolve npm installed formatters (#5900) --- docs/user-guide/command-line-interface.md | 11 ++++++ lib/cli-engine.js | 23 ++++++++++-- .../eslint-formatter-foo/index.js | 1 + .../cli-engine/eslint-formatter-bar/index.js | 1 + tests/lib/cli-engine.js | 36 +++++++++++++++++++ 5 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 tests/fixtures/cli-engine/@somenamespace/eslint-formatter-foo/index.js create mode 100644 tests/fixtures/cli-engine/eslint-formatter-bar/index.js diff --git a/docs/user-guide/command-line-interface.md b/docs/user-guide/command-line-interface.md index 3a7e17650c1e..631a7203b91a 100644 --- a/docs/user-guide/command-line-interface.md +++ b/docs/user-guide/command-line-interface.md @@ -333,6 +333,17 @@ Example: eslint -f ./customformat.js file.js +An npm-installed formatter is resolved with or without `eslint-formatter-` prefix. + +Example: + + npm install eslint-formatter-pretty + + eslint -f pretty file.js + + // equivalent: + eslint -f eslint-formatter-pretty file.js + When specified, the given format is output to the console. If you'd like to save that output into a file, you can do so on the command line like so: eslint -f compact file.js > results.txt diff --git a/lib/cli-engine.js b/lib/cli-engine.js index 38c49cb31d84..0d94945ee49e 100644 --- a/lib/cli-engine.js +++ b/lib/cli-engine.js @@ -26,10 +26,14 @@ const fs = require("fs"), validator = require("./config/config-validator"), stringify = require("json-stable-stringify"), hash = require("./util/hash"), + ModuleResolver = require("./util/module-resolver"), + Plugins = require("./config/plugins"), pkg = require("../package.json"); const debug = require("debug")("eslint:cli-engine"); +const resolver = new ModuleResolver(); + //------------------------------------------------------------------------------ // Typedefs //------------------------------------------------------------------------------ @@ -670,15 +674,28 @@ class CLIEngine { // replace \ with / for Windows compatibility format = format.replace(/\\/g, "/"); + let cwd = this.options ? this.options.cwd : process.cwd(); + + const namespace = Plugins.getNamespace(format); + + if (namespace) { + cwd = `${cwd}/${namespace}`; + format = Plugins.removeNamespace(format); + } + let formatterPath; // if there's a slash, then it's a file if (format.indexOf("/") > -1) { - const cwd = this.options ? this.options.cwd : process.cwd(); - formatterPath = path.resolve(cwd, format); } else { - formatterPath = `./formatters/${format}`; + const npmFormat = /^eslint-formatter-/.test(format) ? format : `eslint-formatter-${format}`; + + try { + formatterPath = resolver.resolve(npmFormat, cwd); + } catch (_) { + formatterPath = `./formatters/${format}`; + } } try { diff --git a/tests/fixtures/cli-engine/@somenamespace/eslint-formatter-foo/index.js b/tests/fixtures/cli-engine/@somenamespace/eslint-formatter-foo/index.js new file mode 100644 index 000000000000..0a55f349ae71 --- /dev/null +++ b/tests/fixtures/cli-engine/@somenamespace/eslint-formatter-foo/index.js @@ -0,0 +1 @@ +module.exports = function() {}; diff --git a/tests/fixtures/cli-engine/eslint-formatter-bar/index.js b/tests/fixtures/cli-engine/eslint-formatter-bar/index.js new file mode 100644 index 000000000000..0a55f349ae71 --- /dev/null +++ b/tests/fixtures/cli-engine/eslint-formatter-bar/index.js @@ -0,0 +1 @@ +module.exports = function() {}; diff --git a/tests/lib/cli-engine.js b/tests/lib/cli-engine.js index 5026d4b197e7..7b17b25d16db 100644 --- a/tests/lib/cli-engine.js +++ b/tests/lib/cli-engine.js @@ -2685,6 +2685,42 @@ describe("CLIEngine", () => { assert.isFunction(formatter); }); + it("should return a function when a formatter prefixed with eslint-formatter is requested", () => { + const engine = new CLIEngine({ + cwd: getFixturePath("cli-engine") + }), + formatter = engine.getFormatter("bar"); + + assert.isFunction(formatter); + }); + + it("should return a function when a formatter is requested, also when the eslint-formatter prefix is included in the format argument", () => { + const engine = new CLIEngine({ + cwd: getFixturePath("cli-engine") + }), + formatter = engine.getFormatter("eslint-formatter-bar"); + + assert.isFunction(formatter); + }); + + it("should return a function when a formatter is requested within a scoped npm package", () => { + const engine = new CLIEngine({ + cwd: getFixturePath("cli-engine") + }), + formatter = engine.getFormatter("@somenamespace/foo"); + + assert.isFunction(formatter); + }); + + it("should return a function when a formatter is requested within a scoped npm package, also when the eslint-formatter prefix is included in the format argument", () => { + const engine = new CLIEngine({ + cwd: getFixturePath("cli-engine") + }), + formatter = engine.getFormatter("@somenamespace/eslint-formatter-foo"); + + assert.isFunction(formatter); + }); + it("should return null when a customer formatter doesn't exist", () => { const engine = new CLIEngine(), formatterPath = getFixturePath("formatters", "doesntexist.js");