From 51202f4b6e4dc88cfa1e8ce38176ccfb077b90fb Mon Sep 17 00:00:00 2001 From: Stephen Scott Date: Mon, 26 Feb 2018 18:47:55 -0700 Subject: [PATCH 1/7] Format 2-26 blog post with prettier --- website/blog/2018-02-26-1.11.0.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/website/blog/2018-02-26-1.11.0.md b/website/blog/2018-02-26-1.11.0.md index ff70747d6059..ef7d40027030 100644 --- a/website/blog/2018-02-26-1.11.0.md +++ b/website/blog/2018-02-26-1.11.0.md @@ -551,6 +551,7 @@ In Prettier 1.10.2, we had a lot of logic to handle formatting of Microsoft-brow #### Don't lowercase nesting selector ([#4048] by [@evilebottnawi]) In Prettier 1.10.2, we were incorrectly lower-casing nesting SCSS selectors: + ```scss // Unformatted code: @@ -567,6 +568,7 @@ In Prettier 1.10.2, we were incorrectly lower-casing nesting SCSS selectors: ``` This has been fixed in Prettier 1.11.0: + ```scss // Formatted code: (Prettier 1.11.0): @@ -633,6 +635,7 @@ Prettier 1.11.0 will now respect the indentation level you set in your markdown, #### Format AMD define calls like CJS require calls ([#3830] by [@salemhilal]) When using AMD modules, one pattern is to use `define` to specify the dependencies of an anonymous module like so: + ```js define([ From 74a132c4ba6e871f2e3b69f786c9082cffafe0b7 Mon Sep 17 00:00:00 2001 From: suchipi Date: Mon, 26 Feb 2018 22:03:56 -0700 Subject: [PATCH 2/7] Bump own prettier dependency version to 1.11.0 (#4058) --- docs/vim.md | 6 +++--- package.json | 2 +- yarn.lock | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/vim.md b/docs/vim.md index f2281081dfc4..861f4cf950a5 100644 --- a/docs/vim.md +++ b/docs/vim.md @@ -77,9 +77,9 @@ When installed via vim-plug, a default prettier executable is installed inside v vim-prettier executable resolution: -1. Traverse parents and search for Prettier installation inside `node_modules` -2. Look for a global prettier installation -3. Use locally installed vim-prettier prettier executable +1. Traverse parents and search for Prettier installation inside `node_modules` +2. Look for a global prettier installation +3. Use locally installed vim-prettier prettier executable ### vim-prettier - Usage diff --git a/package.json b/package.json index ed6ae9403dc5..dc33488f9743 100644 --- a/package.json +++ b/package.json @@ -73,7 +73,7 @@ "eslint-plugin-react": "7.1.0", "jest": "21.1.0", "mkdirp": "0.5.1", - "prettier": "1.10.2", + "prettier": "1.11.0", "prettylint": "1.0.0", "rimraf": "2.6.2", "rollup": "0.47.6", diff --git a/yarn.lock b/yarn.lock index 565a17647cb3..ff7b7c2d4213 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3600,9 +3600,9 @@ preserve@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" -prettier@1.10.2: - version "1.10.2" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.10.2.tgz#1af8356d1842276a99a5b5529c82dd9e9ad3cc93" +prettier@1.11.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.11.0.tgz#c024f70cab158c993f50fc0c25ffe738cb8b0f85" pretty-format@21.3.0-beta.15: version "21.3.0-beta.15" From 23f032f3481bef118c604ef19e74305804e75602 Mon Sep 17 00:00:00 2001 From: Lipis Date: Tue, 27 Feb 2018 13:15:45 +0200 Subject: [PATCH 3/7] Fix @orta's link (#4060) --- website/blog/2018-02-26-1.11.0.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/website/blog/2018-02-26-1.11.0.md b/website/blog/2018-02-26-1.11.0.md index ef7d40027030..dc2f7129c3e7 100644 --- a/website/blog/2018-02-26-1.11.0.md +++ b/website/blog/2018-02-26-1.11.0.md @@ -6,7 +6,7 @@ title: "Prettier 1.11: CSS fixes and new TypeScript feature support" This release features a ton of CSS formatting fixes as well as support for some new TypeScript features, in addition to some general bugfixes for other languages. -Since the last release, the [Prettier website](https://prettier.io) has gotten an all-new design thanks to [@orta]! +Since the last release, the [Prettier website](https://prettier.io) has gotten an all-new design thanks to [@orta](https://github.com/orta)! ### Facebook is 💯% Prettier @@ -1084,7 +1084,6 @@ This is a minor change to the the way `.editorignore` files are handled. Previou Thanks to all of Prettier's contributors and the community for making Prettier a successful and productive open-source project! We couldn't do it without everyone ❤️ [@evilebottnawi]: https://github.com/evilebottnawi -[@orta]: https://github.com/orta [@ikatyang]: https://github.com/ikatyang [@cryrivers]: https://github.com/Cryrivers [@hudochenkov]: https://github.com/hudochenkov From d05a29da05b2084790491eaef85917ce584e4fbd Mon Sep 17 00:00:00 2001 From: Christian Zosel Date: Tue, 27 Feb 2018 14:20:02 +0100 Subject: [PATCH 4/7] Allow plugins to override default options (#3991) * refactor(cli): defer default value applying * Allow plugins to override default options * Move "defaultOptions" to top level of plugin * Simplify implementation * Attach plugin name * Add pluginOptions to cli help * Update snapshots * Code review (immutable style) * Add test for help output * Use snapshot test, fix Object.assign * Refactor to immutable style * Add test case for automatic plugin resolution * Add tests for applying and overriding default opts * Remove "since" option * Only set defaults for CLI args when no pluginDefaults are present * Revert workaround, rebase to #4045 * Add basic documentation for `options` and `defaultOptions` --- docs/plugins.md | 35 +++++++++++++++++- src/cli/minimist.js | 35 ++++++++++++++++++ src/cli/util.js | 22 +++++++---- src/common/load-plugins.js | 2 +- src/common/support.js | 10 +++++ src/main/get-plugin.js | 19 ++++++++++ src/main/get-printer.js | 21 ----------- src/main/options.js | 24 ++++++++++-- .../__snapshots__/early-exit.js.snap | 30 +++++++++++++++ .../__snapshots__/support-info.js.snap | 18 +++++++++ tests_integration/__tests__/early-exit.js | 21 +++++++++++ .../__tests__/plugin-default-options.js | 29 +++++++++++++++ .../node_modules/prettier-plugin-bar/index.js | 3 ++ .../plugins/defaultOptions/.config.json.swp | Bin 0 -> 4096 bytes .../plugins/defaultOptions/config.json | 3 ++ .../plugins/defaultOptions/plugin.js | 26 +++++++++++++ 16 files changed, 263 insertions(+), 35 deletions(-) create mode 100644 src/cli/minimist.js create mode 100644 src/main/get-plugin.js delete mode 100644 src/main/get-printer.js create mode 100644 tests_integration/__tests__/plugin-default-options.js create mode 100644 tests_integration/plugins/defaultOptions/.config.json.swp create mode 100644 tests_integration/plugins/defaultOptions/config.json create mode 100644 tests_integration/plugins/defaultOptions/plugin.js diff --git a/docs/plugins.md b/docs/plugins.md index 9c465ddcbb4b..fda3f59980e1 100644 --- a/docs/plugins.md +++ b/docs/plugins.md @@ -46,7 +46,13 @@ If the plugin is unable to be found automatically, you can load them with: ## Developing Plugins -Prettier plugins are regular JavaScript modules with three exports, `languages`, `parsers` and `printers`. +Prettier plugins are regular JavaScript modules with five exports: + +* `languages` +* `parsers` +* `printers` +* `options` +* `defaultOptions` ### `languages` @@ -149,6 +155,33 @@ function embed( If you don't want to switch to a different parser, simply return `null` or `undefined`. +### `options` + +`options` is an object containing the custom options your plugin supports. + +Example: + +```js +options: { + openingBraceNewLine: { + type: "boolean", + category: "Global", + default: true, + description: "Move open brace for code blocks onto new line." + } +} +``` + +### `defaultOptions` + +If your plugin requires different default values for some of prettier's core options, you can specify them in `defaultOptions`: + +``` +defaultOptions: { + tabWidth: 4 +} +``` + ### Utility functions A `util` module from prettier core is considered a private API and is not meant to be consumed by plugins. Instead, the `util-shared` module provides the following limited set of utility functions for plugins: diff --git a/src/cli/minimist.js b/src/cli/minimist.js new file mode 100644 index 000000000000..aa62b68a6f93 --- /dev/null +++ b/src/cli/minimist.js @@ -0,0 +1,35 @@ +"use strict"; + +const minimist = require("minimist"); + +const PLACEHOLDER = null; + +/** + * unspecified boolean flag without default value is parsed as `undefined` instead of `false` + */ +module.exports = function(args, options) { + const boolean = options.boolean || []; + const defaults = options.default || {}; + + const booleanWithoutDefault = boolean.filter(key => !(key in defaults)); + const newDefaults = Object.assign( + {}, + defaults, + booleanWithoutDefault.reduce( + (reduced, key) => Object.assign(reduced, { [key]: PLACEHOLDER }), + {} + ) + ); + + const parsed = minimist( + args, + Object.assign({}, options, { default: newDefaults }) + ); + + return Object.keys(parsed).reduce((reduced, key) => { + if (parsed[key] !== PLACEHOLDER) { + reduced[key] = parsed[key]; + } + return reduced; + }, {}); +}; diff --git a/src/cli/util.js b/src/cli/util.js index a21531d818a5..4ec80b646992 100644 --- a/src/cli/util.js +++ b/src/cli/util.js @@ -3,7 +3,6 @@ const path = require("path"); const camelCase = require("camelcase"); const dashify = require("dashify"); -const minimist = require("minimist"); const fs = require("fs"); const globby = require("globby"); const ignore = require("ignore"); @@ -11,6 +10,7 @@ const chalk = require("chalk"); const readline = require("readline"); const leven = require("leven"); +const minimist = require("./minimist"); const prettier = require("../../index"); const cleanAST = require("../common/clean-ast").cleanAST; const errors = require("../common/errors"); @@ -228,11 +228,7 @@ function parseArgsToOptions(context, overrideDefaults) { Object.assign({ string: minimistOptions.string, boolean: minimistOptions.boolean, - default: Object.assign( - {}, - cliifyOptions(context.apiDefaultOptions, apiDetailedOptionMap), - cliifyOptions(overrideDefaults, apiDetailedOptionMap) - ) + default: cliifyOptions(overrideDefaults, apiDetailedOptionMap) }) ), context.detailedOptions, @@ -305,7 +301,7 @@ function createIgnorer(context) { } function eachFilename(context, patterns, callback) { - const ignoreNodeModules = context.argv["with-node-modules"] === false; + const ignoreNodeModules = context.argv["with-node-modules"] !== true; if (ignoreNodeModules) { patterns = patterns.concat(["!**/node_modules/**", "!./node_modules/**"]); } @@ -613,7 +609,16 @@ function createDetailedUsage(context, optionName) { ? `\n\nDefault: ${createDefaultValueDisplay(optionDefaultValue)}` : ""; - return `${header}${description}${choices}${defaults}`; + const pluginDefaults = + option.pluginDefaults && Object.keys(option.pluginDefaults).length + ? `\nPlugin defaults:${Object.keys(option.pluginDefaults).map( + key => + `\n* ${key}: ${createDefaultValueDisplay( + option.pluginDefaults[key] + )}` + )}` + : ""; + return `${header}${description}${choices}${defaults}${pluginDefaults}`; } function getOptionDefaultValue(context, optionName) { @@ -743,6 +748,7 @@ function createMinimistOptions(detailedOptions) { .map(option => option.name), default: detailedOptions .filter(option => !option.deprecated) + .filter(option => !option.forwardToApi || option.name === "plugin") .filter(option => option.default !== undefined) .reduce( (current, option) => diff --git a/src/common/load-plugins.js b/src/common/load-plugins.js index 581e5470fa88..b4899784b393 100644 --- a/src/common/load-plugins.js +++ b/src/common/load-plugins.js @@ -30,7 +30,7 @@ function loadPlugins(plugins) { } const pluginPath = resolve.sync(plugin, { basedir: process.cwd() }); - return eval("require")(pluginPath); + return Object.assign({ name: plugin }, eval("require")(pluginPath)); }); return deduplicate(internalPlugins.concat(externalPlugins)); diff --git a/src/common/support.js b/src/common/support.js index 1127ef457e81..1ebee5585760 100644 --- a/src/common/support.js +++ b/src/common/support.js @@ -249,6 +249,16 @@ function getSupportInfo(version, opts) { } return newOption; + }) + .map(option => { + const filteredPlugins = plugins.filter( + plugin => plugin.defaultOptions && plugin.defaultOptions[option.name] + ); + const pluginDefaults = filteredPlugins.reduce((reduced, plugin) => { + reduced[plugin.name] = plugin.defaultOptions[option.name]; + return reduced; + }, {}); + return Object.assign(option, { pluginDefaults }); }); const usePostCssParser = semver.lt(version, "1.7.1"); diff --git a/src/main/get-plugin.js b/src/main/get-plugin.js new file mode 100644 index 000000000000..17e4b7bd4412 --- /dev/null +++ b/src/main/get-plugin.js @@ -0,0 +1,19 @@ +"use strict"; + +function getPlugin(options) { + const astFormat = options.astFormat; + + if (!astFormat) { + throw new Error("getPlugin() requires astFormat to be set"); + } + const printerPlugin = options.plugins.find( + plugin => plugin.printers[astFormat] + ); + if (!printerPlugin) { + throw new Error(`Couldn't find plugin for AST format "${astFormat}"`); + } + + return printerPlugin; +} + +module.exports = getPlugin; diff --git a/src/main/get-printer.js b/src/main/get-printer.js deleted file mode 100644 index cba1b1005dd3..000000000000 --- a/src/main/get-printer.js +++ /dev/null @@ -1,21 +0,0 @@ -"use strict"; - -function getPrinter(options) { - const astFormat = options.astFormat; - - if (!astFormat) { - throw new Error("getPrinter() requires astFormat to be set"); - } - const printerPlugin = options.plugins.find( - plugin => plugin.printers[astFormat] - ); - if (!printerPlugin) { - throw new Error( - `Couldn't find printer plugin for AST format "${astFormat}"` - ); - } - - return printerPlugin.printers[astFormat]; -} - -module.exports = getPrinter; diff --git a/src/main/options.js b/src/main/options.js index a6b037a90401..d285bfe7c6df 100644 --- a/src/main/options.js +++ b/src/main/options.js @@ -5,7 +5,7 @@ const getSupportInfo = require("../common/support").getSupportInfo; const normalizer = require("./options-normalizer"); const loadPlugins = require("../common/load-plugins"); const resolveParser = require("./parser").resolveParser; -const getPrinter = require("./get-printer"); +const getPlugin = require("./get-plugin"); const hiddenDefaults = { astFormat: "estree", @@ -53,11 +53,27 @@ function normalize(options, opts) { rawOptions.astFormat = parser.astFormat; rawOptions.locEnd = parser.locEnd; rawOptions.locStart = parser.locStart; - rawOptions.printer = getPrinter(rawOptions); + const plugin = getPlugin(rawOptions); + rawOptions.printer = plugin.printers[rawOptions.astFormat]; - Object.keys(defaults).forEach(k => { + const pluginDefaults = supportOptions + .filter( + optionInfo => + optionInfo.pluginDefaults && optionInfo.pluginDefaults[plugin.name] + ) + .reduce( + (reduced, optionInfo) => + Object.assign(reduced, { + [optionInfo.name]: optionInfo.pluginDefaults[plugin.name] + }), + {} + ); + + const mixedDefaults = Object.assign({}, defaults, pluginDefaults); + + Object.keys(mixedDefaults).forEach(k => { if (rawOptions[k] == null) { - rawOptions[k] = defaults[k]; + rawOptions[k] = mixedDefaults[k]; } }); diff --git a/tests_integration/__tests__/__snapshots__/early-exit.js.snap b/tests_integration/__tests__/__snapshots__/early-exit.js.snap index e602e3083412..bbe6abca3e9e 100644 --- a/tests_integration/__tests__/__snapshots__/early-exit.js.snap +++ b/tests_integration/__tests__/__snapshots__/early-exit.js.snap @@ -514,6 +514,36 @@ exports[`show detailed usage with --help write (stdout) 1`] = ` exports[`show detailed usage with --help write (write) 1`] = `Array []`; +exports[`show detailed usage with plugin options (automatic resolution) (stderr) 1`] = `""`; + +exports[`show detailed usage with plugin options (automatic resolution) (stdout) 1`] = ` +"--tab-width + + Number of spaces per indentation level. + +Default: 2 +Plugin defaults: +* prettier-plugin-bar: 4 +" +`; + +exports[`show detailed usage with plugin options (automatic resolution) (write) 1`] = `Array []`; + +exports[`show detailed usage with plugin options (manual resolution) (stderr) 1`] = `""`; + +exports[`show detailed usage with plugin options (manual resolution) (stdout) 1`] = ` +"--tab-width + + Number of spaces per indentation level. + +Default: 2 +Plugin defaults: +* ../plugins/automatic/node_modules/prettier-plugin-bar: 4 +" +`; + +exports[`show detailed usage with plugin options (manual resolution) (write) 1`] = `Array []`; + exports[`show usage with --help (stderr) 1`] = `""`; exports[`show usage with --help (stdout) 1`] = ` diff --git a/tests_integration/__tests__/__snapshots__/support-info.js.snap b/tests_integration/__tests__/__snapshots__/support-info.js.snap index 965556595d88..9d13a4548e2e 100644 --- a/tests_integration/__tests__/__snapshots__/support-info.js.snap +++ b/tests_integration/__tests__/__snapshots__/support-info.js.snap @@ -661,6 +661,7 @@ exports[`CLI --support-info (stdout) 1`] = ` \\"description\\": \\"Include parentheses around a sole arrow function parameter.\\", \\"name\\": \\"arrowParens\\", + \\"pluginDefaults\\": {}, \\"since\\": \\"1.9.0\\", \\"type\\": \\"choice\\" }, @@ -670,6 +671,7 @@ exports[`CLI --support-info (stdout) 1`] = ` \\"description\\": \\"Print spaces between brackets.\\", \\"name\\": \\"bracketSpacing\\", \\"oppositeDescription\\": \\"Do not print spaces between brackets.\\", + \\"pluginDefaults\\": {}, \\"since\\": \\"0.0.0\\", \\"type\\": \\"boolean\\" }, @@ -679,6 +681,7 @@ exports[`CLI --support-info (stdout) 1`] = ` \\"description\\": \\"Print (to stderr) where a cursor at the given position would move to after formatting.\\\\nThis option cannot be used with --range-start and --range-end.\\", \\"name\\": \\"cursorOffset\\", + \\"pluginDefaults\\": {}, \\"range\\": { \\"end\\": null, \\"start\\": -1, \\"step\\": 1 }, \\"since\\": \\"1.4.0\\", \\"type\\": \\"int\\" @@ -688,6 +691,7 @@ exports[`CLI --support-info (stdout) 1`] = ` \\"description\\": \\"Specify the input filepath. This will be used to do parser inference.\\", \\"name\\": \\"filepath\\", + \\"pluginDefaults\\": {}, \\"since\\": \\"1.4.0\\", \\"type\\": \\"path\\" }, @@ -697,6 +701,7 @@ exports[`CLI --support-info (stdout) 1`] = ` \\"description\\": \\"Insert @format pragma into file's first docblock comment.\\", \\"name\\": \\"insertPragma\\", + \\"pluginDefaults\\": {}, \\"since\\": \\"1.8.0\\", \\"type\\": \\"boolean\\" }, @@ -705,6 +710,7 @@ exports[`CLI --support-info (stdout) 1`] = ` \\"default\\": false, \\"description\\": \\"Put > on the last line instead of at a new line.\\", \\"name\\": \\"jsxBracketSameLine\\", + \\"pluginDefaults\\": {}, \\"since\\": \\"0.17.0\\", \\"type\\": \\"boolean\\" }, @@ -729,6 +735,7 @@ exports[`CLI --support-info (stdout) 1`] = ` \\"default\\": \\"babylon\\", \\"description\\": \\"Which parser to use.\\", \\"name\\": \\"parser\\", + \\"pluginDefaults\\": {}, \\"since\\": \\"0.0.10\\", \\"type\\": \\"choice\\" }, @@ -739,6 +746,7 @@ exports[`CLI --support-info (stdout) 1`] = ` \\"description\\": \\"Add a plugin. Multiple plugins can be passed as separate \`--plugin\`s.\\", \\"name\\": \\"plugins\\", + \\"pluginDefaults\\": {}, \\"since\\": \\"1.10.0\\", \\"type\\": \\"path\\" }, @@ -747,6 +755,7 @@ exports[`CLI --support-info (stdout) 1`] = ` \\"default\\": 80, \\"description\\": \\"The line length where Prettier will try wrap.\\", \\"name\\": \\"printWidth\\", + \\"pluginDefaults\\": {}, \\"range\\": { \\"end\\": null, \\"start\\": 0, \\"step\\": 1 }, \\"since\\": \\"0.0.0\\", \\"type\\": \\"int\\" @@ -773,6 +782,7 @@ exports[`CLI --support-info (stdout) 1`] = ` \\"default\\": \\"preserve\\", \\"description\\": \\"How to wrap prose. (markdown)\\", \\"name\\": \\"proseWrap\\", + \\"pluginDefaults\\": {}, \\"since\\": \\"1.8.2\\", \\"type\\": \\"choice\\" }, @@ -782,6 +792,7 @@ exports[`CLI --support-info (stdout) 1`] = ` \\"description\\": \\"Format code ending at a given character offset (exclusive).\\\\nThe range will extend forwards to the end of the selected statement.\\\\nThis option cannot be used with --cursor-offset.\\", \\"name\\": \\"rangeEnd\\", + \\"pluginDefaults\\": {}, \\"range\\": { \\"end\\": null, \\"start\\": 0, \\"step\\": 1 }, \\"since\\": \\"1.4.0\\", \\"type\\": \\"int\\" @@ -792,6 +803,7 @@ exports[`CLI --support-info (stdout) 1`] = ` \\"description\\": \\"Format code starting at a given character offset.\\\\nThe range will extend backwards to the start of the first line containing the selected statement.\\\\nThis option cannot be used with --cursor-offset.\\", \\"name\\": \\"rangeStart\\", + \\"pluginDefaults\\": {}, \\"range\\": { \\"end\\": null, \\"start\\": 0, \\"step\\": 1 }, \\"since\\": \\"1.4.0\\", \\"type\\": \\"int\\" @@ -802,6 +814,7 @@ exports[`CLI --support-info (stdout) 1`] = ` \\"description\\": \\"Require either '@prettier' or '@format' to be present in the file's first docblock comment\\\\nin order for it to be formatted.\\", \\"name\\": \\"requirePragma\\", + \\"pluginDefaults\\": {}, \\"since\\": \\"1.7.0\\", \\"type\\": \\"boolean\\" }, @@ -812,6 +825,7 @@ exports[`CLI --support-info (stdout) 1`] = ` \\"name\\": \\"semi\\", \\"oppositeDescription\\": \\"Do not print semicolons, except at the beginning of lines which may need them.\\", + \\"pluginDefaults\\": {}, \\"since\\": \\"1.0.0\\", \\"type\\": \\"boolean\\" }, @@ -820,6 +834,7 @@ exports[`CLI --support-info (stdout) 1`] = ` \\"default\\": false, \\"description\\": \\"Use single quotes instead of double quotes.\\", \\"name\\": \\"singleQuote\\", + \\"pluginDefaults\\": {}, \\"since\\": \\"0.0.0\\", \\"type\\": \\"boolean\\" }, @@ -828,6 +843,7 @@ exports[`CLI --support-info (stdout) 1`] = ` \\"default\\": 2, \\"description\\": \\"Number of spaces per indentation level.\\", \\"name\\": \\"tabWidth\\", + \\"pluginDefaults\\": {}, \\"range\\": { \\"end\\": null, \\"start\\": 0, \\"step\\": 1 }, \\"type\\": \\"int\\" }, @@ -849,6 +865,7 @@ exports[`CLI --support-info (stdout) 1`] = ` \\"default\\": \\"none\\", \\"description\\": \\"Print trailing commas wherever possible when multi-line.\\", \\"name\\": \\"trailingComma\\", + \\"pluginDefaults\\": {}, \\"since\\": \\"0.0.0\\", \\"type\\": \\"choice\\" }, @@ -857,6 +874,7 @@ exports[`CLI --support-info (stdout) 1`] = ` \\"default\\": false, \\"description\\": \\"Indent with tabs instead of spaces.\\", \\"name\\": \\"useTabs\\", + \\"pluginDefaults\\": {}, \\"since\\": \\"1.0.0\\", \\"type\\": \\"boolean\\" } diff --git a/tests_integration/__tests__/early-exit.js b/tests_integration/__tests__/early-exit.js index 0832bdccad6c..25b3609d1724 100644 --- a/tests_integration/__tests__/early-exit.js +++ b/tests_integration/__tests__/early-exit.js @@ -26,6 +26,27 @@ describe(`show detailed usage with --help l (alias)`, () => { }); }); +describe(`show detailed usage with plugin options (automatic resolution)`, () => { + runPrettier("plugins/automatic", [ + "--help", + "tab-width", + "--parser=bar" + ]).test({ + status: 0 + }); +}); + +describe(`show detailed usage with plugin options (manual resolution)`, () => { + runPrettier("cli", [ + "--help", + "tab-width", + "--plugin=../plugins/automatic/node_modules/prettier-plugin-bar", + "--parser=bar" + ]).test({ + status: 0 + }); +}); + commonUtil .arrayify( Object.assign( diff --git a/tests_integration/__tests__/plugin-default-options.js b/tests_integration/__tests__/plugin-default-options.js new file mode 100644 index 000000000000..2a9bad9b8555 --- /dev/null +++ b/tests_integration/__tests__/plugin-default-options.js @@ -0,0 +1,29 @@ +"use strict"; + +const runPrettier = require("../runPrettier"); + +describe("plugin default options should work", () => { + runPrettier( + "plugins/defaultOptions", + ["--stdin-filepath", "example.foo", "--plugin=./plugin"], + { input: "hello-world" } + ).test({ + stdout: "tabWidth:8", + stderr: "", + status: 0, + write: [] + }); +}); + +describe("overriding plugin default options should work", () => { + runPrettier( + "plugins/defaultOptions", + ["--stdin-filepath", "example.foo", "--plugin=./plugin", "--tab-width=4"], + { input: "hello-world" } + ).test({ + stdout: "tabWidth:4", + stderr: "", + status: 0, + write: [] + }); +}); diff --git a/tests_integration/plugins/automatic/node_modules/prettier-plugin-bar/index.js b/tests_integration/plugins/automatic/node_modules/prettier-plugin-bar/index.js index b878e8e3207a..9b4f1157d656 100644 --- a/tests_integration/plugins/automatic/node_modules/prettier-plugin-bar/index.js +++ b/tests_integration/plugins/automatic/node_modules/prettier-plugin-bar/index.js @@ -19,5 +19,8 @@ module.exports = { bar: { print: path => concat(["bar+", path.getValue().text]) } + }, + defaultOptions: { + tabWidth: 4 } }; diff --git a/tests_integration/plugins/defaultOptions/.config.json.swp b/tests_integration/plugins/defaultOptions/.config.json.swp new file mode 100644 index 0000000000000000000000000000000000000000..5a1ea1a99fce9466a8624c539a9e0683c275cd92 GIT binary patch literal 4096 zcmYc?2=nw+FxN9-00IF91{>LusK)jhhU-9qPaY=D}W?o5ZdQoCYW`3T2K~8CUW?r#=egTMEte>2pmzJ5X zmsOlk$SwHnAC(&ofe{-5r6p;)7Q76`MurBUFi=)fR1g*l9kIbN>haMK7!85Z5Eu=C U(GVC7fzc2c4S~@R7>OYO0QbKwasU7T literal 0 HcmV?d00001 diff --git a/tests_integration/plugins/defaultOptions/config.json b/tests_integration/plugins/defaultOptions/config.json new file mode 100644 index 000000000000..37ed1cfadc87 --- /dev/null +++ b/tests_integration/plugins/defaultOptions/config.json @@ -0,0 +1,3 @@ +{ + "plugins": ["./plugin"] +} diff --git a/tests_integration/plugins/defaultOptions/plugin.js b/tests_integration/plugins/defaultOptions/plugin.js new file mode 100644 index 000000000000..ba094ac7a404 --- /dev/null +++ b/tests_integration/plugins/defaultOptions/plugin.js @@ -0,0 +1,26 @@ +"use strict"; + +module.exports = { + languages: [ + { + name: "foo", + parsers: ["foo-parser"], + extensions: [".foo"] + } + ], + defaultOptions: { + tabWidth: 8 + }, + parsers: { + "foo-parser": { + parse: text => ({ text }), + astFormat: "foo-ast" + } + }, + printers: { + "foo-ast": { + print: (path, options) => + options.tabWidth ? `tabWidth:${options.tabWidth}` : path.getValue().text + } + } +}; From 0ce4ce31385e95fd2da32c72031bb35f9fc60db0 Mon Sep 17 00:00:00 2001 From: Ika Date: Thu, 1 Mar 2018 00:14:30 +0800 Subject: [PATCH 5/7] fix(api): no regression for deprecated parser (#4072) --- src/main/options.js | 15 +++++++++-- .../__snapshots__/deprecated-parser.js.snap | 6 +++++ .../__tests__/deprecated-parser.js | 26 +++++++++++++++++++ 3 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 tests_integration/__tests__/__snapshots__/deprecated-parser.js.snap create mode 100644 tests_integration/__tests__/deprecated-parser.js diff --git a/src/main/options.js b/src/main/options.js index d285bfe7c6df..da786dbd528c 100644 --- a/src/main/options.js +++ b/src/main/options.js @@ -26,7 +26,8 @@ function normalize(options, opts) { const supportOptions = getSupportInfo(null, { plugins, pluginsLoaded: true, - showUnreleased: true + showUnreleased: true, + showDeprecated: true }).options; const defaults = supportOptions.reduce( (reduced, optionInfo) => @@ -49,10 +50,20 @@ function normalize(options, opts) { } } - const parser = resolveParser(rawOptions); + const parser = resolveParser( + !rawOptions.parser + ? rawOptions + : // handle deprecated parsers + normalizer.normalizeApiOptions( + rawOptions, + [supportOptions.find(x => x.name === "parser")], + { passThrough: true, logger: false } + ) + ); rawOptions.astFormat = parser.astFormat; rawOptions.locEnd = parser.locEnd; rawOptions.locStart = parser.locStart; + const plugin = getPlugin(rawOptions); rawOptions.printer = plugin.printers[rawOptions.astFormat]; diff --git a/tests_integration/__tests__/__snapshots__/deprecated-parser.js.snap b/tests_integration/__tests__/__snapshots__/deprecated-parser.js.snap new file mode 100644 index 000000000000..beb62c7a8536 --- /dev/null +++ b/tests_integration/__tests__/__snapshots__/deprecated-parser.js.snap @@ -0,0 +1,6 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`API format with deprecated parser should work 1`] = ` +"\`{ \\"parser\\": \\"postcss\\" }\` is deprecated. Prettier now treats it as \`{ \\"parser\\": \\"css\\" }\`. +" +`; diff --git a/tests_integration/__tests__/deprecated-parser.js b/tests_integration/__tests__/deprecated-parser.js new file mode 100644 index 000000000000..96e111fb35ee --- /dev/null +++ b/tests_integration/__tests__/deprecated-parser.js @@ -0,0 +1,26 @@ +"use strict"; + +const prettier = require("../../tests_config/require_prettier"); + +let warnings = ""; + +beforeAll(() => { + jest + .spyOn(console, "warn") + .mockImplementation(text => (warnings += text + "\n")); +}); + +beforeEach(() => { + warnings = ""; +}); + +afterAll(() => { + jest.restoreAllMocks(); +}); + +test("API format with deprecated parser should work", () => { + expect(() => + prettier.format("body { color: #131313; }", { parser: "postcss" }) + ).not.toThrowError(); + expect(warnings).toMatchSnapshot(); +}); From 2897c950f842f46aaebed424f3ec3d4caa930326 Mon Sep 17 00:00:00 2001 From: Simon Lydell Date: Wed, 28 Feb 2018 18:53:08 +0100 Subject: [PATCH 6/7] Try to clarify when to use the issue template (#4059) --- .github/ISSUE_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index c42b094755dd..db2156688f12 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,4 +1,4 @@ - -**Prettier 1.11.0** +**Prettier 1.11.1** [Playground link](https://prettier.io/playground/#.....) ```sh # Options (if any): diff --git a/CHANGELOG.md b/CHANGELOG.md index 59df32a833df..f8d905e523ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 1.11.1 + +[link](https://github.com/prettier/prettier/compare/1.11.0...1.11.1) + +* 1.11.0 was incorrectly shipped with the wrong version of the TypeScript parser, which broke conditional types. This release fixes it. + # 1.11.0 * [Release Notes](https://prettier.io/blog/2018/02/26/1.11.0.html) diff --git a/package.json b/package.json index dc33488f9743..5509e0325185 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prettier", - "version": "1.11.0", + "version": "1.11.1", "description": "Prettier is an opinionated code formatter", "bin": { "prettier": "./bin/prettier.js"