diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md index 7805193c..34e0a3a0 100644 --- a/CHANGELOG.unreleased.md +++ b/CHANGELOG.unreleased.md @@ -44,6 +44,10 @@ const link = http://example.com; --> +#### API: add resolveConfig option to getFileInfo() ([#6666] by [@kaicataldo]) + +Add a `resolveConfig: boolean` option to `prettier.getFileInfo()` that, when set to `true`, will resolve the configuration for the given file path. This allows consumers to take any overridden parsers into account. + #### JavaScript: add support for PartialApplication ([#6397] by [@JounQin]) Previous versions would not be able to format this syntax, this has been fixed in this version. diff --git a/docs/api.md b/docs/api.md index 88ba19fd..a2126dc2 100644 --- a/docs/api.md +++ b/docs/api.md @@ -100,6 +100,8 @@ Setting `options.ignorePath` (`string`) and `options.withNodeModules` (`boolean` Providing [plugin](plugins.md) paths in `options.plugins` (`string[]`) helps extract `inferredParser` for files that are not supported by Prettier core. +When setting `options.resolveConfig` (`boolean`, default `false`), Prettier will resolve the configuration for the given `filePath`. This is useful, for example, when the `inferredParser` might be overridden for a subset of files. + Use `prettier.getFileInfo.sync(filePath [, options])` if you'd like to use sync version. ## `prettier.getSupportInfo([version])` diff --git a/src/common/get-file-info.js b/src/common/get-file-info.js index fb5474dc..ca7b9f0c 100644 --- a/src/common/get-file-info.js +++ b/src/common/get-file-info.js @@ -2,6 +2,7 @@ const createIgnorer = require("./create-ignorer"); const options = require("../main/options"); +const config = require("../config/resolve-config"); const path = require("path"); /** @@ -28,11 +29,13 @@ function getFileInfo(filePath, opts) { } return createIgnorer(opts.ignorePath, opts.withNodeModules).then(ignorer => - _getFileInfo( + _getFileInfo({ ignorer, - normalizeFilePath(filePath, opts.ignorePath), - opts.plugins - ) + filePath: normalizeFilePath(filePath, opts.ignorePath), + plugins: opts.plugins, + resolveConfig: opts.resolveConfig, + sync: false + }) ); } @@ -49,21 +52,45 @@ getFileInfo.sync = function(filePath, opts) { } const ignorer = createIgnorer.sync(opts.ignorePath, opts.withNodeModules); - return _getFileInfo( + return _getFileInfo({ ignorer, - normalizeFilePath(filePath, opts.ignorePath), - opts.plugins - ); + filePath: normalizeFilePath(filePath, opts.ignorePath), + plugins: opts.plugins, + resolveConfig: opts.resolveConfig, + sync: true + }); }; -function _getFileInfo(ignorer, filePath, plugins) { - const ignored = ignorer.ignores(filePath); - const inferredParser = options.inferParser(filePath, plugins) || null; - - return { - ignored, - inferredParser +function _getFileInfo({ + ignorer, + filePath, + plugins, + resolveConfig = false, + sync = false +}) { + const fileInfo = { + ignored: ignorer.ignores(filePath), + inferredParser: options.inferParser(filePath, plugins) || null }; + + if (!fileInfo.inferredParser && resolveConfig) { + if (!sync) { + return config.resolveConfig(filePath).then(resolvedConfig => { + if (resolvedConfig && resolvedConfig.parser) { + fileInfo.inferredParser = resolvedConfig.parser; + } + + return fileInfo; + }); + } + + const resolvedConfig = config.resolveConfig.sync(filePath); + if (resolvedConfig && resolvedConfig.parser) { + fileInfo.inferredParser = resolvedConfig.parser; + } + } + + return fileInfo; } function normalizeFilePath(filePath, ignorePath) { diff --git a/tests_integration/__tests__/file-info.js b/tests_integration/__tests__/file-info.js index 444045fd..9150d48a 100644 --- a/tests_integration/__tests__/file-info.js +++ b/tests_integration/__tests__/file-info.js @@ -131,6 +131,142 @@ test("API getFileInfo.sync with filepath only", () => { }); }); +test("API getFileInfo with resolveConfig", () => { + const file1 = path.resolve( + path.join(__dirname, "../cli/with-resolve-config/file.foo") + ); + const file2 = path.resolve( + path.join(__dirname, "../cli/with-resolve-config/file.bar") + ); + + expect(prettier.getFileInfo(file1)).resolves.toMatchObject({ + ignored: false, + inferredParser: null + }); + expect(prettier.getFileInfo(file2)).resolves.toMatchObject({ + ignored: false, + inferredParser: null + }); + expect( + prettier.getFileInfo(file1, { + resolveConfig: true + }) + ).resolves.toMatchObject({ + ignored: false, + inferredParser: "json" + }); + expect( + prettier.getFileInfo(file2, { + resolveConfig: true + }) + ).resolves.toMatchObject({ + ignored: false, + inferredParser: "babel" + }); +}); + +test("API getFileInfo with resolveConfig when no config is present", () => { + const file1 = path.resolve( + path.join(__dirname, "../cli/with-resolve-config-no-config/file.foo") + ); + const file2 = path.resolve( + path.join(__dirname, "../cli/with-resolve-config-no-config/file.bar") + ); + + expect(prettier.getFileInfo(file1)).resolves.toMatchObject({ + ignored: false, + inferredParser: null + }); + expect(prettier.getFileInfo(file2)).resolves.toMatchObject({ + ignored: false, + inferredParser: null + }); + expect( + prettier.getFileInfo(file1, { + resolveConfig: true + }) + ).resolves.toMatchObject({ + ignored: false, + inferredParser: null + }); + expect( + prettier.getFileInfo(file2, { + resolveConfig: true + }) + ).resolves.toMatchObject({ + ignored: false, + inferredParser: null + }); +}); + +test("API getFileInfo.sync with resolveConfig", () => { + const file1 = path.resolve( + path.join(__dirname, "../cli/with-resolve-config/file.foo") + ); + const file2 = path.resolve( + path.join(__dirname, "../cli/with-resolve-config/file.bar") + ); + + expect(prettier.getFileInfo.sync(file1)).toMatchObject({ + ignored: false, + inferredParser: null + }); + expect(prettier.getFileInfo.sync(file2)).toMatchObject({ + ignored: false, + inferredParser: null + }); + expect( + prettier.getFileInfo.sync(file1, { + resolveConfig: true + }) + ).toMatchObject({ + ignored: false, + inferredParser: "json" + }); + expect( + prettier.getFileInfo.sync(file2, { + resolveConfig: true + }) + ).toMatchObject({ + ignored: false, + inferredParser: "babel" + }); +}); + +test("API getFileInfo.sync with resolveConfig when no config is present", () => { + const file1 = path.resolve( + path.join(__dirname, "../cli/with-resolve-config-no-config/file.foo") + ); + const file2 = path.resolve( + path.join(__dirname, "../cli/with-resolve-config-no-config/file.bar") + ); + + expect(prettier.getFileInfo.sync(file1)).toMatchObject({ + ignored: false, + inferredParser: null + }); + expect(prettier.getFileInfo.sync(file2)).toMatchObject({ + ignored: false, + inferredParser: null + }); + expect( + prettier.getFileInfo.sync(file1, { + resolveConfig: true + }) + ).toMatchObject({ + ignored: false, + inferredParser: null + }); + expect( + prettier.getFileInfo.sync(file2, { + resolveConfig: true + }) + ).toMatchObject({ + ignored: false, + inferredParser: null + }); +}); + test("API getFileInfo with ignorePath", () => { const file = path.resolve( path.join(__dirname, "../cli/ignore-path/regular-module.js") diff --git a/tests_integration/cli/with-resolve-config-no-config/file.bar b/tests_integration/cli/with-resolve-config-no-config/file.bar new file mode 100644 index 00000000..4f4b4c84 --- /dev/null +++ b/tests_integration/cli/with-resolve-config-no-config/file.bar @@ -0,0 +1 @@ +const foo = "bar"; diff --git a/tests_integration/cli/with-resolve-config-no-config/file.foo b/tests_integration/cli/with-resolve-config-no-config/file.foo new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/tests_integration/cli/with-resolve-config-no-config/file.foo @@ -0,0 +1 @@ +{} diff --git a/tests_integration/cli/with-resolve-config/.prettierrc b/tests_integration/cli/with-resolve-config/.prettierrc new file mode 100644 index 00000000..a7d13fff --- /dev/null +++ b/tests_integration/cli/with-resolve-config/.prettierrc @@ -0,0 +1,12 @@ +{ + "overrides": [ + { + "files": "*.foo", + "options": { "parser": "json" } + }, + { + "files": "*.bar", + "options": { "parser": "babel" } + } + ] +} diff --git a/tests_integration/cli/with-resolve-config/file.bar b/tests_integration/cli/with-resolve-config/file.bar new file mode 100644 index 00000000..4f4b4c84 --- /dev/null +++ b/tests_integration/cli/with-resolve-config/file.bar @@ -0,0 +1 @@ +const foo = "bar"; diff --git a/tests_integration/cli/with-resolve-config/file.foo b/tests_integration/cli/with-resolve-config/file.foo new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/tests_integration/cli/with-resolve-config/file.foo @@ -0,0 +1 @@ +{}