refactor: normalizeArgv without using getter

master
ikatyang 2017-09-09 13:38:28 +08:00
parent a7f595ca3e
commit 4d4d8e3f4e
5 changed files with 120 additions and 110 deletions

View File

@ -1,8 +1,6 @@
"use strict";
const normalizer = require("./cli-normalizer");
const detailOptions = normalizer.normalizeDetailOptions({
const detailOptions = normalizeDetailOptions({
"bracket-spacing": {
type: "boolean",
category: "format",
@ -241,6 +239,29 @@ function dedent(str) {
return str.replace(new RegExp(`^ {${spaces}}`, "gm"), "").trim();
}
function normalizeDetailOptions(rawDetailOptions) {
const names = Object.keys(rawDetailOptions).sort();
const normaliezd = names.map(name => {
const option = rawDetailOptions[name];
return Object.assign({}, option, {
name,
choices:
option.choices &&
option.choices.map(
choice => (typeof choice === "object" ? choice : { value: choice })
),
getter: option.getter || (value => value)
});
});
normaliezd.forEach(normalizedOption => {
normaliezd[normalizedOption.name] = normalizedOption;
});
return normaliezd;
}
module.exports = {
minimistOptions,
detailOptions

View File

@ -1,95 +0,0 @@
"use strict";
const validator = require("./cli-validator");
function normalizeDetailOptions(detailOptions) {
const names = Object.keys(detailOptions).sort();
const normaliezdOptions = names.map(name => {
const option = detailOptions[name];
const normalizedOption = Object.assign({}, option, {
name,
choices:
option.choices &&
option.choices.map(
choice => (typeof choice === "string" ? { value: choice } : choice)
),
_getValue: (value, argv) => {
const normalizedValue = getValue(value, argv);
if (option.exception !== undefined) {
if (typeof option.exception === "function") {
if (option.exception(normalizedValue)) {
return normalizedValue;
}
} else {
if (normalizedValue === option.exception) {
return normalizedValue;
}
}
}
switch (option.type) {
case "int":
validator.validateIntOption(normalizedValue, normalizedOption);
return Number(normalizedValue);
case "choice":
validator.validateChoiceOption(normalizedValue, normalizedOption);
break;
}
return normalizedValue;
}
});
return normalizedOption;
function getValue(value, argv) {
if (value && option.deprecated) {
let warning = `\`--${name}\` is deprecated.`;
if (typeof option.deprecated === "string") {
warning += ` ${option.deprecated}`;
}
console.warn(warning);
}
if (typeof option.getter === "function") {
return option.getter(value, argv);
}
if (option.type === "choice") {
const choice = option.choices.find(choice => choice.value === value);
if (choice !== undefined && choice.deprecated) {
const warningValue =
value === "" ? "without an argument" : `with value \`${value}\``;
console.warn(
`\`--${name}\` ${warningValue} is deprecated. Automatically redirect to \`--${name}=${choice.redirect}\`.`
);
return choice.redirect;
}
}
return value;
}
});
normaliezdOptions.forEach(normalizedOption => {
normaliezdOptions[normalizedOption.name] = normalizedOption;
});
return normaliezdOptions;
}
function normalizeArgv(argv, detailOptions) {
const normalizedArgv = { _: argv["_"] };
detailOptions.forEach(option => {
Object.defineProperty(normalizedArgv, option.name, {
get: () => option._getValue(argv[option.name], normalizedArgv)
});
});
return normalizedArgv;
}
module.exports = {
normalizeArgv,
normalizeDetailOptions
};

View File

@ -14,7 +14,7 @@ const prettier = eval("require")("../index");
const cleanAST = require("./clean-ast").cleanAST;
const resolver = require("./resolve-config");
const constant = require("./cli-constant");
const normalizer = require("./cli-normalizer");
const validator = require("./cli-validator");
const apiDefaultOptions = require("./options").defaults;
function getOptions(argv) {
@ -159,7 +159,7 @@ function getOptionsForFile(argv, filePath) {
function parseArgsToOptions(argv, overrideDefaults) {
return getOptions(
normalizer.normalizeArgv(
normalizeArgv(
minimist(
argv.__args,
Object.assign({
@ -172,7 +172,7 @@ function parseArgsToOptions(argv, overrideDefaults) {
)
})
),
constant.detailOptions
{ warning: false }
)
);
}
@ -398,10 +398,99 @@ function indent(str, spaces) {
return str.replace(/^/gm, " ".repeat(spaces));
}
function normalizeArgv(rawArgv, options) {
options = options || {};
const consoleWarn = options.warning === false ? () => {} : console.warn;
const normalized = {};
Object.keys(rawArgv).forEach(key => {
const rawValue = rawArgv[key];
if (key === "_") {
normalized[key] = rawValue;
return;
}
if (key.length === 1) {
// do nothing with alias
return;
}
const option = constant.detailOptions[key];
if (option === undefined) {
// unknown option
return;
}
const value = getValue(rawValue, option);
if (option.exception !== undefined) {
if (typeof option.exception === "function") {
if (option.exception(value)) {
normalized[key] = value;
return;
}
} else {
if (value === option.exception) {
normalized[key] = value;
return;
}
}
}
switch (option.type) {
case "int":
validator.validateIntOption(value, option);
normalized[key] = Number(value);
break;
case "choice":
validator.validateChoiceOption(value, option);
// eslint-disable-next-line no-fallthrough
default:
normalized[key] = value;
break;
}
});
return normalized;
function getValue(rawValue, option) {
if (rawValue && option.deprecated) {
let warning = `\`--${option.name}\` is deprecated.`;
if (typeof option.deprecated === "string") {
warning += ` ${option.deprecated}`;
}
consoleWarn(warning);
}
const value = option.getter(rawValue, rawArgv);
if (option.type === "choice") {
const choice = option.choices.find(choice => choice.value === rawValue);
if (choice !== undefined && choice.deprecated) {
const warningDescription =
rawValue === ""
? "without an argument"
: `with value \`${rawValue}\``;
consoleWarn(
`\`--${option.name}\` ${warningDescription} is deprecated. Automatically redirect to \`--${option.name}=${choice.redirect}\`.`
);
return choice.redirect;
}
}
return value;
}
}
module.exports = {
logResolvedConfigPathOrDie,
format,
formatStdin,
formatFiles,
createUsage
createUsage,
normalizeArgv
};

View File

@ -6,13 +6,9 @@ const prettier = eval("require")("../index");
const constant = require("./cli-constant");
const util = require("./cli-util");
const validator = require("./cli-validator");
const normalizer = require("./cli-normalizer");
function run(args) {
const argv = normalizer.normalizeArgv(
minimist(args, constant.minimistOptions),
constant.detailOptions
);
const argv = util.normalizeArgv(minimist(args, constant.minimistOptions));
argv.__args = args;
argv.__filePatterns = argv["_"];

View File

@ -19,9 +19,8 @@ Expected \\"none\\", \\"es5\\" or \\"all\\", but received: \\"wow\\"
`;
exports[`throw error with invalid config precedence option (configPrecedence) 1`] = `
"Error: Invalid option for --config-precedence.
Expected \\"cli-override\\", \\"file-override\\" or \\"prefer-file\\", but received: \\"option/configPrecedence\\"
"
"Invalid option for --config-precedence.
Expected \\"cli-override\\", \\"file-override\\" or \\"prefer-file\\", but received: \\"option/configPrecedence\\""
`;
exports[`throw error with invalid config target (directory) 1`] = `