Add --no-plugin-search (#10274)
Co-authored-by: Alexander Kachkaev <alexander@kachkaev.ru>
This commit is contained in:
1 parent
162097e2d2
commit
3ba48bb266
14 files changed
+190
-20
No files matched your search
@@ -0,0 +1,12 @@
|
||||
#### Add `--no-plugin-search` to turn off plugin autoloading (#10274 by @fisker)
|
||||
|
||||
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.
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```cli
|
||||
// Prettier stable
|
||||
$ prettier . --plugin-search-dir=a-dir-without-plugins
|
||||
|
||||
// Prettier main
|
||||
$ prettier . --no-plugin-search
|
||||
```
|
||||
@@ -200,3 +200,7 @@ $ prettier "**/*" --write --ignore-unknown
|
||||
## `--no-error-on-unmatched-pattern`
|
||||
|
||||
Prevent errors when pattern is unmatched.
|
||||
|
||||
## `--no-plugin-search`
|
||||
|
||||
Disable plugin autoloading.
|
||||
+1
-1
@@ -46,7 +46,7 @@ The paths that are provided to `pluginSearchDirs` will be searched for `@prettie
|
||||
|
||||
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()`.)
|
||||
|
||||
Providing at least one path to `--plugin-search-dir`/`pluginSearchDirs` turns off plugin autoloading in the default directory (i.e. `node_modules` above `prettier` binary).
|
||||
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.
|
||||
|
||||
## Official Plugins
|
||||
|
||||
|
||||
@@ -202,6 +202,10 @@ const options = {
|
||||
default: "log",
|
||||
choices: ["silent", "error", "warn", "log", "debug"],
|
||||
},
|
||||
"plugin-search": {
|
||||
type: "boolean",
|
||||
oppositeDescription: "Disable plugin autoloading.",
|
||||
},
|
||||
"support-info": {
|
||||
type: "boolean",
|
||||
description: "Print support information as JSON.",
|
||||
|
||||
@@ -15,6 +15,9 @@ const { createDetailedUsage, createUsage } = require("./usage.js");
|
||||
const { formatStdin, formatFiles } = require("./format.js");
|
||||
const logFileInfoOrDie = require("./file-info.js");
|
||||
const logResolvedConfigPathOrDie = require("./find-config-path.js");
|
||||
const {
|
||||
utils: { isNonEmptyArray },
|
||||
} = require("./prettier-internal.js");
|
||||
|
||||
async function run(rawArguments) {
|
||||
// Create a default level logger, so we can log errors during `logLevel` parsing
|
||||
@@ -42,6 +45,18 @@ async function main(rawArguments, logger) {
|
||||
|
||||
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.");
|
||||
}
|
||||
|
||||
@@ -14,6 +14,10 @@ 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)
|
||||
);
|
||||
@@ -25,19 +29,27 @@ function parseArgv(rawArguments, detailedOptions, logger, keys) {
|
||||
colorsModule: chalk,
|
||||
});
|
||||
|
||||
return 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`
|
||||
// Otherwise use camel case for readability
|
||||
// `--ignore-unknown` -> `ignoreUnknown`
|
||||
return [option.forwardToApi || camelCase(key), value];
|
||||
})
|
||||
);
|
||||
return {
|
||||
...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`
|
||||
// Otherwise use camel case for readability
|
||||
// `--ignore-unknown` -> `ignoreUnknown`
|
||||
return [option.forwardToApi || camelCase(key), value];
|
||||
})
|
||||
),
|
||||
get __raw() {
|
||||
return argv;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const detailedOptionsWithoutPlugins = getContextOptions().detailedOptions;
|
||||
const detailedOptionsWithoutPlugins = getContextOptions(
|
||||
[],
|
||||
false
|
||||
).detailedOptions;
|
||||
function parseArgvWithoutPlugins(rawArguments, logger, keys) {
|
||||
return parseArgv(
|
||||
rawArguments,
|
||||
|
||||
@@ -22,14 +22,17 @@ function load(plugins, pluginSearchDirs) {
|
||||
plugins = [];
|
||||
}
|
||||
|
||||
if (!pluginSearchDirs) {
|
||||
if (pluginSearchDirs === false) {
|
||||
pluginSearchDirs = [];
|
||||
}
|
||||
// unless pluginSearchDirs are provided, auto-load plugins from node_modules that are parent to Prettier
|
||||
if (pluginSearchDirs.length === 0) {
|
||||
const autoLoadDir = thirdParty.findParentDir(__dirname, "node_modules");
|
||||
if (autoLoadDir) {
|
||||
pluginSearchDirs = [autoLoadDir];
|
||||
} else {
|
||||
pluginSearchDirs = pluginSearchDirs || [];
|
||||
|
||||
// unless pluginSearchDirs are provided, auto-load plugins from node_modules that are parent to Prettier
|
||||
if (pluginSearchDirs.length === 0) {
|
||||
const autoLoadDir = thirdParty.findParentDir(__dirname, "node_modules");
|
||||
if (autoLoadDir) {
|
||||
pluginSearchDirs = [autoLoadDir];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -75,6 +75,7 @@ module.exports = {
|
||||
utils: {
|
||||
arrayify: require("./utils/arrayify.js"),
|
||||
getLast: require("./utils/get-last.js"),
|
||||
isNonEmptyArray: require("./common/util.js").isNonEmptyArray,
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
@@ -94,6 +94,10 @@ function normalizeOptions(
|
||||
hasDeprecationWarned = normalizer._hasDeprecationWarned;
|
||||
}
|
||||
|
||||
if (isCLI && normalized["plugin-search"] === false) {
|
||||
normalized["plugin-search-dir"] = false;
|
||||
}
|
||||
|
||||
return normalized;
|
||||
}
|
||||
|
||||
@@ -123,8 +127,32 @@ function optionInfosToSchemas(optionInfos, { isCLI, colorsModule }) {
|
||||
}
|
||||
|
||||
function optionInfoToSchema(optionInfo, { isCLI, optionInfos, colorsModule }) {
|
||||
const { name } = optionInfo;
|
||||
|
||||
if (name === "plugin-search-dir" || name === "pluginSearchDirs") {
|
||||
return vnopts.AnySchema.create({
|
||||
name,
|
||||
preprocess(value) {
|
||||
if (value === false) {
|
||||
return value;
|
||||
}
|
||||
value = Array.isArray(value) ? value : [value];
|
||||
return 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 parameters = { name: optionInfo.name };
|
||||
const handlers = {};
|
||||
|
||||
switch (optionInfo.type) {
|
||||
|
||||
@@ -153,6 +153,7 @@ Other options:
|
||||
--loglevel <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.
|
||||
@@ -322,6 +323,7 @@ Other options:
|
||||
--loglevel <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.
|
||||
|
||||
@@ -358,6 +358,17 @@ 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`] = `Array []`;
|
||||
|
||||
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`] = `Array []`;
|
||||
|
||||
exports[`show detailed usage with --help no-semi (stderr) 1`] = `""`;
|
||||
|
||||
exports[`show detailed usage with --help no-semi (stdout) 1`] = `
|
||||
|
||||
@@ -304,6 +304,14 @@ test("API resolveConfig resolves relative path values based on config filepath",
|
||||
plugins: [path.join(parentDir, "path-to-plugin")],
|
||||
pluginSearchDirs: [path.join(parentDir, "path-to-plugin-search-dir")],
|
||||
});
|
||||
|
||||
expect(
|
||||
prettier.resolveConfig.sync(
|
||||
path.join(__dirname, "../cli/config/plugin-search-dirs/index.js")
|
||||
)
|
||||
).toMatchObject({
|
||||
pluginSearchDirs: false,
|
||||
});
|
||||
});
|
||||
|
||||
test("API resolveConfig de-references to an external module", () => {
|
||||
|
||||
@@ -205,3 +205,70 @@ 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 runPrettier("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=bar"];
|
||||
const { stdout: stdoutWithoutPlugin } = await runPrettier(
|
||||
"plugins/automatic",
|
||||
args
|
||||
);
|
||||
const argsWithPlugin = [...args, "--plugin=./prettier-plugin-bar.js"];
|
||||
const { stdout: stdoutWithPlugin } = await runPrettier(
|
||||
"plugins/automatic",
|
||||
argsWithPlugin
|
||||
);
|
||||
const { stdout: stdoutWithoutPluginAndNoPluginSearch } = await runPrettier(
|
||||
"plugins/automatic",
|
||||
[...args, "--no-plugin-search"]
|
||||
);
|
||||
const { stdout: stdoutWithPluginButNoPluginSearch } = await runPrettier(
|
||||
"plugins/automatic",
|
||||
[...argsWithPlugin, "--no-plugin-search"]
|
||||
);
|
||||
|
||||
expect(stdoutWithoutPlugin).not.toBe(stdoutWithPlugin);
|
||||
expect(stdoutWithoutPluginAndNoPluginSearch).toBe("");
|
||||
expect(stdoutWithPlugin).toBe(stdoutWithPluginButNoPluginSearch);
|
||||
});
|
||||
|
||||
test("--no-plugin-search together with --plugin-search-dir", async () => {
|
||||
const result1 = await runPrettier("plugins/automatic", [
|
||||
"--no-plugin-search",
|
||||
"--plugin-search-dir",
|
||||
]);
|
||||
const result2 = await runPrettier("plugins/automatic", [
|
||||
"--no-plugin-search",
|
||||
"--plugin-search-dir=foo",
|
||||
]);
|
||||
const result3 = await runPrettier("plugins/automatic", [
|
||||
"--no-plugin-search",
|
||||
"--plugin-search-dir=foo",
|
||||
"--plugin-search-dir=bar",
|
||||
]);
|
||||
|
||||
expect(result1).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"status": 1,
|
||||
"stderr": "[error] Cannot use --no-plugin-search and --plugin-search-dir together.
|
||||
",
|
||||
"stdout": "",
|
||||
"write": Array [],
|
||||
}
|
||||
`);
|
||||
expect(result2).toEqual(result1);
|
||||
expect(result3).toEqual(result1);
|
||||
});
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"pluginSearchDirs": false
|
||||
}
|
||||
Reference in new issue
Block a user