Skip to content

Commit

Permalink
Merge pull request #213 from passy/new-prompt
Browse files Browse the repository at this point in the history
Prompt: Replaced 'read' with high-level 'prompt' library
  • Loading branch information
sindresorhus committed Apr 23, 2013
2 parents 0486c2c + 71495d8 commit 663ed3f
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 16 deletions.
104 changes: 92 additions & 12 deletions lib/actions/prompt.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,84 @@
var read = require('read');
'use strict';

var prompt_ = require('prompt');
var _ = require('lodash');
var validate = require('revalidator').validate;


function evaluatePrompts(prompt) {
if (_.isFunction(prompt.default)) {
prompt.default = prompt.default();
} else if (typeof prompt.default === 'boolean') {
// Handle boolean defaults as confirmation prompts.
var defaultMsg = prompt.default ? 'Y/n' : 'y/N';
prompt.default = defaultMsg;

prompt.validator = function (value) {
return value.match(/^([yYnN]|(y\/N)|(Y\/n))$/);
};
prompt.required = true;

prompt.before = function (val) {
if (val === 'Y/n' || val.toLowerCase() === 'y') {
return true;
} else if (val === 'y/N' || val.toLowerCase() === 'n') {
return false;
}

return val;
};
}

return prompt;
}

// Monkey-patching prompt._performValidation to get rid of the overly verbose
// error message.
//
// Arguments:
// - name {Object} Variable name
// - prop {Object|string} Variable to get input for.
// - against {Object} Input
// - schema {Object} Validation schema
// - line {String|Boolean} Input line
// - callback {function} Continuation to pass control to when complete.
//
// Perfoms user input validation, print errors if needed and returns value
// according to validation
//
prompt_._performValidation = function (name, prop, against, schema, line, callback) {
var numericInput, valid, msg;

try {
valid = validate(against, schema);
} catch (err) {
return (line !== -1) ? callback(err) : false;
}

if (!valid.valid) {
msg = 'Invalid input';

if (prompt_.colors) {
prompt_.logger.error(msg);
} else {
prompt_.logger.error(msg);
}

if (prop.schema.message) {
prompt_.logger.error(prop.schema.message);
}

prompt_.emit('invalid', prop, line);
}

return valid.valid;
};

// Prompt for user input based on the given Array of `prompts` to perform in
// series, and call `done` callback on completion. `prompts` can be a single
// Hash of options in which case a single prompt is performed.
//
// Options can be any read's option: https://github.com/isaacs/read#options
// Options can be any prompt's option: https://npmjs.org/package/prompt
//
// - prompts - A single or an Array of Hash options.
// - done - Callback to call on error or on completion.
Expand All @@ -13,23 +87,29 @@ var read = require('read');
module.exports = function prompt(prompts, done) {
prompts = Array.isArray(prompts) ? prompts : [prompts];

var results = {};
(function next(prompt) {
if (!prompt) {
return done(null, results);
}
prompts = prompts.map(evaluatePrompts);

if (!prompt.prompt) {
prompt.prompt = prompt.message;
}
prompt_.message = '[' + '?'.green + ']';
prompt_.delimiter = ' ';
prompt_.start();

read(prompt, function (err, value) {
var results = {};
(function next(prompt) {
function handleResult(err, value) {
if (err) {
return done(err);
}

results[prompt.name] = value;
next(prompts.shift());
});
}

if (!prompt) {
return done(null, results);
}

prompt_.get(prompt, handleResult);
})(prompts.shift());

return this;
};
2 changes: 1 addition & 1 deletion lib/util/conflicter.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ conflicter._ask = function (filepath, content, cb) {
return cb(err);
}

var answer = result.overwrite;
var answer = result.overwrite.overwrite;

var ok = 'Yynaqdh'.split('').some(function (valid) {
return valid === answer;
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,13 @@
"underscore.string": "~2.3.1",
"lodash": "~1.1.1",
"mkdirp": "~0.3.5",
"read": "~1.0.4",
"glob": "~3.1.21",
"nopt": "~2.1.1",
"cli-table": "~0.2.0",
"debug": "~0.7.2",
"isbinaryfile": "~0.1.8"
"isbinaryfile": "~0.1.8",
"prompt": "~0.2.9",
"revalidator": "~0.1.5"
},
"devDependencies": {
"mocha": "~1.9.0",
Expand Down
2 changes: 1 addition & 1 deletion test/conflicter.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ describe('conflicter', function () {
describe('conflicter#_ask', function () {
var promptMock = {
prompt: function (config, cb) {
cb(this.err, { overwrite: this.answer });
cb(this.err, { overwrite: { overwrite: this.answer } });
},
err: null,
answer: null
Expand Down

0 comments on commit 663ed3f

Please sign in to comment.