Remove plugin search feature (#14759)
Co-authored-by: SUZUKI Sosuke <aosukeke@gmail.com>
This commit is contained in:
1 parent
fbd82cf774
commit
54404fc96f
36 files changed
+35
-638
No files matched your search
@@ -0,0 +1,7 @@
|
||||
#### [Breaking] plugin search feature has been removed (#14759 by @fisker)
|
||||
|
||||
The plugin auto search feature didn't work well when using pnpm, and cause slowness.
|
||||
|
||||
`--plugin-search-dir`, `--no-plugin-search` flags for CLI and `pluginSearchDirs` in API options has been removed in Prettier main.
|
||||
|
||||
`--plugin` flag and `plugins` option should be used instead, see [documentation](https://prettier.io/docs/en/plugins.html#using-plugins).
|
||||
@@ -204,10 +204,6 @@ prettier "**/*" --write --ignore-unknown
|
||||
|
||||
Prevent errors when pattern is unmatched.
|
||||
|
||||
## `--no-plugin-search`
|
||||
|
||||
Disable plugin autoloading.
|
||||
|
||||
## `--cache`
|
||||
|
||||
If this option is enabled, the following values are used as cache keys and the file is formatted only if one of them is changed.
|
||||
|
||||
+6
-18
@@ -7,26 +7,21 @@ Plugins are ways of adding new languages or formatting rules to Prettier. Pretti
|
||||
|
||||
## Using Plugins
|
||||
|
||||
Plugins are automatically loaded if you have them installed in the same `node_modules` directory where `prettier` is located. Plugin package names must start with `@prettier/plugin-` or `prettier-plugin-` or `@<scope>/prettier-plugin-` to be registered.
|
||||
You can load plugins with:
|
||||
|
||||
> `<scope>` should be replaced by a name, read more about [NPM scope](https://docs.npmjs.com/misc/scope.html).
|
||||
|
||||
When plugins cannot be found automatically, you can load them with:
|
||||
|
||||
- The [CLI](cli.md), via `--plugin-search-dir` and `--plugin`:
|
||||
- The [CLI](cli.md), via `--plugin`:
|
||||
|
||||
```bash
|
||||
prettier --write main.foo --plugin-search-dir=./dir-with-plugins --plugin=prettier-plugin-foo
|
||||
prettier --write main.foo --plugin=prettier-plugin-foo
|
||||
```
|
||||
|
||||
> Tip: You can set `--plugin-search-dir` or `--plugin` options multiple times.
|
||||
> Tip: You can set `--plugin` options multiple times.
|
||||
|
||||
- The [API](api.md), via the `pluginSearchDirs` and `plugins` options:
|
||||
- The [API](api.md), via the `plugins` options:
|
||||
|
||||
```js
|
||||
await prettier.format("code", {
|
||||
parser: "foo",
|
||||
pluginSearchDirs: ["./dir-with-plugins"],
|
||||
plugins: ["prettier-plugin-foo"],
|
||||
});
|
||||
```
|
||||
@@ -35,18 +30,11 @@ When plugins cannot be found automatically, you can load them with:
|
||||
|
||||
```json
|
||||
{
|
||||
"pluginSearchDirs": ["./dir-with-plugins"],
|
||||
"plugins": ["prettier-plugin-foo"]
|
||||
}
|
||||
```
|
||||
|
||||
`pluginSearchDirs` and `plugins` are independent and one does not require the other.
|
||||
|
||||
The paths that are provided to `pluginSearchDirs` will be searched for `@prettier/plugin-*`, `prettier-plugin-*`, and `@*/prettier-plugin-*`. For instance, these can be your project directory, a `node_modules` directory, the location of global npm modules, or any arbitrary directory that contains plugins.
|
||||
|
||||
Strings provided to `plugins` are ultimately passed to `require()`, so you can provide a module/package name, a path, or anything else `require()` takes. (`pluginSearchDirs` works the same way. That is, valid plugin paths that it finds are passed to `require()`.)
|
||||
|
||||
To turn off plugin autoloading, use `--no-plugin-search` when using Prettier CLI or add `{ pluginSearchDirs: false }` to options in `prettier.format()` or to the config file.
|
||||
Strings provided to `plugins` are ultimately passed to [`import()` expression](https://nodejs.org/api/esm.html#import-expressions), so you can provide a module/package name, a path, or anything else `import()` takes.
|
||||
|
||||
## Official Plugins
|
||||
|
||||
|
||||
@@ -80,19 +80,6 @@ function optionToSchema(option) {
|
||||
}
|
||||
if (option.array) {
|
||||
schema = wrapWithArraySchema(schema);
|
||||
|
||||
// #10274
|
||||
if (option.name === "pluginSearchDirs") {
|
||||
schema = {
|
||||
oneOf: [
|
||||
schema,
|
||||
{
|
||||
enum: [false],
|
||||
description: "Disable plugin autoloading.",
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
}
|
||||
return {
|
||||
description: option.description,
|
||||
|
||||
@@ -220,10 +220,6 @@ const options = {
|
||||
description: "What level of logs to report.",
|
||||
type: "choice",
|
||||
},
|
||||
pluginSearch: {
|
||||
oppositeDescription: "Disable plugin autoloading.",
|
||||
type: "boolean",
|
||||
},
|
||||
supportInfo: {
|
||||
description: "Print support information as JSON.",
|
||||
type: "boolean",
|
||||
|
||||
+6
-9
@@ -29,13 +29,11 @@ class Context {
|
||||
async init() {
|
||||
const { rawArguments, logger } = this;
|
||||
|
||||
const { plugins, pluginSearchDirs } = parseArgvWithoutPlugins(
|
||||
rawArguments,
|
||||
logger,
|
||||
["plugin", "plugin-search-dir"]
|
||||
);
|
||||
const { plugins } = parseArgvWithoutPlugins(rawArguments, logger, [
|
||||
"plugin",
|
||||
]);
|
||||
|
||||
await this.pushContextPlugins(plugins, pluginSearchDirs);
|
||||
await this.pushContextPlugins(plugins);
|
||||
|
||||
const argv = parseArgv(rawArguments, this.detailedOptions, logger);
|
||||
this.argv = argv;
|
||||
@@ -44,10 +42,9 @@ class Context {
|
||||
|
||||
/**
|
||||
* @param {string[]} plugins
|
||||
* @param {string[]=} pluginSearchDirs
|
||||
*/
|
||||
async pushContextPlugins(plugins, pluginSearchDirs) {
|
||||
const options = await getContextOptions(plugins, pluginSearchDirs);
|
||||
async pushContextPlugins(plugins) {
|
||||
const options = await getContextOptions(plugins);
|
||||
this.#stack.push(options);
|
||||
Object.assign(this, options);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ async function logFileInfoOrDie(context) {
|
||||
ignorePath,
|
||||
withNodeModules,
|
||||
plugins,
|
||||
pluginSearchDirs,
|
||||
config,
|
||||
} = context.argv;
|
||||
|
||||
@@ -16,7 +15,6 @@ async function logFileInfoOrDie(context) {
|
||||
ignorePath,
|
||||
withNodeModules,
|
||||
plugins,
|
||||
pluginSearchDirs,
|
||||
resolveConfig: config !== false,
|
||||
});
|
||||
|
||||
|
||||
+1
-13
@@ -6,7 +6,7 @@ import { createDetailedUsage, createUsage } from "./usage.js";
|
||||
import { formatStdin, formatFiles } from "./format.js";
|
||||
import logFileInfoOrDie from "./file-info.js";
|
||||
import logResolvedConfigPathOrDie from "./find-config-path.js";
|
||||
import { printToScreen, isNonEmptyArray } from "./utils.js";
|
||||
import { printToScreen } from "./utils.js";
|
||||
import printSupportInfo from "./print-support-info.js";
|
||||
|
||||
async function run(rawArguments) {
|
||||
@@ -38,18 +38,6 @@ async function run(rawArguments) {
|
||||
async function main(context) {
|
||||
context.logger.debug(`normalized argv: ${JSON.stringify(context.argv)}`);
|
||||
|
||||
if (context.argv.pluginSearch === false) {
|
||||
const rawPluginSearchDirs = context.argv.__raw["plugin-search-dir"];
|
||||
if (
|
||||
typeof rawPluginSearchDirs === "string" ||
|
||||
isNonEmptyArray(rawPluginSearchDirs)
|
||||
) {
|
||||
throw new Error(
|
||||
"Cannot use --no-plugin-search and --plugin-search-dir together."
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (context.argv.check && context.argv.listDifferent) {
|
||||
throw new Error("Cannot use --check and --list-different together.");
|
||||
}
|
||||
|
||||
@@ -13,9 +13,7 @@ export default function createMinimistOptions(detailedOptions) {
|
||||
|
||||
if (
|
||||
!option.deprecated &&
|
||||
(!option.forwardToApi ||
|
||||
name === "plugin" ||
|
||||
name === "plugin-search-dir") &&
|
||||
(!option.forwardToApi || name === "plugin") &&
|
||||
option.default !== undefined
|
||||
) {
|
||||
defaultValues[option.name] = option.default;
|
||||
|
||||
@@ -64,11 +64,10 @@ function supportInfoToContextOptions({ options: supportOptions, languages }) {
|
||||
};
|
||||
}
|
||||
|
||||
async function getContextOptions(plugins, pluginSearchDirs) {
|
||||
async function getContextOptions(plugins) {
|
||||
const supportInfo = await getSupportInfo({
|
||||
showDeprecated: true,
|
||||
plugins,
|
||||
pluginSearchDirs,
|
||||
});
|
||||
|
||||
return supportInfoToContextOptions(supportInfo);
|
||||
|
||||
@@ -10,10 +10,6 @@ function parseArgv(rawArguments, detailedOptions, logger, keys) {
|
||||
let argv = minimist(rawArguments, minimistOptions);
|
||||
|
||||
if (keys) {
|
||||
if (keys.includes("plugin-search-dir") && !keys.includes("plugin-search")) {
|
||||
keys.push("plugin-search");
|
||||
}
|
||||
|
||||
detailedOptions = detailedOptions.filter((option) =>
|
||||
keys.includes(option.name)
|
||||
);
|
||||
@@ -26,8 +22,7 @@ function parseArgv(rawArguments, detailedOptions, logger, keys) {
|
||||
...Object.fromEntries(
|
||||
Object.entries(normalized).map(([key, value]) => {
|
||||
const option = detailedOptions.find(({ name }) => name === key) || {};
|
||||
// If the flag is a prettier option, use the option name
|
||||
// `--plugin-search-dir` -> `pluginSearchDirs`
|
||||
// If the flag is a prettier api option, use the option name
|
||||
// Otherwise use camel case for readability
|
||||
// `--ignore-unknown` -> `ignoreUnknown`
|
||||
return [option.forwardToApi || camelCase(key), value];
|
||||
|
||||
@@ -49,14 +49,12 @@ async function resolveConfig(filePath, options) {
|
||||
...mergeOverrides(result, filePath),
|
||||
};
|
||||
|
||||
for (const optionName of ["plugins", "pluginSearchDirs"]) {
|
||||
if (Array.isArray(merged[optionName])) {
|
||||
merged[optionName] = merged[optionName].map((value) =>
|
||||
typeof value === "string" && value.startsWith(".") // relative path
|
||||
? path.resolve(path.dirname(result.filepath), value)
|
||||
: value
|
||||
);
|
||||
}
|
||||
if (Array.isArray(merged.plugins)) {
|
||||
merged.plugins = merged.plugins.map((value) =>
|
||||
typeof value === "string" && value.startsWith(".") // relative path
|
||||
? path.resolve(path.dirname(result.filepath), value)
|
||||
: value
|
||||
);
|
||||
}
|
||||
|
||||
return merged;
|
||||
|
||||
Vendored
-4
@@ -405,10 +405,6 @@ export interface RequiredOptions extends doc.printer.Options {
|
||||
* Provide ability to support new languages to prettier.
|
||||
*/
|
||||
plugins: Array<string | Plugin>;
|
||||
/**
|
||||
* Specify plugin directory paths to search for plugins if not installed in the same `node_modules` where prettier is located.
|
||||
*/
|
||||
pluginSearchDirs: string[] | false;
|
||||
/**
|
||||
* How to handle whitespaces in HTML.
|
||||
* @default "css"
|
||||
|
||||
+2
-5
@@ -1,4 +1,5 @@
|
||||
import vnopts from "vnopts";
|
||||
// "fast-glob" is bundled here since the API uses `micromatch` too
|
||||
import fastGlob from "fast-glob";
|
||||
import * as core from "./main/core.js";
|
||||
import {
|
||||
@@ -9,7 +10,6 @@ import getFileInfoWithoutPlugins from "./common/get-file-info.js";
|
||||
import {
|
||||
loadBuiltinPlugins,
|
||||
loadPlugins,
|
||||
searchPlugins,
|
||||
clearCache as clearPluginCache,
|
||||
} from "./main/plugins/index.js";
|
||||
import {
|
||||
@@ -37,7 +37,7 @@ function withPlugins(
|
||||
) {
|
||||
return async (...args) => {
|
||||
const options = args[optionsArgumentIndex] ?? {};
|
||||
const { plugins = [], pluginSearchDirs } = options;
|
||||
const { plugins = [] } = options;
|
||||
|
||||
args[optionsArgumentIndex] = {
|
||||
...options,
|
||||
@@ -46,9 +46,6 @@ function withPlugins(
|
||||
loadBuiltinPlugins(),
|
||||
// TODO: standalone version allow `plugins` to be `prettierPlugins` which is an object, should allow that too
|
||||
loadPlugins(plugins),
|
||||
options.pluginSearchDirs === false
|
||||
? []
|
||||
: searchPlugins(pluginSearchDirs),
|
||||
])
|
||||
).flat(),
|
||||
};
|
||||
|
||||
@@ -145,21 +145,6 @@ const options = {
|
||||
cliName: "plugin",
|
||||
cliCategory: CATEGORY_CONFIG,
|
||||
},
|
||||
pluginSearchDirs: {
|
||||
type: "path",
|
||||
array: true,
|
||||
default: [{ value: [] }],
|
||||
category: CATEGORY_GLOBAL,
|
||||
description: outdent`
|
||||
Custom directory that contains prettier plugins in node_modules subdirectory.
|
||||
Overrides default behavior when plugins are searched relatively to the location of Prettier.
|
||||
Multiple values are accepted.
|
||||
`,
|
||||
exception: (value) =>
|
||||
typeof value === "string" || typeof value === "object",
|
||||
cliName: "plugin-search-dir",
|
||||
cliCategory: CATEGORY_CONFIG,
|
||||
},
|
||||
printWidth: {
|
||||
category: CATEGORY_GLOBAL,
|
||||
type: "int",
|
||||
|
||||
@@ -72,10 +72,6 @@ function normalizeOptions(
|
||||
hasDeprecationWarned = normalizer._hasDeprecationWarned;
|
||||
}
|
||||
|
||||
if (isCLI && normalized["plugin-search"] === false) {
|
||||
normalized["plugin-search-dir"] = false;
|
||||
}
|
||||
|
||||
return normalized;
|
||||
}
|
||||
|
||||
@@ -117,32 +113,6 @@ function optionInfosToSchemas(optionInfos, { isCLI, FlagSchema }) {
|
||||
function optionInfoToSchema(optionInfo, { isCLI, optionInfos, FlagSchema }) {
|
||||
const { name } = optionInfo;
|
||||
|
||||
if (name === "plugin-search-dir" || name === "pluginSearchDirs") {
|
||||
return vnopts.AnySchema.create({
|
||||
// @ts-expect-error
|
||||
name,
|
||||
preprocess(value) {
|
||||
if (value === false) {
|
||||
return value;
|
||||
}
|
||||
value = Array.isArray(value) ? value : [value];
|
||||
return value;
|
||||
},
|
||||
/**
|
||||
* @param {Array<unknown> | false} value
|
||||
*/
|
||||
validate(value) {
|
||||
if (value === false) {
|
||||
return true;
|
||||
}
|
||||
return value.every((dir) => typeof dir === "string");
|
||||
},
|
||||
expected() {
|
||||
return "false or paths to plugin search dir";
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const parameters = { name };
|
||||
let SchemaConstructor;
|
||||
const handlers = {};
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
import { clearCache as clearPluginLoadCache } from "./load-plugin.js";
|
||||
import { clearCache as clearPluginSearchCache } from "./search-plugins.js";
|
||||
|
||||
export function clearCache() {
|
||||
clearPluginLoadCache();
|
||||
clearPluginSearchCache();
|
||||
}
|
||||
export { clearCache } from "./load-plugin.js";
|
||||
export { default as loadBuiltinPlugins } from "./load-builtin-plugins.js";
|
||||
export { default as loadPlugins } from "./load-plugins.js";
|
||||
export { searchPlugins } from "./search-plugins.js";
|
||||
@@ -1,76 +0,0 @@
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import mem, { memClear } from "mem";
|
||||
import fastGlob from "fast-glob";
|
||||
import isDirectory from "../../utils/is-directory.js";
|
||||
import mockable from "../../common/mockable.js";
|
||||
import { loadPluginFromDirectory } from "./load-plugin.js";
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
const findNodeModules = mem((directory) =>
|
||||
mockable.findParentDir(directory, "node_modules")
|
||||
);
|
||||
|
||||
const findPluginsInNodeModules = mem(async (nodeModulesDir) => {
|
||||
const pluginPackageJsonPaths = await fastGlob(
|
||||
[
|
||||
"prettier-plugin-*/package.json",
|
||||
"@*/prettier-plugin-*/package.json",
|
||||
"@prettier/plugin-*/package.json",
|
||||
],
|
||||
{
|
||||
cwd: nodeModulesDir,
|
||||
}
|
||||
);
|
||||
return pluginPackageJsonPaths.map(path.dirname);
|
||||
});
|
||||
|
||||
const searchPluginsInDirectory = mem(async (directory) => {
|
||||
const absolutePath = path.resolve(process.cwd(), directory);
|
||||
const nodeModulesDir = path.join(absolutePath, "node_modules");
|
||||
|
||||
// In some fringe cases (ex: files "mounted" as virtual directories), the
|
||||
// isDirectory(absolutePath) check might be false even though
|
||||
// the node_modules actually exists.
|
||||
if (
|
||||
!(await isDirectory(nodeModulesDir)) &&
|
||||
!(await isDirectory(absolutePath))
|
||||
) {
|
||||
throw new Error(`${directory} does not exist or is not a directory`);
|
||||
}
|
||||
|
||||
const pluginNames = await findPluginsInNodeModules(nodeModulesDir);
|
||||
|
||||
return Promise.all(
|
||||
pluginNames.map((name) => loadPluginFromDirectory(name, nodeModulesDir))
|
||||
);
|
||||
});
|
||||
|
||||
const searchPlugins = mem(
|
||||
async (directories = []) => {
|
||||
// unless pluginSearchDirs are provided, auto-load plugins from node_modules that are parent to Prettier
|
||||
if (directories.length === 0) {
|
||||
const nodeModulesDirectory = findNodeModules(__dirname);
|
||||
if (nodeModulesDirectory) {
|
||||
directories = [nodeModulesDirectory];
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
await Promise.all(
|
||||
directories.map((directory) => searchPluginsInDirectory(directory))
|
||||
)
|
||||
).flat();
|
||||
},
|
||||
{ cacheKey: JSON.stringify }
|
||||
);
|
||||
|
||||
function clearCache() {
|
||||
memClear(searchPlugins);
|
||||
memClear(searchPluginsInDirectory);
|
||||
memClear(findPluginsInNodeModules);
|
||||
memClear(findNodeModules);
|
||||
}
|
||||
|
||||
export { searchPlugins, clearCache };
|
||||
+1
-2
@@ -6,11 +6,10 @@ import coreOptions from "./core-options.evaluate.js";
|
||||
*/
|
||||
|
||||
/**
|
||||
* Strings in `plugins` and `pluginSearchDirs` are handled by a wrapped version
|
||||
* Strings in `plugins` are handled by a wrapped version
|
||||
* of this function created by `withPlugins`. Don't pass them here directly.
|
||||
* @param {object} param0
|
||||
* @param {(string | object)[]=} param0.plugins Strings are resolved by `withPlugins`.
|
||||
* @param {string[]=} param0.pluginSearchDirs Added by `withPlugins`.
|
||||
* @param {boolean=} param0.showDeprecated
|
||||
* @return {{ languages: Array<any>, options: Array<NamedOptionInfo> }}
|
||||
*/
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
import fs from "node:fs/promises";
|
||||
|
||||
async function isDirectory(directory) {
|
||||
let stat;
|
||||
|
||||
try {
|
||||
stat = await fs.stat(directory);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
|
||||
return stat.isDirectory();
|
||||
}
|
||||
|
||||
export default isDirectory;
|
||||
@@ -265,8 +265,6 @@ function runSpec(fixtures, parsers, options) {
|
||||
describe(title, () => {
|
||||
const formatOptions = {
|
||||
printWidth: 80,
|
||||
// Should not search plugins by default
|
||||
pluginSearchDirs: false,
|
||||
...options,
|
||||
filepath: filename,
|
||||
parser,
|
||||
|
||||
@@ -23,15 +23,10 @@ function printOptions(options) {
|
||||
filepath,
|
||||
errors,
|
||||
parser,
|
||||
pluginSearchDirs,
|
||||
|
||||
...snapshotOptions
|
||||
} = options;
|
||||
|
||||
if (pluginSearchDirs !== false) {
|
||||
snapshotOptions.pluginSearchDirs = pluginSearchDirs;
|
||||
}
|
||||
|
||||
const keys = Object.keys(snapshotOptions).sort();
|
||||
return keys
|
||||
.map((key) => `${key}: ${stringify(snapshotOptions[key])}`)
|
||||
|
||||
@@ -34,27 +34,6 @@ prettier.doc.builders.cursor;
|
||||
prettier.doc.builders.cursor.type;
|
||||
prettier.doc.builders.cursor.placeholder;
|
||||
|
||||
prettier.format("pluginSearchDir is empty", {
|
||||
pluginSearchDirs: [],
|
||||
});
|
||||
|
||||
prettier.format("pluginSearchDir is not empty", {
|
||||
pluginSearchDirs: ["/a", "/b"],
|
||||
});
|
||||
|
||||
prettier.format("pluginSearchDir is not empty and mixed with weird stuff", {
|
||||
pluginSearchDirs: ["c", "d", ""],
|
||||
});
|
||||
|
||||
prettier.format("pluginSearchDir is false", {
|
||||
pluginSearchDirs: false,
|
||||
});
|
||||
|
||||
prettier.format("pluginSearchDir can not be true", {
|
||||
// @ts-expect-error
|
||||
pluginSearchDirs: true,
|
||||
});
|
||||
|
||||
prettier.format("singleAttributePerLine is available", {
|
||||
singleAttributePerLine: true,
|
||||
});
|
||||
@@ -10,21 +10,6 @@ exports[`show detailed usage with --help l (alias) (stdout) 1`] = `
|
||||
|
||||
exports[`show detailed usage with --help l (alias) (write) 1`] = `[]`;
|
||||
|
||||
exports[`show detailed usage with plugin options (automatic resolution) (stderr) 1`] = `""`;
|
||||
|
||||
exports[`show detailed usage with plugin options (automatic resolution) (stdout) 1`] = `
|
||||
"--tab-width <int>
|
||||
|
||||
Number of spaces per indentation level.
|
||||
|
||||
Default: 2
|
||||
Plugin defaults:
|
||||
* prettier-plugin-bar: 4
|
||||
* prettier-plugin-baz.js: 4"
|
||||
`;
|
||||
|
||||
exports[`show detailed usage with plugin options (automatic resolution) (write) 1`] = `[]`;
|
||||
|
||||
exports[`show detailed usage with plugin options (manual resolution) (stderr) 1`] = `""`;
|
||||
|
||||
exports[`show detailed usage with plugin options (manual resolution) (stdout) 1`] = `
|
||||
@@ -115,11 +100,6 @@ Config options:
|
||||
Defaults to [.gitignore, .prettierignore].
|
||||
--plugin <path> Add a plugin. Multiple plugins can be passed as separate \`--plugin\`s.
|
||||
Defaults to [].
|
||||
--plugin-search-dir <path>
|
||||
Custom directory that contains prettier plugins in node_modules subdirectory.
|
||||
Overrides default behavior when plugins are searched relatively to the location of Prettier.
|
||||
Multiple values are accepted.
|
||||
Defaults to [].
|
||||
--with-node-modules Process files inside 'node_modules' directory.
|
||||
|
||||
Editor options:
|
||||
@@ -157,7 +137,6 @@ Other options:
|
||||
--log-level <silent|error|warn|log|debug>
|
||||
What level of logs to report.
|
||||
Defaults to log.
|
||||
--no-plugin-search Disable plugin autoloading.
|
||||
--require-pragma Require either '@prettier' or '@format' to be present in the file's first docblock comment
|
||||
in order for it to be formatted.
|
||||
Defaults to false.
|
||||
@@ -286,11 +265,6 @@ Config options:
|
||||
Defaults to [.gitignore, .prettierignore].
|
||||
--plugin <path> Add a plugin. Multiple plugins can be passed as separate \`--plugin\`s.
|
||||
Defaults to [].
|
||||
--plugin-search-dir <path>
|
||||
Custom directory that contains prettier plugins in node_modules subdirectory.
|
||||
Overrides default behavior when plugins are searched relatively to the location of Prettier.
|
||||
Multiple values are accepted.
|
||||
Defaults to [].
|
||||
--with-node-modules Process files inside 'node_modules' directory.
|
||||
|
||||
Editor options:
|
||||
@@ -328,7 +302,6 @@ Other options:
|
||||
--log-level <silent|error|warn|log|debug>
|
||||
What level of logs to report.
|
||||
Defaults to log.
|
||||
--no-plugin-search Disable plugin autoloading.
|
||||
--require-pragma Require either '@prettier' or '@format' to be present in the file's first docblock comment
|
||||
in order for it to be formatted.
|
||||
Defaults to false.
|
||||
|
||||
@@ -72,24 +72,6 @@ exports[`extracts file-info with inferredParser=foo when a plugin is hand-picked
|
||||
|
||||
exports[`extracts file-info with inferredParser=foo when a plugin is hand-picked (write) 1`] = `[]`;
|
||||
|
||||
exports[`extracts file-info with inferredParser=foo when plugins are autoloaded (stderr) 1`] = `""`;
|
||||
|
||||
exports[`extracts file-info with inferredParser=foo when plugins are autoloaded (stdout) 1`] = `
|
||||
"{ "ignored": false, "inferredParser": "foo" }
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`extracts file-info with inferredParser=foo when plugins are autoloaded (write) 1`] = `[]`;
|
||||
|
||||
exports[`extracts file-info with inferredParser=foo when plugins are loaded with --plugin-search-dir (stderr) 1`] = `""`;
|
||||
|
||||
exports[`extracts file-info with inferredParser=foo when plugins are loaded with --plugin-search-dir (stdout) 1`] = `
|
||||
"{ "ignored": false, "inferredParser": "foo" }
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`extracts file-info with inferredParser=foo when plugins are loaded with --plugin-search-dir (write) 1`] = `[]`;
|
||||
|
||||
exports[`extracts file-info with inferredParser=null for file.foo (stderr) 1`] = `""`;
|
||||
|
||||
exports[`extracts file-info with inferredParser=null for file.foo (stdout) 1`] = `
|
||||
|
||||
@@ -370,16 +370,6 @@ exports[`show detailed usage with --help no-error-on-unmatched-pattern (stdout)
|
||||
|
||||
exports[`show detailed usage with --help no-error-on-unmatched-pattern (write) 1`] = `[]`;
|
||||
|
||||
exports[`show detailed usage with --help no-plugin-search (stderr) 1`] = `""`;
|
||||
|
||||
exports[`show detailed usage with --help no-plugin-search (stdout) 1`] = `
|
||||
"--no-plugin-search
|
||||
|
||||
Disable plugin autoloading."
|
||||
`;
|
||||
|
||||
exports[`show detailed usage with --help no-plugin-search (write) 1`] = `[]`;
|
||||
|
||||
exports[`show detailed usage with --help no-semi (stderr) 1`] = `""`;
|
||||
|
||||
exports[`show detailed usage with --help no-semi (stdout) 1`] = `
|
||||
@@ -438,20 +428,6 @@ Default: []"
|
||||
|
||||
exports[`show detailed usage with --help plugin (write) 1`] = `[]`;
|
||||
|
||||
exports[`show detailed usage with --help plugin-search-dir (stderr) 1`] = `""`;
|
||||
|
||||
exports[`show detailed usage with --help plugin-search-dir (stdout) 1`] = `
|
||||
"--plugin-search-dir <path>
|
||||
|
||||
Custom directory that contains prettier plugins in node_modules subdirectory.
|
||||
Overrides default behavior when plugins are searched relatively to the location of Prettier.
|
||||
Multiple values are accepted.
|
||||
|
||||
Default: []"
|
||||
`;
|
||||
|
||||
exports[`show detailed usage with --help plugin-search-dir (write) 1`] = `[]`;
|
||||
|
||||
exports[`show detailed usage with --help print-width (stderr) 1`] = `""`;
|
||||
|
||||
exports[`show detailed usage with --help print-width (stdout) 1`] = `
|
||||
|
||||
@@ -276,26 +276,6 @@ This option cannot be used with --range-start and --range-end.",
|
||||
"default": undefined,
|
||||
"description": "Which parser to use.",
|
||||
},
|
||||
"pluginSearchDirs": {
|
||||
"default": [],
|
||||
"description": "Custom directory that contains prettier plugins in node_modules subdirectory.
|
||||
Overrides default behavior when plugins are searched relatively to the location of Prettier.
|
||||
Multiple values are accepted.",
|
||||
"oneOf": [
|
||||
{
|
||||
"items": {
|
||||
"type": "string",
|
||||
},
|
||||
"type": "array",
|
||||
},
|
||||
{
|
||||
"description": "Disable plugin autoloading.",
|
||||
"enum": [
|
||||
false,
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
"plugins": {
|
||||
"default": [],
|
||||
"description": "Add a plugin. Multiple plugins can be passed as separate \`--plugin\`s.",
|
||||
|
||||
@@ -180,10 +180,6 @@ exports[`API getSupportInfo() 1`] = `
|
||||
"default": undefined,
|
||||
"type": "choice",
|
||||
},
|
||||
"pluginSearchDirs": {
|
||||
"default": [],
|
||||
"type": "path",
|
||||
},
|
||||
"plugins": {
|
||||
"default": [],
|
||||
"type": "path",
|
||||
@@ -939,15 +935,6 @@ exports[`CLI --support-info (stdout) 1`] = `
|
||||
"pluginDefaults": {},
|
||||
"type": "path"
|
||||
},
|
||||
{
|
||||
"array": true,
|
||||
"category": "Global",
|
||||
"default": [],
|
||||
"description": "Custom directory that contains prettier plugins in node_modules subdirectory.\\nOverrides default behavior when plugins are searched relatively to the location of Prettier.\\nMultiple values are accepted.",
|
||||
"name": "pluginSearchDirs",
|
||||
"pluginDefaults": {},
|
||||
"type": "path"
|
||||
},
|
||||
{
|
||||
"category": "Global",
|
||||
"default": 80,
|
||||
|
||||
@@ -92,7 +92,7 @@ describe("deprecated option values are warned", () => {
|
||||
|
||||
describe("options with `cliName` should not allow to pass directly", () => {
|
||||
// `filepath` can only pass through `--stdin-filepath`
|
||||
// `plugins` and `pluginSearchDirs` works the same
|
||||
// `plugins` works the same
|
||||
runCli("cli/arg-parsing", ["--stdin-filepath", "file.js"], {
|
||||
isTTY: false,
|
||||
input: "prettier()",
|
||||
|
||||
@@ -233,15 +233,6 @@ test("API resolveConfig resolves relative path values based on config filepath",
|
||||
prettier.resolveConfig(`${currentDir}/index.js`)
|
||||
).resolves.toMatchObject({
|
||||
plugins: [path.join(parentDir, "path-to-plugin")],
|
||||
pluginSearchDirs: [path.join(parentDir, "path-to-plugin-search-dir")],
|
||||
});
|
||||
|
||||
await expect(
|
||||
prettier.resolveConfig(
|
||||
path.join(__dirname, "../cli/config/plugin-search-dirs/index.js")
|
||||
)
|
||||
).resolves.toMatchObject({
|
||||
pluginSearchDirs: false,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -19,17 +19,6 @@ describe("show detailed usage with --help l (alias)", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("show detailed usage with plugin options (automatic resolution)", () => {
|
||||
runCli("plugins/automatic", [
|
||||
"--help",
|
||||
"tab-width",
|
||||
"--parser=bar",
|
||||
"--plugin-search-dir=.",
|
||||
]).test({
|
||||
status: 0,
|
||||
});
|
||||
});
|
||||
|
||||
describe("show detailed usage with plugin options (manual resolution)", () => {
|
||||
runCli("cli", [
|
||||
"--help",
|
||||
|
||||
@@ -105,23 +105,6 @@ describe("extracts file-info with inferredParser=null for file.foo", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("extracts file-info with inferredParser=foo when plugins are autoloaded", () => {
|
||||
runCli("plugins/automatic/", ["--file-info", "file.foo"]).test({
|
||||
status: 0,
|
||||
});
|
||||
});
|
||||
|
||||
describe("extracts file-info with inferredParser=foo when plugins are loaded with --plugin-search-dir", () => {
|
||||
runCli("cli/", [
|
||||
"--file-info",
|
||||
"file.foo",
|
||||
"--plugin-search-dir",
|
||||
"../plugins/automatic",
|
||||
]).test({
|
||||
status: 0,
|
||||
});
|
||||
});
|
||||
|
||||
describe("extracts file-info with inferredParser=foo when a plugin is hand-picked", () => {
|
||||
runCli("cli/", [
|
||||
"--file-info",
|
||||
@@ -361,25 +344,6 @@ test("returns null parser for unknown shebang", async () => {
|
||||
});
|
||||
});
|
||||
|
||||
test("API getFileInfo with plugins loaded using pluginSearchDir", async () => {
|
||||
const file = "file.foo";
|
||||
const pluginsPath = path.resolve(
|
||||
path.join(__dirname, "../plugins/automatic")
|
||||
);
|
||||
await expect(prettier.getFileInfo(file)).resolves.toMatchObject({
|
||||
ignored: false,
|
||||
inferredParser: null,
|
||||
});
|
||||
await expect(
|
||||
prettier.getFileInfo(file, {
|
||||
pluginSearchDirs: [pluginsPath],
|
||||
})
|
||||
).resolves.toMatchObject({
|
||||
ignored: false,
|
||||
inferredParser: "foo",
|
||||
});
|
||||
});
|
||||
|
||||
test("API getFileInfo with hand-picked plugins", async () => {
|
||||
const file = "file.foo";
|
||||
const pluginPath = path.resolve(
|
||||
|
||||
@@ -1,128 +1,3 @@
|
||||
describe("automatically loads 'prettier-plugin-*'", () => {
|
||||
runCli("plugins/automatic", ["file.txt", "--parser=bar"]).test({
|
||||
stdout: "content from `prettier-plugin-bar` package + contents",
|
||||
stderr: "",
|
||||
status: 0,
|
||||
write: [],
|
||||
});
|
||||
});
|
||||
|
||||
describe("automatically loads '@prettier/plugin-*'", () => {
|
||||
runCli("plugins/automatic", ["file.txt", "--parser=foo"]).test({
|
||||
stdout: "foo+contents",
|
||||
stderr: "",
|
||||
status: 0,
|
||||
write: [],
|
||||
});
|
||||
});
|
||||
|
||||
describe("automatically loads '@<name>/prettier-plugin-*'", () => {
|
||||
runCli("plugins/automatic", ["file.txt", "--parser=foobar"]).test({
|
||||
stdout: "foobar+contents",
|
||||
stderr: "",
|
||||
status: 0,
|
||||
write: [],
|
||||
});
|
||||
});
|
||||
|
||||
describe("automatically loads 'prettier-plugin-*' from --plugin-search-dir (same as autoload dir)", () => {
|
||||
runCli("plugins/automatic", [
|
||||
"file.txt",
|
||||
"--parser=foo",
|
||||
"--plugin-search-dir=.",
|
||||
]).test({
|
||||
stdout: "foo+contents",
|
||||
stderr: "",
|
||||
status: 0,
|
||||
write: [],
|
||||
});
|
||||
});
|
||||
|
||||
describe("automatically loads '@prettier/plugin-*' from --plugin-search-dir (same as autoload dir)", () => {
|
||||
runCli("plugins/automatic", [
|
||||
"file.txt",
|
||||
"--parser=bar",
|
||||
"--plugin-search-dir=.",
|
||||
]).test({
|
||||
stdout: "content from `prettier-plugin-bar` package + contents",
|
||||
stderr: "",
|
||||
status: 0,
|
||||
write: [],
|
||||
});
|
||||
});
|
||||
|
||||
describe("automatically loads '@<name>/prettier-plugin-*' from --plugin-search-dir (same as autoload dir)", () => {
|
||||
runCli("plugins/automatic", [
|
||||
"file.txt",
|
||||
"--parser=foobar",
|
||||
"--plugin-search-dir=.",
|
||||
]).test({
|
||||
stdout: "foobar+contents",
|
||||
stderr: "",
|
||||
status: 0,
|
||||
write: [],
|
||||
});
|
||||
});
|
||||
|
||||
describe("automatically loads 'prettier-plugin-*' from --plugin-search-dir (different to autoload dir)", () => {
|
||||
runCli("plugins", [
|
||||
"automatic/file.txt",
|
||||
"--parser=foo",
|
||||
"--plugin-search-dir=automatic",
|
||||
]).test({
|
||||
stdout: "foo+contents",
|
||||
stderr: "",
|
||||
status: 0,
|
||||
write: [],
|
||||
});
|
||||
});
|
||||
|
||||
describe("automatically loads '@prettier/plugin-*' from --plugin-search-dir (different to autoload dir)", () => {
|
||||
runCli("plugins", [
|
||||
"automatic/file.txt",
|
||||
"--parser=bar",
|
||||
"--plugin-search-dir=automatic",
|
||||
]).test({
|
||||
stdout: "content from `prettier-plugin-bar` package + contents",
|
||||
stderr: "",
|
||||
status: 0,
|
||||
write: [],
|
||||
});
|
||||
});
|
||||
|
||||
describe("does not crash when --plugin-search-dir does not contain node_modules", () => {
|
||||
runCli(
|
||||
"plugins/extensions",
|
||||
[
|
||||
"file.foo",
|
||||
"--end-of-line",
|
||||
"lf",
|
||||
"--plugin=./plugin.cjs",
|
||||
"--plugin-search-dir=.",
|
||||
],
|
||||
{ ignoreLineEndings: true }
|
||||
).test({
|
||||
stdout: "!contents",
|
||||
stderr: "",
|
||||
status: 0,
|
||||
write: [],
|
||||
});
|
||||
});
|
||||
|
||||
describe("crashes when one of --plugin-search-dir does not exist", () => {
|
||||
runCli("plugins/automatic", [
|
||||
"file.txt",
|
||||
"--parser=foo",
|
||||
"--plugin-search-dir=non-existing-dir",
|
||||
"--plugin-search-dir=.",
|
||||
]).test({
|
||||
stdout: "",
|
||||
stderr: "[error] non-existing-dir does not exist or is not a directory",
|
||||
status: 1,
|
||||
write: [],
|
||||
});
|
||||
});
|
||||
|
||||
describe("loads --plugin by its relative path", () => {
|
||||
runCli("plugins", [
|
||||
"automatic/file.txt",
|
||||
@@ -167,7 +42,6 @@ describe("loads --plugin by filename without leading ./, should resolve to file,
|
||||
"file.txt",
|
||||
"--parser=baz",
|
||||
"--plugin=prettier-plugin-baz.js",
|
||||
"--no-plugin-search",
|
||||
]).test({
|
||||
stdout: "content from `prettier-plugin-baz.js` file + contents",
|
||||
stderr: "",
|
||||
@@ -188,76 +62,3 @@ describe("loads --plugin by bespoke plugin name (assuming it is installed in cwd
|
||||
write: [],
|
||||
});
|
||||
});
|
||||
|
||||
test("--no-plugin-search", async () => {
|
||||
async function getParser(args = []) {
|
||||
const { stdout } = await runCli("plugins/automatic", [
|
||||
"--file-info=file.foo",
|
||||
...args,
|
||||
]);
|
||||
return JSON.parse(stdout).inferredParser;
|
||||
}
|
||||
|
||||
expect(await getParser()).toBe("foo");
|
||||
expect(await getParser(["--plugin-search-dir=."])).toBe("foo");
|
||||
expect(await getParser(["--no-plugin-search"])).toBeNull();
|
||||
});
|
||||
|
||||
test("--no-plugin-search still allow use --plugin", async () => {
|
||||
const args = ["file.txt", "--parser=baz"];
|
||||
const { stdout: stdoutWithoutPlugin } = await runCli(
|
||||
"plugins/automatic",
|
||||
args
|
||||
);
|
||||
const argsWithPlugin = [...args, "--plugin=./prettier-plugin-baz.js"];
|
||||
const { stdout: stdoutWithPlugin } = await runCli(
|
||||
"plugins/automatic",
|
||||
argsWithPlugin
|
||||
);
|
||||
const { stdout: stdoutWithoutPluginAndNoPluginSearch } = await runCli(
|
||||
"plugins/automatic",
|
||||
[...args, "--no-plugin-search"]
|
||||
);
|
||||
const { stdout: stdoutWithPluginButNoPluginSearch } = await runCli(
|
||||
"plugins/automatic",
|
||||
[...argsWithPlugin, "--no-plugin-search"]
|
||||
);
|
||||
|
||||
expect(stdoutWithoutPlugin).toBe(
|
||||
"content from `prettier-plugin-baz.js` package + contents"
|
||||
);
|
||||
expect(stdoutWithPlugin).toBe(
|
||||
"content from `prettier-plugin-baz.js` package + contents"
|
||||
);
|
||||
expect(stdoutWithoutPluginAndNoPluginSearch).toBe("");
|
||||
expect(stdoutWithPluginButNoPluginSearch).toBe(
|
||||
"content from `prettier-plugin-baz.js` file + contents"
|
||||
);
|
||||
});
|
||||
|
||||
test("--no-plugin-search together with --plugin-search-dir", async () => {
|
||||
const result1 = await runCli("plugins/automatic", [
|
||||
"--no-plugin-search",
|
||||
"--plugin-search-dir",
|
||||
]);
|
||||
const result2 = await runCli("plugins/automatic", [
|
||||
"--no-plugin-search",
|
||||
"--plugin-search-dir=foo",
|
||||
]);
|
||||
const result3 = await runCli("plugins/automatic", [
|
||||
"--no-plugin-search",
|
||||
"--plugin-search-dir=foo",
|
||||
"--plugin-search-dir=bar",
|
||||
]);
|
||||
|
||||
expect(result1).toMatchInlineSnapshot(`
|
||||
{
|
||||
"status": 1,
|
||||
"stderr": "[error] Cannot use --no-plugin-search and --plugin-search-dir together.",
|
||||
"stdout": "",
|
||||
"write": [],
|
||||
}
|
||||
`);
|
||||
expect(result2).toEqual(result1);
|
||||
expect(result3).toEqual(result1);
|
||||
});
|
||||
@@ -1,12 +0,0 @@
|
||||
describe("plugin search should not crash when prettier isn't inside a directory", () => {
|
||||
runCli(
|
||||
"plugins/virtualDirectory",
|
||||
["--stdin-filepath", "example.js", "--plugin-search-dir=."],
|
||||
{ input: "" }
|
||||
).test({
|
||||
stdout: "",
|
||||
stderr: "",
|
||||
status: 0,
|
||||
write: [],
|
||||
});
|
||||
});
|
||||
@@ -1,3 +1,2 @@
|
||||
{
|
||||
"pluginSearchDirs": false
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
{
|
||||
"plugins": ["../path-to-plugin"],
|
||||
"pluginSearchDirs": ["../path-to-plugin-search-dir"]
|
||||
"plugins": ["../path-to-plugin"]
|
||||
}
|
||||
Reference in new issue
Block a user