Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

yeoman-generator

Package Overview
Dependencies
Maintainers
4
Versions
167
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

yeoman-generator - npm Package Compare versions

Comparing version 0.11.4 to 0.12.0

lib/util/common.js

16

lib/actions/actions.js

@@ -80,6 +80,7 @@ var logger = process.logging || require('./utils/log');

this.checkForCollision(destination, body, function (err, status) {
this.checkForCollision(destination, body, function (err, config) {
var stats;
if (err) {
config.callback(err);
return this.emit('error', err);

@@ -90,4 +91,4 @@ }

// actual write
if (!(/force|create/.test(status))) {
return;
if (!(/force|create/.test(config.status))) {
return config.callback();
}

@@ -106,2 +107,4 @@

}
config.callback();
}.bind(this));

@@ -139,4 +142,5 @@

actions.write = function write(filepath, content) {
this.checkForCollision(filepath, content, function (err, status) {
this.checkForCollision(filepath, content, function (err, config) {
if (err) {
config.callback(err);
return this.emit('error', err);

@@ -147,6 +151,8 @@ }

// actual write
if (/force|create/.test(status)) {
if (/force|create/.test(config.status)) {
mkdirp.sync(path.dirname(filepath));
fs.writeFileSync(filepath, content);
}
config.callback();
});

@@ -153,0 +159,0 @@ return this;

'use strict';
var prompt_ = require('prompt');
var _ = require('lodash');
var validate = require('revalidator').validate;
var inquirer = require('inquirer');
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.
// series, and call `done` callback on completion.
//
// Options can be any prompt's option: https://npmjs.org/package/prompt
// Options can be any prompt's option: https://github.com/SBoudrias/Inquirer.js
//
// - prompts - A single or an Array of Hash options.
// - prompts - an Array of Hash options.
// - done - Callback to call on error or on completion.
//
// Returns the generator instance.
module.exports = function prompt(prompts, done) {
prompts = Array.isArray(prompts) ? prompts : [prompts];
prompts = prompts.map(evaluatePrompts);
prompt_.colors = false;
prompt_.message = '[' + '?'.green + ']';
prompt_.delimiter = ' ';
prompt_.start();
var results = {};
(function next(prompt) {
function handleResult(err, value) {
if (err) {
return done(err);
}
results[prompt.name] = value[prompt.name];
next(prompts.shift());
}
if (!prompt) {
return done(null, results);
}
prompt_.get(prompt, handleResult);
})(prompts.shift());
module.exports = function prompt() {
inquirer.prompt.apply(inquirer, arguments);
return this;
};

@@ -91,2 +91,3 @@ var fs = require('fs');

_.extend(Base.prototype, require('./actions/wiring'));
_.extend(Base.prototype, require('./util/common'));
Base.prototype.prompt = require('./actions/prompt');

@@ -258,4 +259,5 @@ Base.prototype.invoke = require('./actions/invoke');

}
next();
});
next();
};

@@ -262,0 +264,0 @@

@@ -123,3 +123,3 @@ var fs = require('fs');

generator.prompt = function (prompts, done) {
done(null, answers);
done(answers);
};

@@ -126,0 +126,0 @@ generator.origPrompt = origPrompt;

@@ -9,2 +9,3 @@ var logger = process.logging || require('./log');

var log = logger('conflicter');
var async = require('async');

@@ -49,18 +50,26 @@ var conflicter = module.exports = Object.create(events.EventEmitter.prototype);

conflicter.resolve = function resolve(cb) {
var conflicts = this.conflicts;
(function next(conflict) {
if (!conflict) {
return cb();
}
conflicter.collision(conflict.file, conflict.content, function (err, status) {
if (err) {
return cb(err);
var resolveConflicts = function (conflict) {
return function (next) {
if (!conflict) {
return next();
}
conflicter.emit('resolved:' + conflict.file, status);
next(conflicts.shift());
});
conflicter.collision(conflict.file, conflict.content, function (status) {
conflicter.emit('resolved:' + conflict.file, {
status: status,
callback: next
});
});
};
};
})(conflicts.shift());
async.series(this.conflicts.map(resolveConflicts), function (err) {
if (err) {
cb();
return self.emit('error', err);
}
conflicter.reset();
cb();
}.bind(this));
};

@@ -73,63 +82,48 @@

var self = this;
var menu = [
' ' + 'Y'.bold + ' yes overwrite',
' ' + 'n'.bold + ' no do not overwrite',
' ' + 'a'.bold + ' all overwrite this and all others',
' ' + 'q'.bold + ' quit abort',
' ' + 'd'.bold + ' diff show the differences between the old and the new',
' ' + 'h'.bold + ' help show help'
].join('\n');
var config = {
message: ('Overwrite ' + filepath + '? (enter "h" for help) [Ynaqdh]?'),
name: 'overwrite',
default: 'h'
};
process.nextTick(function () {
self.emit('prompt', config);
self.emit('conflict', filepath);
});
prompt(config, function (err, result) {
if (err) {
return cb(err);
}
var answer = result.overwrite;
var ok = 'Yynaqdh'.split('').some(function (valid) {
return valid === answer;
});
if (answer === 'h' || !ok) {
console.log(menu);
return self._ask(filepath, content, cb);
}
if (answer === 'n') {
log.skip(filepath);
return cb(null, 'skip');
}
if (answer === 'q') {
log.writeln('Aborting...');
return process.exit(0);
}
if (/Y|a/i.test(answer)) {
log.force(filepath);
if (answer === 'a') {
var config = [{
type: 'list',
message: 'Overwrite ' + filepath + '?',
choices: [{
name: 'Overwrite',
value: function () {
log.force(filepath);
return cb('force');
}
}, {
name: 'do not overwrite',
value: function () {
log.skip(filepath);
return cb('skip');
}
}, {
name: 'overwrite this and all others',
value: function () {
log.force(filepath);
self.force = true;
return cb('force');
}
return cb(null, 'force');
}
}, {
name: 'abort',
value: function () {
log.writeln('Aborting ...');
return process.exit(0);
}
}, {
name: 'show the differences between the old and the new',
value: function () {
console.log(conflicter.diff(fs.readFileSync(filepath, 'utf8'), content));
return self._ask(filepath, content, cb);
}
}],
name: 'overwrite'
}];
if (answer === 'd') {
console.log(conflicter.diff(fs.readFileSync(filepath, 'utf8'), content));
return self._ask(filepath, content, cb);
}
process.nextTick(function () {
this.emit('prompt', config);
this.emit('conflict', filepath);
}.bind(this));
// default, even though we should have handled every possible value
return cb();
prompt(config, function (result) {
cb(result.overwrite());
});

@@ -143,3 +137,3 @@ };

log.create(filepath);
return cb(null, 'create');
return cb('create');
}

@@ -152,3 +146,3 @@

log.identical(filepath);
return cb(null, 'identical');
return cb('identical');
}

@@ -158,3 +152,3 @@

log.force(filepath);
return cb(null, 'force');
return cb('force');
}

@@ -161,0 +155,0 @@

{
"name": "yeoman-generator",
"version": "0.11.4",
"version": "0.12.0",
"description": "Rails-inspired generator system that provides scaffolding for your apps",

@@ -42,11 +42,10 @@ "keywords": [

"isbinaryfile": "~0.1.8",
"prompt": "~0.2.9",
"revalidator": "~0.1.5",
"dargs": "~0.1.0",
"async": "~0.2.8"
"async": "~0.2.8",
"inquirer": "~0.1.3"
},
"devDependencies": {
"mocha": "~1.9.0",
"mocha": "~1.10.0",
"proxyquire": "~0.4.0"
}
}

@@ -20,3 +20,3 @@ # Generator [![Build Status](https://secure.travis-ci.org/yeoman/generator.png?branch=master)](http://travis-ci.org/yeoman/generator)

There is currently no formal infrastructure for testing generators, however you may find our [mocha generator](https://github.com/yeoman/yeoman/wiki/Testing-generators) for custom generators useful.
There is currently no formal infrastructure for testing generators, however you may find our [mocha generator](https://github.com/yeoman/generator-mocha) for custom generators useful.

@@ -23,0 +23,0 @@ ## Officially maintained generators

@@ -35,3 +35,5 @@ /*global describe, before, it, afterEach, beforeEach */

it('generator.prompt(defaults, prompts, cb)', function (done) {
this.dummy.prompt([], done);
this.dummy.prompt([], function () {
done();
});
});

@@ -38,0 +40,0 @@

@@ -1,2 +0,2 @@

/*global describe, before, it */
/*global describe, before, beforeEach, it */
var fs = require('fs');

@@ -8,2 +8,3 @@ var path = require('path');

var generators = require('..');
var helpers = require('../lib/test/helpers');

@@ -69,2 +70,29 @@

describe('generator.run(args, cb) regression', function () {
beforeEach(function () {
var Unicorn = function () {
generators.Base.apply(this, arguments);
};
util.inherits(Unicorn, generators.Base);
Unicorn.prototype.test1 = function () {
this.async()();
};
Unicorn.prototype.test2 = function () {
// Nothing
};
this.unicorn = helpers.createGenerator('unicorn:app', [
[Unicorn, 'unicorn:app']
]);
});
it('should call `done` only once', function (done) {
// Mocha will fail if done was called more than once.
this.unicorn.run({}, done);
});
});
describe('generator.runHooks(cb)', function () {

@@ -71,0 +99,0 @@ it('should go through all registered hooks, and invoke them in series', function (done) {

@@ -42,3 +42,6 @@ /*global describe, before, it */

it('with at least one', function (done) {
it('with at least one, without async callback handling', function (done) {
var conflicts = 0;
var callbackExecuted = false;
conflicter.add(__filename);

@@ -50,4 +53,45 @@ conflicter.add({

conflicter.resolve(done);
// called.
conflicter.once('resolved:' + __filename, function (config) {
conflicts++;
});
// not called.
conflicter.once('resolved:foo.js', function (config) {
conflicts++;
});
conflicter.resolve(function(){
callbackExecuted = true;
});
assert(conflicts, 1);
assert(!callbackExecuted);
done();
});
it('with at least one, with async callback handling', function (done) {
var called = 0;
conflicter.add(__filename);
conflicter.add({
file: 'foo.js',
content: 'var foo = "foo";\n'
});
conflicter.once('resolved:' + __filename, function (config) {
called++;
config.callback();
});
conflicter.once('resolved:foo.js', function (config) {
called++;
config.callback();
});
conflicter.resolve(function(){
assert(called, 2);
done();
});
});
});

@@ -59,3 +103,3 @@

it('identical status', function(done) {
conflicter.collision(__filename, me, function (err, status) {
conflicter.collision(__filename, me, function (status) {
assert.equal(status, 'identical');

@@ -67,3 +111,3 @@ done();

it('create status', function (done) {
conflicter.collision('foo.js', '', function (err, status) {
conflicter.collision('foo.js', '', function (status) {
assert.equal(status, 'create');

@@ -75,3 +119,3 @@ done();

it('conflict status', function (done) {
conflicter.collision(__filename, '', function (err, status) {
conflicter.collision(__filename, '', function (status) {
assert.equal(status, 'force');

@@ -91,3 +135,3 @@ done();

prompt: function (config, cb) {
cb(this.err, { overwrite: this.answer });
cb({ overwrite: this.answer });
},

@@ -104,21 +148,11 @@ err: null,

it('skips on "n answer"', function (done) {
promptMock.answer = 'n';
this.conflicter._ask('/tmp/file', 'my file contents', function (err, result) {
assert.strictEqual(err, null);
assert(result, 'skip');
it('Calls answer related function', function (done) {
var callCount = 0;
promptMock.answer = function () { callCount++; };
this.conflicter._ask('/tmp/file', 'my file contents', function (result) {
assert(callCount, 1);
done();
});
});
it('enables force on "a" answer', function (done) {
promptMock.answer = 'a';
this.conflicter._ask('/tmp/file', 'my file contents', function (err, result) {
assert.strictEqual(err, null);
assert(result, 'force');
assert(this.conflicter.force);
done();
}.bind(this));
});
});
});

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc