Skip to content

Commit

Permalink
Chore: Replace the inquirer dependency with enquirer (#13254)
Browse files Browse the repository at this point in the history
* Update: Replace dependency inquirer with enquirer (fixes #13208)

Closes #13208

* Replace confirm prompts with toggle prompts to match inquirer behaviour

* Fix skip property typo

* Add help description

* Use hint instead of message for usage informatino

Co-authored-by: YeonJuan <yeonjuan93@naver.com>

* Add comment about initial select prompt

* Update config-initializer.js

* Update config-initializer.js

Co-authored-by: YeonJuan <yeonjuan93@naver.com>
  • Loading branch information
Siilwyn and yeonjuan committed Jun 9, 2020
1 parent 0f1f5ed commit 7ce7988
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 68 deletions.
156 changes: 89 additions & 67 deletions lib/init/config-initializer.js
Expand Up @@ -12,7 +12,7 @@

const util = require("util"),
path = require("path"),
inquirer = require("inquirer"),
enquirer = require("enquirer"),
ProgressBar = require("progress"),
semver = require("semver"),
espree = require("espree"),
Expand Down Expand Up @@ -146,7 +146,7 @@ function getModulesList(config, installESLint) {
*
* Note: This clones the config object and returns a new config to avoid mutating
* the original config parameter.
* @param {Object} answers answers received from inquirer
* @param {Object} answers answers received from enquirer
* @param {Object} config config object
* @returns {Object} config object with configured rules
*/
Expand Down Expand Up @@ -253,7 +253,7 @@ function configureRules(answers, config) {

/**
* process user's answers and create config object
* @param {Object} answers answers received from inquirer
* @param {Object} answers answers received from enquirer
* @returns {Object} config object
*/
function processAnswers(answers) {
Expand Down Expand Up @@ -409,7 +409,7 @@ function installModules(modules) {
npmUtils.installSyncSaveDev(modules);
}

/* istanbul ignore next: no need to test inquirer */
/* istanbul ignore next: no need to test enquirer */
/**
* Ask user to install modules.
* @param {string[]} modules Array of modules to be installed.
Expand All @@ -425,14 +425,19 @@ function askInstallModules(modules, packageJsonExists) {

log.info("The config that you've selected requires the following dependencies:\n");
log.info(modules.join(" "));
return inquirer.prompt([
return enquirer.prompt([
{
type: "confirm",
type: "toggle",
name: "executeInstallation",
message: "Would you like to install them now with npm?",
default: true,
when() {
return modules.length && packageJsonExists;
enabled: "Yes",
disabled: "No",
initial: 1,
skip() {
return !(modules.length && packageJsonExists);
},
result(input) {
return this.skipped ? null : input;
}
}
]).then(({ executeInstallation }) => {
Expand All @@ -442,114 +447,124 @@ function askInstallModules(modules, packageJsonExists) {
});
}

/* istanbul ignore next: no need to test inquirer */
/* istanbul ignore next: no need to test enquirer */
/**
* Ask use a few questions on command prompt
* @returns {Promise} The promise with the result of the prompt
*/
function promptUser() {

return inquirer.prompt([
return enquirer.prompt([
{
type: "list",
type: "select",
name: "purpose",
message: "How would you like to use ESLint?",
default: "problems",

// The returned number matches the name value of nth in the choices array.
initial: 1,
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" }
{ message: "To check syntax only", name: "syntax" },
{ message: "To check syntax and find problems", name: "problems" },
{ message: "To check syntax, find problems, and enforce code style", name: "style" }
]
},
{
type: "list",
type: "select",
name: "moduleType",
message: "What type of modules does your project use?",
default: "esm",
initial: 0,
choices: [
{ name: "JavaScript modules (import/export)", value: "esm" },
{ name: "CommonJS (require/exports)", value: "commonjs" },
{ name: "None of these", value: "none" }
{ message: "JavaScript modules (import/export)", name: "esm" },
{ message: "CommonJS (require/exports)", name: "commonjs" },
{ message: "None of these", name: "none" }
]
},
{
type: "list",
type: "select",
name: "framework",
message: "Which framework does your project use?",
default: "react",
initial: 0,
choices: [
{ name: "React", value: "react" },
{ name: "Vue.js", value: "vue" },
{ name: "None of these", value: "none" }
{ message: "React", name: "react" },
{ message: "Vue.js", name: "vue" },
{ message: "None of these", name: "none" }
]
},
{
type: "confirm",
type: "toggle",
name: "typescript",
message: "Does your project use TypeScript?",
default: false
enabled: "Yes",
disabled: "No",
initial: 0
},
{
type: "checkbox",
type: "multiselect",
name: "env",
message: "Where does your code run?",
default: ["browser"],
hint: "(Press <space> to select, <a> to toggle all, <i> to invert selection)",
initial: 0,
choices: [
{ name: "Browser", value: "browser" },
{ name: "Node", value: "node" }
{ message: "Browser", name: "browser" },
{ message: "Node", name: "node" }
]
},
{
type: "list",
type: "select",
name: "source",
message: "How would you like to define a style for your project?",
default: "guide",
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" }
{ message: "Use a popular style guide", name: "guide" },
{ message: "Answer questions about your style", name: "prompt" },
{ message: "Inspect your JavaScript file(s)", name: "auto" }
],
when(answers) {
return answers.purpose === "style";
skip() {
return this.state.answers.purpose !== "style";
},
result(input) {
return this.skipped ? null : input;
}
},
{
type: "list",
type: "select",
name: "styleguide",
message: "Which style guide do you want to follow?",
choices: [
{ name: "Airbnb: https://github.com/airbnb/javascript", value: "airbnb" },
{ name: "Standard: https://github.com/standard/standard", value: "standard" },
{ name: "Google: https://github.com/google/eslint-config-google", value: "google" }
{ message: "Airbnb: https://github.com/airbnb/javascript", name: "airbnb" },
{ message: "Standard: https://github.com/standard/standard", name: "standard" },
{ message: "Google: https://github.com/google/eslint-config-google", name: "google" }
],
when(answers) {
answers.packageJsonExists = npmUtils.checkPackageJson();
return answers.source === "guide" && answers.packageJsonExists;
skip() {
this.state.answers.packageJsonExists = npmUtils.checkPackageJson();
return !(this.state.answers.source === "guide" && this.state.answers.packageJsonExists);
},
result(input) {
return this.skipped ? null : input;
}
},
{
type: "input",
name: "patterns",
message: "Which file(s), path(s), or glob(s) should be examined?",
when(answers) {
return (answers.source === "auto");
skip() {
return this.state.answers.source !== "auto";
},
validate(input) {
if (input.trim().length === 0 && input.trim() !== ",") {
if (!this.skipped && input.trim().length === 0 && input.trim() !== ",") {
return "You must tell us what code to examine. Try again.";
}
return true;
}
},
{
type: "list",
type: "select",
name: "format",
message: "What format do you want your config file to be in?",
default: "JavaScript",
initial: 0,
choices: ["JavaScript", "YAML", "JSON"]
},
{
type: "confirm",
type: "toggle",
name: "installESLint",
message(answers) {
const verb = semver.ltr(answers.localESLintVersion, answers.requiredESLintVersionRange)
Expand All @@ -558,9 +573,14 @@ function promptUser() {

return `The style guide "${answers.styleguide}" requires eslint@${answers.requiredESLintVersionRange}. You are currently using eslint@${answers.localESLintVersion}.\n Do you want to ${verb}?`;
},
default: true,
when(answers) {
return answers.source === "guide" && answers.packageJsonExists && hasESLintVersionConflict(answers);
enabled: "Yes",
disabled: "No",
initial: 1,
skip() {
return !(this.state.answers.source === "guide" && this.state.answers.packageJsonExists && hasESLintVersionConflict(this.state.answers));
},
result(input) {
return this.skipped ? null : input;
}
}
]).then(earlyAnswers => {
Expand Down Expand Up @@ -613,33 +633,35 @@ function promptUser() {
}

// continue with the style questions otherwise...
return inquirer.prompt([
return enquirer.prompt([
{
type: "list",
type: "select",
name: "indent",
message: "What style of indentation do you use?",
default: "tab",
choices: [{ name: "Tabs", value: "tab" }, { name: "Spaces", value: 4 }]
initial: 0,
choices: [{ message: "Tabs", name: "tab" }, { message: "Spaces", name: 4 }]
},
{
type: "list",
type: "select",
name: "quotes",
message: "What quotes do you use for strings?",
default: "double",
choices: [{ name: "Double", value: "double" }, { name: "Single", value: "single" }]
initial: 0,
choices: [{ message: "Double", name: "double" }, { message: "Single", name: "single" }]
},
{
type: "list",
type: "select",
name: "linebreak",
message: "What line endings do you use?",
default: "unix",
choices: [{ name: "Unix", value: "unix" }, { name: "Windows", value: "windows" }]
initial: 0,
choices: [{ message: "Unix", name: "unix" }, { message: "Windows", name: "windows" }]
},
{
type: "confirm",
type: "toggle",
name: "semi",
message: "Do you require semicolons?",
default: true
enabled: "Yes",
disabled: "No",
initial: 1
}
]).then(answers => {
const totalAnswers = Object.assign({}, earlyAnswers, answers);
Expand Down
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -52,6 +52,7 @@
"cross-spawn": "^7.0.2",
"debug": "^4.0.1",
"doctrine": "^3.0.0",
"enquirer": "^2.3.5",
"eslint-scope": "^5.1.0",
"eslint-utils": "^2.0.0",
"eslint-visitor-keys": "^1.2.0",
Expand All @@ -65,7 +66,6 @@
"ignore": "^4.0.6",
"import-fresh": "^3.0.0",
"imurmurhash": "^0.1.4",
"inquirer": "^7.0.0",
"is-glob": "^4.0.0",
"js-yaml": "^3.13.1",
"json-stable-stringify-without-jsonify": "^1.0.1",
Expand Down

0 comments on commit 7ce7988

Please sign in to comment.