Remove plugin search feature (#14759)

Co-authored-by: SUZUKI Sosuke <aosukeke@gmail.com>
This commit is contained in:
fisker CheungandSUZUKI Sosuke authored and GitHub committed 2023-05-05 10:31:25 +08:00
1 parent fbd82cf774
commit 54404fc96f
36 files changed
+35 -638

No files matched your search

+7
View File
@@ -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).
-4
View File
@@ -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
View File
@@ -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
-13
View File
@@ -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,
-4
View File
@@ -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
View File
@@ -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);
}
-2
View File
@@ -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
View File
@@ -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.");
}
+1 -3
View File
@@ -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;
+1 -2
View File
@@ -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);
+1 -6
View File
@@ -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];
+6 -8
View File
@@ -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;
-4
View File
@@ -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
View File
@@ -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(),
};
-15
View File
@@ -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",
-30
View File
@@ -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 -8
View File
@@ -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";
-76
View File
@@ -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
View File
@@ -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> }}
*/
-15
View File
@@ -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;
-2
View File
@@ -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,
-5
View File
@@ -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])}`)
-21
View File
@@ -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,
+1 -1
View File
@@ -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,
});
});
-11
View File
@@ -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",
-36
View File
@@ -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"]
}