Move normalizeCliOptions into cli/ (#13547)

This commit is contained in:
fisker Cheung authored and GitHub committed 2022-10-18 09:58:16 +08:00
1 parent e574e6050a
commit 0029f2df75
6 files changed
+83 -108

No files matched your search

+1 -1
View File
@@ -1,6 +1,6 @@
import dashify from "dashify";
import { resolveConfig } from "../../index.js";
import { normalizeApiOptions } from "../prettier-internal.js";
import { normalizeOptions as normalizeApiOptions } from "../prettier-internal.js";
import minimist from "./minimist.js";
import createMinimistOptions from "./create-minimist-options.js";
import normalizeCliOptions from "./normalize-cli-options.js";
+49 -4
View File
@@ -1,12 +1,57 @@
import chalk from "chalk";
import leven from "leven";
import { normalizeCliOptions as prettierNormalizeCliOptions } from "../prettier-internal.js";
import { normalizeOptions, vnopts } from "../prettier-internal.js";
const descriptor = {
key: (key) => (key.length === 1 ? `-${key}` : `--${key}`),
value: (value) => vnopts.apiDescriptor.value(value),
pair: ({ key, value }) =>
value === false
? `--no-${key}`
: value === true
? descriptor.key(key)
: value === ""
? `${descriptor.key(key)} without an argument`
: `${descriptor.key(key)}=${value}`,
};
class FlagSchema extends vnopts.ChoiceSchema {
#flags = [];
constructor({ name, flags }) {
super({ name, choices: flags });
this.#flags = [...flags].sort();
}
preprocess(value, utils) {
if (
typeof value === "string" &&
value.length > 0 &&
!this.#flags.includes(value)
) {
const suggestion = this.#flags.find((flag) => leven(flag, value) < 3);
if (suggestion) {
utils.logger.warn(
[
`Unknown flag ${chalk.yellow(utils.descriptor.value(value))},`,
`did you mean ${chalk.blue(utils.descriptor.value(suggestion))}?`,
].join(" ")
);
return suggestion;
}
}
return value;
}
expected() {
return "a flag";
}
}
function normalizeCliOptions(options, optionInfos, opts) {
return prettierNormalizeCliOptions(options, optionInfos, {
colorsModule: chalk,
levenshteinDistance: leven,
return normalizeOptions(options, optionInfos, {
...opts,
isCLI: true,
FlagSchema,
descriptor,
});
}
+2 -2
View File
@@ -5,7 +5,7 @@ export const {
coreOptions,
createIgnorer,
optionsHiddenDefaults,
normalizeApiOptions,
normalizeCliOptions,
normalizeOptions,
getSupportInfoWithoutPlugins,
vnopts,
} = sharedWithCli;
+4 -6
View File
@@ -1,3 +1,4 @@
import vnopts from "vnopts";
import core from "./main/core.js";
import { getSupportInfo as getSupportInfoWithoutPlugins } from "./main/support.js";
import getFileInfoWithoutPlugins from "./common/get-file-info.js";
@@ -15,10 +16,7 @@ import * as errors from "./common/errors.js";
import * as coreOptions from "./main/core-options.js";
import createIgnorer from "./common/create-ignorer.js";
import { hiddenDefaults as optionsHiddenDefaults } from "./main/options.js";
import {
normalizeApiOptions,
normalizeCliOptions,
} from "./main/options-normalizer.js";
import normalizeOptions from "./main/options-normalizer.js";
import arrayify from "./utils/arrayify.js";
import partition from "./utils/partition.js";
import { isNonEmptyArray } from "./common/util.js";
@@ -80,9 +78,9 @@ const sharedWithCli = {
coreOptions,
createIgnorer,
optionsHiddenDefaults,
normalizeApiOptions,
normalizeCliOptions,
normalizeOptions,
getSupportInfoWithoutPlugins,
vnopts,
utils: {
arrayify,
isNonEmptyArray,
+24 -92
View File
@@ -4,64 +4,12 @@ import vnopts from "vnopts";
* @typedef {import("./support.js").NamedOptionInfo} NamedOptionInfo
*/
const cliDescriptor = {
key: (key) => (key.length === 1 ? `-${key}` : `--${key}`),
value: (value) => vnopts.apiDescriptor.value(value),
pair: ({ key, value }) =>
value === false
? `--no-${key}`
: value === true
? cliDescriptor.key(key)
: value === ""
? `${cliDescriptor.key(key)} without an argument`
: `${cliDescriptor.key(key)}=${value}`,
};
// To prevent `chalk` and `leven` module from being included in the `standalone.js` bundle, it will take that as an argument if needed.
const getFlagSchema = ({ colorsModule, levenshteinDistance }) =>
class FlagSchema extends vnopts.ChoiceSchema {
#flags = [];
constructor({ name, flags }) {
super({ name, choices: flags });
this.#flags = [...flags].sort();
}
preprocess(value, utils) {
if (
typeof value === "string" &&
value.length > 0 &&
!this.#flags.includes(value)
) {
const suggestion = this.#flags.find(
(flag) => levenshteinDistance(flag, value) < 3
);
if (suggestion) {
utils.logger.warn(
[
`Unknown flag ${colorsModule.yellow(
utils.descriptor.value(value)
)},`,
`did you mean ${colorsModule.blue(
utils.descriptor.value(suggestion)
)}?`,
].join(" ")
);
return suggestion;
}
}
return value;
}
expected() {
return "a flag";
}
};
let hasDeprecationWarned;
/**
* @param {*} options
* @param {*} optionInfos
* @param {{ logger?: false; isCLI?: boolean; passThrough?: boolean; colorsModule?: any; levenshteinDistance?: any }} param2
* @param {{ logger?: false; isCLI?: boolean; passThrough?: string[] | boolean; FlagSchema?: any; descriptor?: any }} param2
*/
function normalizeOptions(
options,
@@ -70,10 +18,24 @@ function normalizeOptions(
logger = false,
isCLI = false,
passThrough = false,
colorsModule = null,
levenshteinDistance = null,
FlagSchema,
descriptor,
} = {}
) {
// TODO: Move CLI related part into `/src/cli`
/* istanbul ignore next */
if (isCLI) {
if (!FlagSchema) {
throw new Error("'FlagSchema' option is required.");
}
if (!descriptor) {
throw new Error("'descriptor' option is required.");
}
} else {
descriptor = vnopts.apiDescriptor;
}
const unknown = !passThrough
? (key, value, options) => {
// Don't suggest `_` for unknown flags
@@ -88,12 +50,7 @@ function normalizeOptions(
!passThrough.includes(key) ? undefined : { [key]: value }
: (key, value) => ({ [key]: value });
const descriptor = isCLI ? cliDescriptor : vnopts.apiDescriptor;
const schemas = optionInfosToSchemas(optionInfos, {
isCLI,
colorsModule,
levenshteinDistance,
});
const schemas = optionInfosToSchemas(optionInfos, { isCLI, FlagSchema });
const normalizer = new vnopts.Normalizer(schemas, {
logger,
unknown,
@@ -121,10 +78,7 @@ function normalizeOptions(
return normalized;
}
function optionInfosToSchemas(
optionInfos,
{ isCLI, colorsModule, levenshteinDistance }
) {
function optionInfosToSchemas(optionInfos, { isCLI, FlagSchema }) {
const schemas = [];
if (isCLI) {
@@ -136,8 +90,7 @@ function optionInfosToSchemas(
optionInfoToSchema(optionInfo, {
isCLI,
optionInfos,
colorsModule,
levenshteinDistance,
FlagSchema,
})
);
@@ -160,10 +113,7 @@ function optionInfosToSchemas(
* @param {any} param1
* @returns
*/
function optionInfoToSchema(
optionInfo,
{ isCLI, optionInfos, colorsModule, levenshteinDistance }
) {
function optionInfoToSchema(optionInfo, { isCLI, optionInfos, FlagSchema }) {
const { name } = optionInfo;
if (name === "plugin-search-dir" || name === "pluginSearchDirs") {
@@ -223,7 +173,8 @@ function optionInfoToSchema(
SchemaConstructor = vnopts.BooleanSchema;
break;
case "flag":
SchemaConstructor = getFlagSchema({ colorsModule, levenshteinDistance });
// Only available when normalizing CLI options
SchemaConstructor = FlagSchema;
parameters.flags = optionInfos.flatMap((optionInfo) =>
[
optionInfo.alias,
@@ -286,23 +237,4 @@ function optionInfoToSchema(
: SchemaConstructor.create({ ...parameters, ...handlers });
}
function normalizeApiOptions(options, optionInfos, opts) {
return normalizeOptions(options, optionInfos, opts);
}
function normalizeCliOptions(options, optionInfos, opts) {
/* istanbul ignore next */
if (process.env.NODE_ENV !== "production") {
if (!opts.colorsModule) {
throw new Error("'colorsModule' option is required.");
}
if (!opts.levenshteinDistance) {
throw new Error("'levenshteinDistance' option is required.");
}
}
return normalizeOptions(options, optionInfos, { isCLI: true, ...opts });
}
export { normalizeApiOptions, normalizeCliOptions };
export default normalizeOptions;
+3 -3
View File
@@ -2,7 +2,7 @@ import path from "node:path";
import { UndefinedParserError } from "../common/errors.js";
import { getSupportInfo } from "../main/support.js";
import getInterpreter from "../utils/get-interpreter.js";
import { normalizeApiOptions } from "./options-normalizer.js";
import normalizeOptions from "./options-normalizer.js";
import { resolveParser } from "./parser.js";
const hiddenDefaults = {
@@ -52,7 +52,7 @@ async function normalize(options, opts = {}) {
const parser = await resolveParser(
// @ts-expect-error
normalizeApiOptions(
normalizeOptions(
rawOptions,
[supportOptions.find((x) => x.name === "parser")],
{ passThrough: true, logger: false }
@@ -90,7 +90,7 @@ async function normalize(options, opts = {}) {
rawOptions.trailingComma = "none";
}
return normalizeApiOptions(rawOptions, supportOptions, {
return normalizeOptions(rawOptions, supportOptions, {
passThrough: Object.keys(hiddenDefaults),
...opts,
});