I am trying to create a small build script which will ask the user for the location to the mysql headers if they are not found in the default path. Right now I am using inquirer
to prompt the user for input which works fine, but I have encountered the following problem:
'use strict'
const inquirer = require('inquirer')
const fs = require('fs')
const MYSQL_INCLUDE_DIR = '/usr/include/mysql'
let questions = [
{
type: 'input',
name: 'MYSQL_INCLUDE_DIR',
message: 'Enter path to mysql headers',
default: MYSQL_INCLUDE_DIR,
when: (answers) => {
return !fs.existsSync(MYSQL_INCLUDE_DIR)
},
validate: (path) => {
return fs.existsSync(path)
}
}
]
inquirer.prompt(questions)
.then((answers) => {
// Problem is that answers.MYSQL_INCLUDE_DIR might be undefined at this point.
})
If the default path to the mysql headers are found then the question will not be displayed and therefor the answer will not be set. How can I set a default value for a question without actually showing it to the user?
Solving the above would also make it possible to do this instead of using the global variable:
let questions = [
{
type: 'input',
name: 'MYSQL_INCLUDE_DIR',
message: 'Enter path to mysql headers',
default: MYSQL_INCLUDE_DIR,
when: (answers) => {
return !fs.existsSync(answers.MYSQL_INCLUDE_DIR)
},
validate: (path) => {
return fs.existsSync(path)
}
}
]
How about:
inquirer.prompt(questions)
.then((answers) => {
const mysqlIncludeDir = answers && answers.MYSQL_INCLUDE_DIR ? answers.MYSQL_INCLUDE_DIR : MYSQL_INCLUDE_DIR;
})
Or more succinctly:
inquirer.prompt(questions)
.then((answers) => {
const theAnswers = {
MYSQL_INCLUDE_DIR,
...answers
};
// theAnswers should be the answers you want
const mysqlIncludeDir = theAnswers.MYSQL_INCLUDE_DIR;
// mysqlIncludeDir should now be same as first solution above
})
Or more generically with the help of lodash, something like:
const myPrompt = (questions) => inquirer.prompt(questions)
.then((answers) => {
return {
...(_.omitBy(_.mapValues(_.keyBy(questions, 'name'), 'default'), q => !q)),
...answers
};
})
myPrompt(questions)
.then((answers) => {
// should be the answers you want
})
That last solution should cause any question with a default
, and a when
which could otherwise hide its default, to have its default forcefully included in the answers.