Skip to content

Commit

Permalink
Update: Reorder init menu (fixes #11105)
Browse files Browse the repository at this point in the history
  • Loading branch information
nzakas committed Feb 13, 2019
1 parent 983c520 commit aaceefb
Showing 1 changed file with 120 additions and 137 deletions.
257 changes: 120 additions & 137 deletions lib/config/config-initializer.js
Expand Up @@ -28,6 +28,8 @@ const debug = require("debug")("eslint:config-initializer");
// Private
//------------------------------------------------------------------------------

const DEFAULT_ECMA_VERSION = 2018;

/* istanbul ignore next: hard to test fs function */
/**
* Create .eslintrc file in the current working directory
Expand Down Expand Up @@ -239,43 +241,50 @@ function configureRules(answers, config) {
* @returns {Object} config object
*/
function processAnswers(answers) {
let config = { rules: {}, env: {}, parserOptions: {} };
let config = {
rules: {},
env: {},
parserOptions: {}
};

config.parserOptions.ecmaVersion = answers.ecmaVersion;
if (answers.ecmaVersion >= 2015) {
if (answers.modules) {
config.parserOptions.sourceType = "module";
}
config.env.es6 = true;
}
// set the latest ECMAScript version
config.parserOptions.ecmaVersion = DEFAULT_ECMA_VERSION;
config.env.es6 = true;

if (answers.commonjs) {
// set the module type
if (answers.moduleType === "esm") {
config.parserOptions.sourceType = "module";
} else if (answers.moduleType === "commonjs") {
config.env.commonjs = true;
}

// add in browser and node environments if necessary
answers.env.forEach(env => {
config.env[env] = true;
});
if (answers.jsx) {
config.parserOptions = config.parserOptions || {};
config.parserOptions.ecmaFeatures = config.parserOptions.ecmaFeatures || {};

// add in library information
if (answers.framwork === "react") {
config.parserOptions.ecmaFeatures.jsx = true;
if (answers.react) {
config.plugins = ["react"];
config.parserOptions.ecmaVersion = 2018;
}
config.plugins = ["react"];
} else if (answers.framework === "vue") {
config.plugins = ["vue"];
}

if (answers.source === "prompt") {
// setup rules based on problems/style enforcement preferences
if (answers.purpose === "problems") {
config.extends = "eslint:recommended";
config.rules.indent = ["error", answers.indent];
config.rules.quotes = ["error", answers.quotes];
config.rules["linebreak-style"] = ["error", answers.linebreak];
config.rules.semi = ["error", answers.semi ? "always" : "never"];
}

if (answers.source === "auto") {
config = configureRules(answers, config);
config = autoconfig.extendFromRecommended(config);
} else if (answers.purpose === "style") {
if (answers.source === "prompt") {
config.extends = "eslint:recommended";
config.rules.indent = ["error", answers.indent];
config.rules.quotes = ["error", answers.quotes];
config.rules["linebreak-style"] = ["error", answers.linebreak];
config.rules.semi = ["error", answers.semi ? "always" : "never"];
} else if (answers.source === "auto") {
config = configureRules(answers, config);
config = autoconfig.extendFromRecommended(config);
}
}

ConfigOps.normalizeToStrings(config);
Expand Down Expand Up @@ -324,7 +333,7 @@ function getLocalESLintVersion() {
* @returns {string} The shareable config name.
*/
function getStyleGuideName(answers) {
if (answers.styleguide === "airbnb" && !answers.airbnbReact) {
if (answers.styleguide === "airbnb" && answers.framework !== "react") {
return "airbnb-base";
}
return answers.styleguide;
Expand Down Expand Up @@ -417,16 +426,62 @@ function askInstallModules(modules, packageJsonExists) {
function promptUser() {

return inquirer.prompt([
{
type: "list",
name: "purpose",
message: "How would you like to use ESLint?",
default: "problems",
choices: [
{ name: "To check syntax only", value: "syntax" },
{ name: "To check syntax and find problems", value: "problems" },
{ name: "To check syntax, find problems, and enforce code style", value: "style" }
]
},
{
type: "list",
name: "moduleType",
message: "What type of modules does your project use?",
default: "esm",
choices: [
{ name: "JavaScript modules", value: "esm" },
{ name: "CommonJS", value: "commonjs" },
{ name: "None of these", value: "none" }
]
},
{
type: "list",
name: "framework",
message: "Which framework does your project use?",
default: "react",
choices: [
{ name: "React", value: "react" },
{ name: "Vue.js", value: "vue" },
{ name: "None of these", value: "none" }
]
},
{
type: "checkbox",
name: "env",
message: "Where does your code run?",
default: ["browser"],
choices: [
{ name: "Browser", value: "browser" },
{ name: "Node", value: "node" }
]
},
{
type: "list",
name: "source",
message: "How would you like to configure ESLint?",
message: "How would you like to define a style for your project?",
default: "prompt",
choices: [
{ name: "Use a popular style guide", value: "guide" },
{ name: "Answer questions about your style", value: "prompt" },
{ name: "Inspect your JavaScript file(s)", value: "auto" }
]
],
when(answers) {
return answers.purpose === "style";
}
},
{
type: "list",
Expand All @@ -442,15 +497,6 @@ function promptUser() {
return answers.source === "guide" && answers.packageJsonExists;
}
},
{
type: "confirm",
name: "airbnbReact",
message: "Do you use React?",
default: false,
when(answers) {
return answers.styleguide === "airbnb";
}
},
{
type: "input",
name: "patterns",
Expand Down Expand Up @@ -501,7 +547,7 @@ function promptUser() {
if (earlyAnswers.installESLint === false && !semver.satisfies(earlyAnswers.localESLintVersion, earlyAnswers.requiredESLintVersionRange)) {
log.info(`Note: it might not work since ESLint's version is mismatched with the ${earlyAnswers.styleguide} config.`);
}
if (earlyAnswers.styleguide === "airbnb" && !earlyAnswers.airbnbReact) {
if (earlyAnswers.styleguide === "airbnb" && earlyAnswers.framework !== "react") {
earlyAnswers.styleguide = "airbnb-base";
}

Expand All @@ -510,121 +556,58 @@ function promptUser() {

return askInstallModules(modules, earlyAnswers.packageJsonExists)
.then(() => writeFile(config, earlyAnswers.format));

} else if (earlyAnswers.source === "auto") {
const combinedAnswers = Object.assign({}, earlyAnswers, secondAnswers);
const config = processAnswers(combinedAnswers);
const modules = getModulesList(config);

return askInstallModules(modules).then(() => writeFile(config, earlyAnswers.format));
}

// continue with the questions otherwise...
// continue with the style questions otherwise...
return inquirer.prompt([
{
type: "list",
name: "ecmaVersion",
message: "Which version of ECMAScript do you use?",
choices: [
{ name: "ES3", value: 3 },
{ name: "ES5", value: 5 },
{ name: "ES2015", value: 2015 },
{ name: "ES2016", value: 2016 },
{ name: "ES2017", value: 2017 },
{ name: "ES2018", value: 2018 }
],
default: 1 // This is the index in the choices list
name: "indent",
message: "What style of indentation do you use?",
default: "tab",
choices: [{ name: "Tabs", value: "tab" }, { name: "Spaces", value: 4 }]
},
{
type: "confirm",
name: "modules",
message: "Are you using ES6 modules?",
default: false,
when(answers) {
return answers.ecmaVersion >= 2015;
}
},
{
type: "checkbox",
name: "env",
message: "Where will your code run?",
default: ["browser"],
choices: [{ name: "Browser", value: "browser" }, { name: "Node", value: "node" }]
type: "list",
name: "quotes",
message: "What quotes do you use for strings?",
default: "double",
choices: [{ name: "Double", value: "double" }, { name: "Single", value: "single" }]
},
{
type: "confirm",
name: "commonjs",
message: "Do you use CommonJS?",
default: false,
when(answers) {
return answers.env.some(env => env === "browser");
}
type: "list",
name: "linebreak",
message: "What line endings do you use?",
default: "unix",
choices: [{ name: "Unix", value: "unix" }, { name: "Windows", value: "windows" }]
},
{
type: "confirm",
name: "jsx",
message: "Do you use JSX?",
default: false
name: "semi",
message: "Do you require semicolons?",
default: true
},
{
type: "confirm",
name: "react",
message: "Do you use React?",
default: false,
when(answers) {
return answers.jsx;
}
}
]).then(secondAnswers => {

// early exit if you are using automatic style generation
if (earlyAnswers.source === "auto") {
const combinedAnswers = Object.assign({}, earlyAnswers, secondAnswers);

const config = processAnswers(combinedAnswers);

const modules = getModulesList(config);

return askInstallModules(modules).then(() => writeFile(config, earlyAnswers.format));
type: "list",
name: "format",
message: "What format do you want your config file to be in?",
default: "JavaScript",
choices: ["JavaScript", "YAML", "JSON"]
}
]).then(answers => {
const totalAnswers = Object.assign({}, earlyAnswers, secondAnswers, answers);

// continue with the style questions otherwise...
return inquirer.prompt([
{
type: "list",
name: "indent",
message: "What style of indentation do you use?",
default: "tab",
choices: [{ name: "Tabs", value: "tab" }, { name: "Spaces", value: 4 }]
},
{
type: "list",
name: "quotes",
message: "What quotes do you use for strings?",
default: "double",
choices: [{ name: "Double", value: "double" }, { name: "Single", value: "single" }]
},
{
type: "list",
name: "linebreak",
message: "What line endings do you use?",
default: "unix",
choices: [{ name: "Unix", value: "unix" }, { name: "Windows", value: "windows" }]
},
{
type: "confirm",
name: "semi",
message: "Do you require semicolons?",
default: true
},
{
type: "list",
name: "format",
message: "What format do you want your config file to be in?",
default: "JavaScript",
choices: ["JavaScript", "YAML", "JSON"]
}
]).then(answers => {
const totalAnswers = Object.assign({}, earlyAnswers, secondAnswers, answers);

const config = processAnswers(totalAnswers);
const modules = getModulesList(config);
const config = processAnswers(totalAnswers);
const modules = getModulesList(config);

return askInstallModules(modules).then(() => writeFile(config, answers.format));
});
return askInstallModules(modules).then(() => writeFile(config, answers.format));
});
});
}
Expand Down

0 comments on commit aaceefb

Please sign in to comment.