yeoman-generator 2.0.5 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/actions/help.js +13 -21
- package/lib/actions/install.js +84 -86
- package/lib/actions/spawn-command.js +10 -8
- package/lib/actions/user.js +2 -2
- package/lib/index.js +200 -127
- package/lib/util/binary-diff.js +13 -13
- package/lib/util/conflicter.js +25 -21
- package/lib/util/deprecate.js +2 -2
- package/lib/util/prompt-suggestion.js +4 -2
- package/lib/util/storage.js +1 -3
- package/package.json +70 -47
package/lib/actions/help.js
CHANGED
|
@@ -13,33 +13,23 @@ const help = module.exports;
|
|
|
13
13
|
/**
|
|
14
14
|
* Tries to get the description from a USAGE file one folder above the
|
|
15
15
|
* source root otherwise uses a default description
|
|
16
|
+
*
|
|
17
|
+
* @return {String} Help message of the generator
|
|
16
18
|
*/
|
|
17
|
-
help.help = function
|
|
19
|
+
help.help = function() {
|
|
18
20
|
const filepath = path.resolve(this.sourceRoot(), '../USAGE');
|
|
19
21
|
const exists = fs.existsSync(filepath);
|
|
20
22
|
|
|
21
|
-
let out = [
|
|
22
|
-
'Usage:',
|
|
23
|
-
' ' + this.usage(),
|
|
24
|
-
''
|
|
25
|
-
];
|
|
23
|
+
let out = ['Usage:', ' ' + this.usage(), ''];
|
|
26
24
|
|
|
27
25
|
// Build options
|
|
28
26
|
if (Object.keys(this._options).length > 0) {
|
|
29
|
-
out = out.concat([
|
|
30
|
-
'Options:',
|
|
31
|
-
this.optionsHelp(),
|
|
32
|
-
''
|
|
33
|
-
]);
|
|
27
|
+
out = out.concat(['Options:', this.optionsHelp(), '']);
|
|
34
28
|
}
|
|
35
29
|
|
|
36
30
|
// Build arguments
|
|
37
31
|
if (this._arguments.length > 0) {
|
|
38
|
-
out = out.concat([
|
|
39
|
-
'Arguments:',
|
|
40
|
-
this.argumentsHelp(),
|
|
41
|
-
''
|
|
42
|
-
]);
|
|
32
|
+
out = out.concat(['Arguments:', this.argumentsHelp(), '']);
|
|
43
33
|
}
|
|
44
34
|
|
|
45
35
|
// Append USAGE file is any
|
|
@@ -63,8 +53,10 @@ function formatArg(config) {
|
|
|
63
53
|
/**
|
|
64
54
|
* Output usage information for this given generator, depending on its arguments
|
|
65
55
|
* or options
|
|
56
|
+
*
|
|
57
|
+
* @return {String} Usage information of the generator
|
|
66
58
|
*/
|
|
67
|
-
help.usage = function
|
|
59
|
+
help.usage = function() {
|
|
68
60
|
const options = Object.keys(this._options).length ? '[options]' : '';
|
|
69
61
|
let name = this.options.namespace;
|
|
70
62
|
let args = '';
|
|
@@ -89,7 +81,7 @@ help.usage = function () {
|
|
|
89
81
|
* @param {String} description
|
|
90
82
|
*/
|
|
91
83
|
|
|
92
|
-
help.desc = function
|
|
84
|
+
help.desc = function(description) {
|
|
93
85
|
this.description = description || '';
|
|
94
86
|
return this;
|
|
95
87
|
};
|
|
@@ -98,7 +90,7 @@ help.desc = function (description) {
|
|
|
98
90
|
* Get help text for arguments
|
|
99
91
|
* @returns {String} Text of options in formatted table
|
|
100
92
|
*/
|
|
101
|
-
help.argumentsHelp = function
|
|
93
|
+
help.argumentsHelp = function() {
|
|
102
94
|
const rows = this._arguments.map(config => {
|
|
103
95
|
return [
|
|
104
96
|
'',
|
|
@@ -116,7 +108,7 @@ help.argumentsHelp = function () {
|
|
|
116
108
|
* Get help text for options
|
|
117
109
|
* @returns {String} Text of options in formatted table
|
|
118
110
|
*/
|
|
119
|
-
help.optionsHelp = function
|
|
111
|
+
help.optionsHelp = function() {
|
|
120
112
|
const options = _.reject(this._options, x => x.hide);
|
|
121
113
|
|
|
122
114
|
const rows = options.map(opt => {
|
|
@@ -125,7 +117,7 @@ help.optionsHelp = function () {
|
|
|
125
117
|
opt.alias ? `-${opt.alias}, ` : '',
|
|
126
118
|
`--${opt.name}`,
|
|
127
119
|
opt.description ? `# ${opt.description}` : '',
|
|
128
|
-
|
|
120
|
+
opt.default !== undefined && opt.default !== '' ? 'Default: ' + opt.default : ''
|
|
129
121
|
];
|
|
130
122
|
});
|
|
131
123
|
|
package/lib/actions/install.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
const assert = require('assert');
|
|
3
3
|
const _ = require('lodash');
|
|
4
4
|
const dargs = require('dargs');
|
|
5
|
-
const async = require('async');
|
|
6
5
|
const chalk = require('chalk');
|
|
7
6
|
|
|
8
7
|
/**
|
|
@@ -15,63 +14,82 @@ const install = module.exports;
|
|
|
15
14
|
* Combine package manager cmd line arguments and run the `install` command.
|
|
16
15
|
*
|
|
17
16
|
* During the `install` step, every command will be scheduled to run once, on the
|
|
18
|
-
* run loop.
|
|
19
|
-
* return it or mix it with `this.async` as it'll dead lock the process.
|
|
17
|
+
* run loop.
|
|
20
18
|
*
|
|
21
19
|
* @param {String} installer Which package manager to use
|
|
22
20
|
* @param {String|Array} [paths] Packages to install. Use an empty string for `npm install`
|
|
23
21
|
* @param {Object} [options] Options to pass to `dargs` as arguments
|
|
24
22
|
* @param {Object} [spawnOptions] Options to pass `child_process.spawn`. ref
|
|
25
23
|
* https://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options
|
|
26
|
-
* @return {Promise} Resolved on installation success, rejected otherwise
|
|
27
24
|
*/
|
|
28
25
|
|
|
29
|
-
install.
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
paths = Array.isArray(paths) ? paths : (paths && paths.split(' ')) || [];
|
|
26
|
+
install.scheduleInstallTask = function(installer, paths, options, spawnOptions) {
|
|
27
|
+
options = options || {};
|
|
28
|
+
spawnOptions = spawnOptions || {};
|
|
29
|
+
paths = Array.isArray(paths) ? paths : (paths && paths.split(' ')) || [];
|
|
34
30
|
|
|
35
|
-
|
|
31
|
+
let args = ['install'].concat(paths).concat(dargs(options));
|
|
36
32
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
33
|
+
// Yarn uses the `add` command to specifically add a package to a project
|
|
34
|
+
if (installer === 'yarn' && paths.length > 0) {
|
|
35
|
+
args[0] = 'add';
|
|
36
|
+
}
|
|
41
37
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
38
|
+
// Only for npm, use a minimum cache of one day
|
|
39
|
+
if (installer === 'npm') {
|
|
40
|
+
args = args.concat(['--cache-min', 24 * 60 * 60]);
|
|
41
|
+
}
|
|
46
42
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
43
|
+
// Return early if we're skipping installation
|
|
44
|
+
if (this.options.skipInstall || this.options['skip-install']) {
|
|
45
|
+
this.log(
|
|
46
|
+
'Skipping install command: ' + chalk.yellow(installer + ' ' + args.join(' '))
|
|
47
|
+
);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
52
50
|
|
|
53
|
-
|
|
51
|
+
this.env.runLoop.add(
|
|
52
|
+
'install',
|
|
53
|
+
done => {
|
|
54
54
|
this.emit(`${installer}Install`, paths);
|
|
55
55
|
this.spawnCommand(installer, args, spawnOptions)
|
|
56
|
-
.on('error',
|
|
57
|
-
this.log(
|
|
58
|
-
'
|
|
59
|
-
|
|
60
|
-
|
|
56
|
+
.on('error', error => {
|
|
57
|
+
this.log(
|
|
58
|
+
chalk.red('Could not finish installation. \n') +
|
|
59
|
+
'Please install ' +
|
|
60
|
+
installer +
|
|
61
|
+
' with ' +
|
|
62
|
+
chalk.yellow('npm install -g ' + installer) +
|
|
63
|
+
' and try again. \n' +
|
|
64
|
+
'If ' +
|
|
65
|
+
installer +
|
|
66
|
+
' is already installed, try running the following command manually: ' +
|
|
67
|
+
chalk.yellow(installer + ' ' + args.join(' '))
|
|
61
68
|
);
|
|
62
|
-
|
|
69
|
+
if (this.options.forceInstall || this.options['force-install']) {
|
|
70
|
+
this.emit('error', error);
|
|
71
|
+
}
|
|
63
72
|
done();
|
|
64
73
|
})
|
|
65
|
-
.on('exit', () => {
|
|
74
|
+
.on('exit', (code, signal) => {
|
|
66
75
|
this.emit(`${installer}Install:end`, paths);
|
|
67
|
-
|
|
76
|
+
if (
|
|
77
|
+
(code || signal) &&
|
|
78
|
+
(this.options.forceInstall || this.options['force-install'])
|
|
79
|
+
) {
|
|
80
|
+
this.emit(
|
|
81
|
+
'error',
|
|
82
|
+
new Error(`Installation of ${installer} failed with code ${code || signal}`)
|
|
83
|
+
);
|
|
84
|
+
}
|
|
68
85
|
done();
|
|
69
86
|
});
|
|
70
|
-
},
|
|
87
|
+
},
|
|
88
|
+
{
|
|
71
89
|
once: installer + ' ' + args.join(' '),
|
|
72
90
|
run: false
|
|
73
|
-
}
|
|
74
|
-
|
|
91
|
+
}
|
|
92
|
+
);
|
|
75
93
|
};
|
|
76
94
|
|
|
77
95
|
/**
|
|
@@ -82,30 +100,30 @@ install.runInstall = function (installer, paths, options, spawnOptions) {
|
|
|
82
100
|
* this.installDependencies({
|
|
83
101
|
* bower: true,
|
|
84
102
|
* npm: true
|
|
85
|
-
* })
|
|
103
|
+
* });
|
|
86
104
|
*
|
|
87
105
|
* @example
|
|
88
106
|
* this.installDependencies({
|
|
89
107
|
* yarn: {force: true},
|
|
90
108
|
* npm: false
|
|
91
|
-
* })
|
|
109
|
+
* });
|
|
92
110
|
*
|
|
93
111
|
* @param {Object} [options]
|
|
94
112
|
* @param {Boolean|Object} [options.npm=true] - whether to run `npm install` or can be options to pass to `dargs` as arguments
|
|
95
113
|
* @param {Boolean|Object} [options.bower=true] - whether to run `bower install` or can be options to pass to `dargs` as arguments
|
|
96
114
|
* @param {Boolean|Object} [options.yarn=false] - whether to run `yarn install` or can be options to pass to `dargs` as arguments
|
|
97
115
|
* @param {Boolean} [options.skipMessage=false] - whether to log the used commands
|
|
98
|
-
* @return {Promise} Resolved once done, rejected if errors
|
|
99
116
|
*/
|
|
100
|
-
install.installDependencies = function
|
|
117
|
+
install.installDependencies = function(options) {
|
|
101
118
|
options = options || {};
|
|
102
|
-
const commands = [];
|
|
103
119
|
const msg = {
|
|
104
120
|
commands: [],
|
|
105
|
-
template: _.template(
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
121
|
+
template: _.template(
|
|
122
|
+
"\n\nI'm all done. " +
|
|
123
|
+
'<%= skipInstall ? "Just run" : "Running" %> <%= commands %> ' +
|
|
124
|
+
'<%= skipInstall ? "" : "for you " %>to install the required dependencies.' +
|
|
125
|
+
'<% if (!skipInstall) { %> If this fails, try running the command yourself.<% } %>\n\n'
|
|
126
|
+
)
|
|
109
127
|
};
|
|
110
128
|
|
|
111
129
|
const getOptions = options => {
|
|
@@ -114,53 +132,36 @@ install.installDependencies = function (options) {
|
|
|
114
132
|
|
|
115
133
|
if (options.npm !== false) {
|
|
116
134
|
msg.commands.push('npm install');
|
|
117
|
-
|
|
118
|
-
this.npmInstall(null, getOptions(options.npm)).then(
|
|
119
|
-
val => cb(null, val),
|
|
120
|
-
cb
|
|
121
|
-
);
|
|
122
|
-
});
|
|
135
|
+
this.npmInstall(null, getOptions(options.npm));
|
|
123
136
|
}
|
|
124
137
|
|
|
125
138
|
if (options.yarn) {
|
|
126
139
|
msg.commands.push('yarn install');
|
|
127
|
-
|
|
128
|
-
this.yarnInstall(null, getOptions(options.yarn)).then(
|
|
129
|
-
val => cb(null, val),
|
|
130
|
-
cb
|
|
131
|
-
);
|
|
132
|
-
});
|
|
140
|
+
this.yarnInstall(null, getOptions(options.yarn));
|
|
133
141
|
}
|
|
134
142
|
|
|
135
143
|
if (options.bower !== false) {
|
|
136
144
|
msg.commands.push('bower install');
|
|
137
|
-
|
|
138
|
-
this.bowerInstall(null, getOptions(options.bower)).then(
|
|
139
|
-
val => cb(null, val),
|
|
140
|
-
cb
|
|
141
|
-
);
|
|
142
|
-
});
|
|
145
|
+
this.bowerInstall(null, getOptions(options.bower));
|
|
143
146
|
}
|
|
144
147
|
|
|
145
|
-
assert(
|
|
148
|
+
assert(
|
|
149
|
+
msg.commands.length,
|
|
150
|
+
'installDependencies needs at least one of `npm`, `bower` or `yarn` to run.'
|
|
151
|
+
);
|
|
146
152
|
|
|
147
153
|
if (!options.skipMessage) {
|
|
148
|
-
const tplValues = _.extend(
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
154
|
+
const tplValues = _.extend(
|
|
155
|
+
{
|
|
156
|
+
skipInstall: false
|
|
157
|
+
},
|
|
158
|
+
this.options,
|
|
159
|
+
{
|
|
160
|
+
commands: chalk.yellow.bold(msg.commands.join(' && '))
|
|
161
|
+
}
|
|
162
|
+
);
|
|
153
163
|
this.log(msg.template(tplValues));
|
|
154
164
|
}
|
|
155
|
-
|
|
156
|
-
return new Promise((resolve, reject) => {
|
|
157
|
-
async.parallel(commands, (err, results) => {
|
|
158
|
-
if (err) {
|
|
159
|
-
return reject(err);
|
|
160
|
-
}
|
|
161
|
-
resolve(results);
|
|
162
|
-
});
|
|
163
|
-
});
|
|
164
165
|
};
|
|
165
166
|
|
|
166
167
|
/**
|
|
@@ -171,10 +172,9 @@ install.installDependencies = function (options) {
|
|
|
171
172
|
* @param {String|Array} [cmpnt] Components to install
|
|
172
173
|
* @param {Object} [options] Options to pass to `dargs` as arguments
|
|
173
174
|
* @param {Object} [spawnOptions] Options to pass `child_process.spawn`.
|
|
174
|
-
* @return {Promise} Resolved if install successful, rejected otherwise
|
|
175
175
|
*/
|
|
176
|
-
install.bowerInstall = function
|
|
177
|
-
|
|
176
|
+
install.bowerInstall = function(cmpnt, options, spawnOptions) {
|
|
177
|
+
this.scheduleInstallTask('bower', cmpnt, options, spawnOptions);
|
|
178
178
|
};
|
|
179
179
|
|
|
180
180
|
/**
|
|
@@ -185,10 +185,9 @@ install.bowerInstall = function (cmpnt, options, spawnOptions) {
|
|
|
185
185
|
* @param {String|Array} [pkgs] Packages to install
|
|
186
186
|
* @param {Object} [options] Options to pass to `dargs` as arguments
|
|
187
187
|
* @param {Object} [spawnOptions] Options to pass `child_process.spawn`.
|
|
188
|
-
* @return {Promise} Resolved if install successful, rejected otherwise
|
|
189
188
|
*/
|
|
190
|
-
install.npmInstall = function
|
|
191
|
-
|
|
189
|
+
install.npmInstall = function(pkgs, options, spawnOptions) {
|
|
190
|
+
this.scheduleInstallTask('npm', pkgs, options, spawnOptions);
|
|
192
191
|
};
|
|
193
192
|
|
|
194
193
|
/**
|
|
@@ -199,8 +198,7 @@ install.npmInstall = function (pkgs, options, spawnOptions) {
|
|
|
199
198
|
* @param {String|Array} [pkgs] Packages to install
|
|
200
199
|
* @param {Object} [options] Options to pass to `dargs` as arguments
|
|
201
200
|
* @param {Object} [spawnOptions] Options to pass `child_process.spawn`.
|
|
202
|
-
* @return {Promise} Resolved if install successful, rejected otherwise
|
|
203
201
|
*/
|
|
204
|
-
install.yarnInstall = function
|
|
205
|
-
|
|
202
|
+
install.yarnInstall = function(pkgs, options, spawnOptions) {
|
|
203
|
+
this.scheduleInstallTask('yarn', pkgs, options, spawnOptions);
|
|
206
204
|
};
|
|
@@ -11,23 +11,25 @@ const spawnCommand = module.exports;
|
|
|
11
11
|
/**
|
|
12
12
|
* Normalize a command across OS and spawn it (asynchronously).
|
|
13
13
|
*
|
|
14
|
-
* @param {String} command
|
|
15
|
-
* @param {Array} args
|
|
16
|
-
* @param {object} [opt]
|
|
14
|
+
* @param {String} command program to execute
|
|
15
|
+
* @param {Array} args list of arguments to pass to the program
|
|
16
|
+
* @param {object} [opt] any cross-spawn options
|
|
17
|
+
* @return {String} spawned process reference
|
|
17
18
|
*/
|
|
18
19
|
spawnCommand.spawnCommand = (command, args, opt) => {
|
|
19
20
|
opt = opt || {};
|
|
20
|
-
return spawn(command, args, _.defaults(opt, {stdio: 'inherit'}));
|
|
21
|
+
return spawn(command, args, _.defaults(opt, { stdio: 'inherit' }));
|
|
21
22
|
};
|
|
22
23
|
|
|
23
24
|
/**
|
|
24
25
|
* Normalize a command across OS and spawn it (synchronously).
|
|
25
26
|
*
|
|
26
|
-
* @param {String} command
|
|
27
|
-
* @param {Array} args
|
|
28
|
-
* @param {object} [opt]
|
|
27
|
+
* @param {String} command program to execute
|
|
28
|
+
* @param {Array} args list of arguments to pass to the program
|
|
29
|
+
* @param {object} [opt] any cross-spawn options
|
|
30
|
+
* @return {String} spawn.sync result
|
|
29
31
|
*/
|
|
30
32
|
spawnCommand.spawnCommandSync = (command, args, opt) => {
|
|
31
33
|
opt = opt || {};
|
|
32
|
-
return spawn.sync(command, args, _.defaults(opt, {stdio: 'inherit'}));
|
|
34
|
+
return spawn.sync(command, args, _.defaults(opt, { stdio: 'inherit' }));
|
|
33
35
|
};
|
package/lib/actions/user.js
CHANGED
|
@@ -27,7 +27,7 @@ user.git.name = () => {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
if (shell.which('git')) {
|
|
30
|
-
name = shell.exec('git config --get user.name', {silent: true}).stdout.trim();
|
|
30
|
+
name = shell.exec('git config --get user.name', { silent: true }).stdout.trim();
|
|
31
31
|
nameCache.set(process.cwd(), name);
|
|
32
32
|
}
|
|
33
33
|
|
|
@@ -47,7 +47,7 @@ user.git.email = () => {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
if (shell.which('git')) {
|
|
50
|
-
email = shell.exec('git config --get user.email', {silent: true}).stdout.trim();
|
|
50
|
+
email = shell.exec('git config --get user.email', { silent: true }).stdout.trim();
|
|
51
51
|
emailCache.set(process.cwd(), email);
|
|
52
52
|
}
|
|
53
53
|
|
package/lib/index.js
CHANGED
|
@@ -75,7 +75,7 @@ class Generator extends EventEmitter {
|
|
|
75
75
|
this.option('help', {
|
|
76
76
|
type: Boolean,
|
|
77
77
|
alias: 'h',
|
|
78
|
-
description:
|
|
78
|
+
description: "Print the generator's options and usage"
|
|
79
79
|
});
|
|
80
80
|
|
|
81
81
|
this.option('skip-cache', {
|
|
@@ -90,9 +90,21 @@ class Generator extends EventEmitter {
|
|
|
90
90
|
default: false
|
|
91
91
|
});
|
|
92
92
|
|
|
93
|
+
this.option('force-install', {
|
|
94
|
+
type: Boolean,
|
|
95
|
+
description: 'Fail on install dependencies error',
|
|
96
|
+
default: false
|
|
97
|
+
});
|
|
98
|
+
|
|
93
99
|
// Checks required parameters
|
|
94
|
-
assert(
|
|
95
|
-
|
|
100
|
+
assert(
|
|
101
|
+
this.options.env,
|
|
102
|
+
'You must provide the environment object. Use env#create() to create a new generator.'
|
|
103
|
+
);
|
|
104
|
+
assert(
|
|
105
|
+
this.options.resolved,
|
|
106
|
+
'You must provide the resolved path value. Use env#create() to create a new generator.'
|
|
107
|
+
);
|
|
96
108
|
this.env = this.options.env;
|
|
97
109
|
this.resolved = this.options.resolved;
|
|
98
110
|
|
|
@@ -122,11 +134,13 @@ class Generator extends EventEmitter {
|
|
|
122
134
|
rootPath = rootPath ? path.dirname(rootPath) : this.env.cwd;
|
|
123
135
|
|
|
124
136
|
if (rootPath !== this.env.cwd) {
|
|
125
|
-
this.log(
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
137
|
+
this.log(
|
|
138
|
+
[
|
|
139
|
+
'',
|
|
140
|
+
'Just found a `.yo-rc.json` in a parent directory.',
|
|
141
|
+
'Setting the project root at: ' + rootPath
|
|
142
|
+
].join('\n')
|
|
143
|
+
);
|
|
130
144
|
this.destinationRoot(rootPath);
|
|
131
145
|
}
|
|
132
146
|
|
|
@@ -153,7 +167,7 @@ class Generator extends EventEmitter {
|
|
|
153
167
|
questions = promptSuggestion.prefillQuestions(this.config, questions);
|
|
154
168
|
|
|
155
169
|
return this.env.adapter.prompt(questions).then(answers => {
|
|
156
|
-
if (!this.options['skip-cache']) {
|
|
170
|
+
if (!this.options['skip-cache'] && !this.options.skipCache) {
|
|
157
171
|
promptSuggestion.storeAnswers(this._globalConfig, questions, answers, false);
|
|
158
172
|
promptSuggestion.storeAnswers(this.config, questions, answers, true);
|
|
159
173
|
}
|
|
@@ -198,12 +212,17 @@ class Generator extends EventEmitter {
|
|
|
198
212
|
const boolOptionRegex = /^no-/;
|
|
199
213
|
if (config.type === Boolean && name.match(boolOptionRegex)) {
|
|
200
214
|
const simpleName = name.replace(boolOptionRegex, '');
|
|
201
|
-
return this.emit(
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
215
|
+
return this.emit(
|
|
216
|
+
'error',
|
|
217
|
+
new Error(
|
|
218
|
+
[
|
|
219
|
+
`Option name ${chalk.yellow(name)} cannot start with ${chalk.red('no-')}\n`,
|
|
220
|
+
`Option name prefixed by ${chalk.yellow('--no')} are parsed as implicit`,
|
|
221
|
+
` boolean. To use ${chalk.yellow('--' + name)} as an option, use\n`,
|
|
222
|
+
chalk.cyan(` this.option('${simpleName}', {type: Boolean})`)
|
|
223
|
+
].join('')
|
|
224
|
+
)
|
|
225
|
+
);
|
|
207
226
|
}
|
|
208
227
|
|
|
209
228
|
if (this._options[name] === null || this._options[name] === undefined) {
|
|
@@ -348,7 +367,10 @@ class Generator extends EventEmitter {
|
|
|
348
367
|
// If the help option was not provided, check whether the argument was
|
|
349
368
|
// required, and whether a value was provided.
|
|
350
369
|
if (config.required && position >= this.args.length) {
|
|
351
|
-
return this.emit(
|
|
370
|
+
return this.emit(
|
|
371
|
+
'error',
|
|
372
|
+
new Error(`Did not provide required argument ${chalk.bold(config.name)}!`)
|
|
373
|
+
);
|
|
352
374
|
}
|
|
353
375
|
});
|
|
354
376
|
}
|
|
@@ -364,154 +386,205 @@ class Generator extends EventEmitter {
|
|
|
364
386
|
* provided, the same values used to initialize the invoker are used to
|
|
365
387
|
* initialize the invoked.
|
|
366
388
|
*
|
|
367
|
-
* @param {Function} [cb]
|
|
389
|
+
* @param {Function} [cb] Deprecated: prefer to use the promise interface
|
|
390
|
+
* @return {Promise} Resolved once the process finish
|
|
368
391
|
*/
|
|
369
392
|
run(cb) {
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
// Ensure a prototype method is a candidate run by default
|
|
386
|
-
function methodIsValid(name) {
|
|
387
|
-
return name.charAt(0) !== '_' && name !== 'constructor';
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
function addMethod(method, methodName, queueName) {
|
|
391
|
-
queueName = queueName || 'default';
|
|
392
|
-
debug(`Queueing ${methodName} in ${queueName}`);
|
|
393
|
-
self.env.runLoop.add(queueName, completed => {
|
|
394
|
-
debug(`Running ${methodName}`);
|
|
395
|
-
self.emit(`method:${methodName}`);
|
|
396
|
-
|
|
397
|
-
runAsync(function () {
|
|
398
|
-
self.async = () => this.async();
|
|
399
|
-
return method.apply(self, self.args);
|
|
400
|
-
})().then(completed).catch(err => {
|
|
401
|
-
debug(`An error occured while running ${methodName}`, err);
|
|
402
|
-
|
|
403
|
-
// Ensure we emit the error event outside the promise context so it won't be
|
|
404
|
-
// swallowed when there's no listeners.
|
|
405
|
-
setImmediate(() => {
|
|
406
|
-
self.emit('error', err);
|
|
407
|
-
cb(err);
|
|
408
|
-
});
|
|
409
|
-
});
|
|
393
|
+
const promise = new Promise((resolve, reject) => {
|
|
394
|
+
const self = this;
|
|
395
|
+
this._running = true;
|
|
396
|
+
this.emit('run');
|
|
397
|
+
|
|
398
|
+
const methods = Object.getOwnPropertyNames(Object.getPrototypeOf(this));
|
|
399
|
+
const validMethods = methods.filter(methodIsValid);
|
|
400
|
+
assert(
|
|
401
|
+
validMethods.length,
|
|
402
|
+
'This Generator is empty. Add at least one method for it to run.'
|
|
403
|
+
);
|
|
404
|
+
|
|
405
|
+
this.env.runLoop.once('end', () => {
|
|
406
|
+
this.emit('end');
|
|
407
|
+
resolve();
|
|
410
408
|
});
|
|
411
|
-
}
|
|
412
409
|
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
// Name points to a function; run it!
|
|
418
|
-
if (typeof item === 'function') {
|
|
419
|
-
return addMethod(item, name, queueName);
|
|
410
|
+
// Ensure a prototype method is a candidate run by default
|
|
411
|
+
function methodIsValid(name) {
|
|
412
|
+
return name.charAt(0) !== '_' && name !== 'constructor';
|
|
420
413
|
}
|
|
421
414
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
415
|
+
function addMethod(method, methodName, queueName) {
|
|
416
|
+
queueName = queueName || 'default';
|
|
417
|
+
debug(`Queueing ${methodName} in ${queueName}`);
|
|
418
|
+
self.env.runLoop.add(queueName, completed => {
|
|
419
|
+
debug(`Running ${methodName}`);
|
|
420
|
+
self.emit(`method:${methodName}`);
|
|
421
|
+
|
|
422
|
+
runAsync(function() {
|
|
423
|
+
self.async = () => this.async();
|
|
424
|
+
return method.apply(self, self.args);
|
|
425
|
+
})()
|
|
426
|
+
.then(completed)
|
|
427
|
+
.catch(err => {
|
|
428
|
+
debug(`An error occured while running ${methodName}`, err);
|
|
429
|
+
|
|
430
|
+
// Ensure we emit the error event outside the promise context so it won't be
|
|
431
|
+
// swallowed when there's no listeners.
|
|
432
|
+
setImmediate(() => {
|
|
433
|
+
self.emit('error', err);
|
|
434
|
+
reject(err);
|
|
435
|
+
});
|
|
436
|
+
});
|
|
437
|
+
});
|
|
425
438
|
}
|
|
426
439
|
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
440
|
+
function addInQueue(name) {
|
|
441
|
+
const item = Object.getPrototypeOf(self)[name];
|
|
442
|
+
const queueName = self.env.runLoop.queueNames.indexOf(name) === -1 ? null : name;
|
|
443
|
+
|
|
444
|
+
// Name points to a function; run it!
|
|
445
|
+
if (typeof item === 'function') {
|
|
446
|
+
return addMethod(item, name, queueName);
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// Not a queue hash; stop
|
|
450
|
+
if (!queueName) {
|
|
430
451
|
return;
|
|
431
452
|
}
|
|
432
453
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
454
|
+
// Run each queue items
|
|
455
|
+
_.each(item, (method, methodName) => {
|
|
456
|
+
if (!_.isFunction(method) || !methodIsValid(methodName)) {
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
436
459
|
|
|
437
|
-
|
|
460
|
+
addMethod(method, methodName, queueName);
|
|
461
|
+
});
|
|
462
|
+
}
|
|
438
463
|
|
|
439
|
-
|
|
440
|
-
this.env.runLoop.add('conflicts', this._writeFiles.bind(this), {
|
|
441
|
-
once: 'write memory fs to disk'
|
|
442
|
-
});
|
|
443
|
-
};
|
|
464
|
+
validMethods.forEach(addInQueue);
|
|
444
465
|
|
|
445
|
-
|
|
446
|
-
|
|
466
|
+
const writeFiles = () => {
|
|
467
|
+
this.env.runLoop.add('conflicts', this._writeFiles.bind(this), {
|
|
468
|
+
once: 'write memory fs to disk'
|
|
469
|
+
});
|
|
470
|
+
};
|
|
447
471
|
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
this.conflicter.resolve(err => {
|
|
451
|
-
if (err) {
|
|
452
|
-
this.emit('error', err);
|
|
453
|
-
}
|
|
472
|
+
this.env.sharedFs.on('change', writeFiles);
|
|
473
|
+
writeFiles();
|
|
454
474
|
|
|
455
|
-
|
|
475
|
+
// Add the default conflicts handling
|
|
476
|
+
this.env.runLoop.add('conflicts', done => {
|
|
477
|
+
this.conflicter.resolve(err => {
|
|
478
|
+
if (err) {
|
|
479
|
+
this.emit('error', err);
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
done();
|
|
483
|
+
});
|
|
456
484
|
});
|
|
485
|
+
|
|
486
|
+
_.invokeMap(this._composedWith, 'run');
|
|
457
487
|
});
|
|
458
488
|
|
|
459
|
-
|
|
460
|
-
|
|
489
|
+
// Maintain backward compatibility with the callback function
|
|
490
|
+
if (_.isFunction(cb)) {
|
|
491
|
+
promise.then(cb, cb);
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
return promise;
|
|
461
495
|
}
|
|
462
496
|
|
|
463
497
|
/**
|
|
464
498
|
* Compose this generator with another one.
|
|
465
|
-
* @param {String}
|
|
499
|
+
* @param {String|Object} generator The path to the generator module or an object (see examples)
|
|
466
500
|
* @param {Object} options The options passed to the Generator
|
|
467
|
-
* @
|
|
468
|
-
* @param {string} [settings.local] Path to a locally stored generator
|
|
469
|
-
* @param {String} [settings.link="weak"] If "strong", the composition will occured
|
|
470
|
-
* even when the composition is initialized by
|
|
471
|
-
* the end user
|
|
472
|
-
* @return {this}
|
|
501
|
+
* @return {this} This generator
|
|
473
502
|
*
|
|
474
503
|
* @example <caption>Using a peerDependency generator</caption>
|
|
475
504
|
* this.composeWith('bootstrap', { sass: true });
|
|
476
505
|
*
|
|
477
506
|
* @example <caption>Using a direct dependency generator</caption>
|
|
478
507
|
* this.composeWith(require.resolve('generator-bootstrap/app/main.js'), { sass: true });
|
|
508
|
+
*
|
|
509
|
+
* @example <caption>Passing a Generator class</caption>
|
|
510
|
+
* this.composeWith({ Generator: MyGenerator, path: '../generator-bootstrap/app/main.js' }, { sass: true });
|
|
479
511
|
*/
|
|
480
|
-
composeWith(
|
|
481
|
-
let
|
|
482
|
-
options = options || {};
|
|
512
|
+
composeWith(generator, options) {
|
|
513
|
+
let instantiatedGenerator;
|
|
483
514
|
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
'skip-cache': this.options.skipCache
|
|
490
|
-
}, options);
|
|
491
|
-
|
|
492
|
-
try {
|
|
493
|
-
const Generator = require(modulePath); // eslint-disable-line import/no-dynamic-require
|
|
494
|
-
Generator.resolved = require.resolve(modulePath);
|
|
495
|
-
Generator.namespace = this.env.namespace(modulePath);
|
|
496
|
-
generator = this.env.instantiate(Generator, {
|
|
515
|
+
const instantiate = (Generator, path) => {
|
|
516
|
+
Generator.resolved = require.resolve(path);
|
|
517
|
+
Generator.namespace = this.env.namespace(path);
|
|
518
|
+
|
|
519
|
+
return this.env.instantiate(Generator, {
|
|
497
520
|
options,
|
|
498
521
|
arguments: options.arguments
|
|
499
522
|
});
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
523
|
+
};
|
|
524
|
+
|
|
525
|
+
options = options || {};
|
|
526
|
+
|
|
527
|
+
// Pass down the default options so they're correctly mirrored down the chain.
|
|
528
|
+
options = _.extend(
|
|
529
|
+
{
|
|
530
|
+
skipInstall: this.options.skipInstall || this.options['skip-install'],
|
|
531
|
+
'skip-install': this.options.skipInstall || this.options['skip-install'],
|
|
532
|
+
skipCache: this.options.skipCache || this.options['skip-cache'],
|
|
533
|
+
'skip-cache': this.options.skipCache || this.options['skip-cache'],
|
|
534
|
+
forceInstall: this.options.forceInstall || this.options['force-install'],
|
|
535
|
+
'force-install': this.options.forceInstall || this.options['force-install']
|
|
536
|
+
},
|
|
537
|
+
options
|
|
538
|
+
);
|
|
539
|
+
|
|
540
|
+
if (typeof generator === 'string') {
|
|
541
|
+
try {
|
|
542
|
+
const Generator = require(generator); // eslint-disable-line import/no-dynamic-require
|
|
543
|
+
instantiatedGenerator = instantiate(Generator, generator);
|
|
544
|
+
} catch (err) {
|
|
545
|
+
if (err.code === 'MODULE_NOT_FOUND') {
|
|
546
|
+
instantiatedGenerator = this.env.create(generator, {
|
|
547
|
+
options,
|
|
548
|
+
arguments: options.arguments
|
|
549
|
+
});
|
|
550
|
+
} else {
|
|
551
|
+
throw err;
|
|
552
|
+
}
|
|
508
553
|
}
|
|
554
|
+
} else {
|
|
555
|
+
assert(
|
|
556
|
+
generator.Generator,
|
|
557
|
+
`${chalk.red('Missing Generator property')}\n` +
|
|
558
|
+
`When passing an object to Generator${chalk.cyan(
|
|
559
|
+
'#composeWith'
|
|
560
|
+
)} include the generator class to run in the ${chalk.cyan(
|
|
561
|
+
'Generator'
|
|
562
|
+
)} property\n\n` +
|
|
563
|
+
`this.composeWith({\n` +
|
|
564
|
+
` ${chalk.yellow('Generator')}: MyGenerator,\n` +
|
|
565
|
+
` ...\n` +
|
|
566
|
+
`});`
|
|
567
|
+
);
|
|
568
|
+
assert(
|
|
569
|
+
typeof generator.path === 'string',
|
|
570
|
+
`${chalk.red('path property is not a string')}\n` +
|
|
571
|
+
`When passing an object to Generator${chalk.cyan(
|
|
572
|
+
'#composeWith'
|
|
573
|
+
)} include the path to the generators files in the ${chalk.cyan(
|
|
574
|
+
'path'
|
|
575
|
+
)} property\n\n` +
|
|
576
|
+
`this.composeWith({\n` +
|
|
577
|
+
` ${chalk.yellow('path')}: '../my-generator',\n` +
|
|
578
|
+
` ...\n` +
|
|
579
|
+
`});`
|
|
580
|
+
);
|
|
581
|
+
instantiatedGenerator = instantiate(generator.Generator, generator.path);
|
|
509
582
|
}
|
|
510
583
|
|
|
511
584
|
if (this._running) {
|
|
512
|
-
|
|
585
|
+
instantiatedGenerator.run();
|
|
513
586
|
} else {
|
|
514
|
-
this._composedWith.push(
|
|
587
|
+
this._composedWith.push(instantiatedGenerator);
|
|
515
588
|
}
|
|
516
589
|
|
|
517
590
|
return this;
|
|
@@ -522,7 +595,7 @@ class Generator extends EventEmitter {
|
|
|
522
595
|
* @return {String} The name of the root generator
|
|
523
596
|
*/
|
|
524
597
|
rootGeneratorName() {
|
|
525
|
-
const pkg = readPkgUp.sync({cwd: this.resolved}).pkg;
|
|
598
|
+
const pkg = readPkgUp.sync({ cwd: this.resolved }).pkg;
|
|
526
599
|
return pkg ? pkg.name : '*';
|
|
527
600
|
}
|
|
528
601
|
|
|
@@ -531,7 +604,7 @@ class Generator extends EventEmitter {
|
|
|
531
604
|
* @return {String} The version of the root generator
|
|
532
605
|
*/
|
|
533
606
|
rootGeneratorVersion() {
|
|
534
|
-
const pkg = readPkgUp.sync({cwd: this.resolved}).pkg;
|
|
607
|
+
const pkg = readPkgUp.sync({ cwd: this.resolved }).pkg;
|
|
535
608
|
return pkg ? pkg.version : '0.0.0';
|
|
536
609
|
}
|
|
537
610
|
|
|
@@ -673,7 +746,7 @@ class Generator extends EventEmitter {
|
|
|
673
746
|
_writeFiles(done) {
|
|
674
747
|
const self = this;
|
|
675
748
|
|
|
676
|
-
const conflictChecker = through.obj(function
|
|
749
|
+
const conflictChecker = through.obj(function(file, enc, cb) {
|
|
677
750
|
const stream = this;
|
|
678
751
|
|
|
679
752
|
// If the file has no state requiring action, move on
|
package/lib/util/binary-diff.js
CHANGED
|
@@ -8,8 +8,10 @@ const Table = require('cli-table');
|
|
|
8
8
|
|
|
9
9
|
exports.isBinary = (existingFilePath, newFileContents) => {
|
|
10
10
|
const existingHeader = readChunk.sync(existingFilePath, 0, 512);
|
|
11
|
-
return
|
|
12
|
-
|
|
11
|
+
return (
|
|
12
|
+
istextorbinary.isBinarySync(undefined, existingHeader) ||
|
|
13
|
+
(newFileContents && istextorbinary.isBinarySync(undefined, newFileContents))
|
|
14
|
+
);
|
|
13
15
|
};
|
|
14
16
|
|
|
15
17
|
exports.diff = (existingFilePath, newFileContents) => {
|
|
@@ -32,17 +34,15 @@ exports.diff = (existingFilePath, newFileContents) => {
|
|
|
32
34
|
|
|
33
35
|
sizeDiff += prettyBytes(Math.abs(existingStat.size - newFileContents.length));
|
|
34
36
|
|
|
35
|
-
table.push(
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
dateFormat(existingStat.mtime),
|
|
43
|
-
|
|
44
|
-
''
|
|
45
|
-
]);
|
|
37
|
+
table.push(
|
|
38
|
+
[
|
|
39
|
+
'Size',
|
|
40
|
+
prettyBytes(existingStat.size),
|
|
41
|
+
prettyBytes(newFileContents.length),
|
|
42
|
+
sizeDiff
|
|
43
|
+
],
|
|
44
|
+
['Last modified', dateFormat(existingStat.mtime), '', '']
|
|
45
|
+
);
|
|
46
46
|
|
|
47
47
|
return table.toString();
|
|
48
48
|
};
|
package/lib/util/conflicter.js
CHANGED
|
@@ -103,7 +103,6 @@ class Conflicter {
|
|
|
103
103
|
* @param {Object} file File object respecting this interface: { path, contents }
|
|
104
104
|
* @param {Function} cb Callback receiving a status string ('identical', 'create',
|
|
105
105
|
* 'skip', 'force')
|
|
106
|
-
* @return {null} nothing
|
|
107
106
|
*/
|
|
108
107
|
collision(file, cb) {
|
|
109
108
|
const rfilepath = path.relative(process.cwd(), file.path);
|
|
@@ -132,8 +131,8 @@ class Conflicter {
|
|
|
132
131
|
/**
|
|
133
132
|
* Actual prompting logic
|
|
134
133
|
* @private
|
|
135
|
-
* @param {Object} file
|
|
136
|
-
* @param {Function} cb
|
|
134
|
+
* @param {Object} file vinyl file object
|
|
135
|
+
* @param {Function} cb callback receiving the next action
|
|
137
136
|
*/
|
|
138
137
|
_ask(file, cb) {
|
|
139
138
|
const rfilepath = path.relative(process.cwd(), file.path);
|
|
@@ -141,23 +140,28 @@ class Conflicter {
|
|
|
141
140
|
name: 'action',
|
|
142
141
|
type: 'expand',
|
|
143
142
|
message: `Overwrite ${rfilepath}?`,
|
|
144
|
-
choices: [
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
143
|
+
choices: [
|
|
144
|
+
{
|
|
145
|
+
key: 'y',
|
|
146
|
+
name: 'overwrite',
|
|
147
|
+
value: 'write'
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
key: 'n',
|
|
151
|
+
name: 'do not overwrite',
|
|
152
|
+
value: 'skip'
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
key: 'a',
|
|
156
|
+
name: 'overwrite this and all others',
|
|
157
|
+
value: 'force'
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
key: 'x',
|
|
161
|
+
name: 'abort',
|
|
162
|
+
value: 'abort'
|
|
163
|
+
}
|
|
164
|
+
]
|
|
161
165
|
};
|
|
162
166
|
|
|
163
167
|
// Only offer diff option for files
|
|
@@ -194,7 +198,7 @@ class Conflicter {
|
|
|
194
198
|
result.action = 'force';
|
|
195
199
|
}
|
|
196
200
|
|
|
197
|
-
this.adapter.log[result.action](rfilepath);
|
|
201
|
+
this.adapter.log[result.action || 'force'](rfilepath);
|
|
198
202
|
return cb(result.action);
|
|
199
203
|
});
|
|
200
204
|
}
|
package/lib/util/deprecate.js
CHANGED
|
@@ -3,7 +3,7 @@ const _ = require('lodash');
|
|
|
3
3
|
const chalk = require('chalk');
|
|
4
4
|
|
|
5
5
|
const deprecate = (message, fn) => {
|
|
6
|
-
return function
|
|
6
|
+
return function() {
|
|
7
7
|
deprecate.log(message);
|
|
8
8
|
return fn.apply(this, arguments);
|
|
9
9
|
};
|
|
@@ -25,7 +25,7 @@ deprecate.object = (message, object) => {
|
|
|
25
25
|
continue;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
mirror[name] = deprecate(msgTpl({name}), func);
|
|
28
|
+
mirror[name] = deprecate(msgTpl({ name }), func);
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
return mirror;
|
|
@@ -36,7 +36,9 @@ const getCheckboxDefault = (question, defaultValue) => {
|
|
|
36
36
|
* @private
|
|
37
37
|
*/
|
|
38
38
|
const getListDefault = (question, defaultValue) => {
|
|
39
|
-
const choiceValues = question.choices.map(choice =>
|
|
39
|
+
const choiceValues = question.choices.map(choice =>
|
|
40
|
+
typeof choice === 'object' ? choice.value : choice
|
|
41
|
+
);
|
|
40
42
|
return choiceValues.indexOf(defaultValue);
|
|
41
43
|
};
|
|
42
44
|
|
|
@@ -115,7 +117,7 @@ promptSuggestion.prefillQuestions = (store, questions) => {
|
|
|
115
117
|
|
|
116
118
|
const storedValue = promptValues[question.name];
|
|
117
119
|
|
|
118
|
-
if (
|
|
120
|
+
if (storedValue === undefined || _.isFunction(question.choices)) {
|
|
119
121
|
// Do not override prompt default when question.choices is a function,
|
|
120
122
|
// since can't guarantee that the `storedValue` will even be in the returned choices
|
|
121
123
|
return question;
|
package/lib/util/storage.js
CHANGED
|
@@ -52,7 +52,6 @@ class Storage {
|
|
|
52
52
|
|
|
53
53
|
/**
|
|
54
54
|
* Save a new object of values
|
|
55
|
-
* @return {null}
|
|
56
55
|
*/
|
|
57
56
|
save() {
|
|
58
57
|
this._persist(this._store);
|
|
@@ -82,7 +81,7 @@ class Storage {
|
|
|
82
81
|
* @return {*} val Whatever was passed in as val.
|
|
83
82
|
*/
|
|
84
83
|
set(key, val) {
|
|
85
|
-
assert(!_.isFunction(val),
|
|
84
|
+
assert(!_.isFunction(val), "Storage value can't be a function");
|
|
86
85
|
|
|
87
86
|
const store = this._store;
|
|
88
87
|
|
|
@@ -99,7 +98,6 @@ class Storage {
|
|
|
99
98
|
/**
|
|
100
99
|
* Delete a key from the store and schedule a save.
|
|
101
100
|
* @param {String} key The key under which the value is stored.
|
|
102
|
-
* @return {null}
|
|
103
101
|
*/
|
|
104
102
|
delete(key) {
|
|
105
103
|
const store = this._store;
|
package/package.json
CHANGED
|
@@ -1,24 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yeoman-generator",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"description": "Rails-inspired generator system that provides scaffolding for your apps",
|
|
5
|
-
"license": "BSD-2-Clause",
|
|
6
|
-
"repository": "yeoman/generator",
|
|
7
5
|
"homepage": "http://yeoman.io",
|
|
8
6
|
"author": "Yeoman",
|
|
9
|
-
"main": "lib",
|
|
10
|
-
"engines": {
|
|
11
|
-
"node": ">=4"
|
|
12
|
-
},
|
|
13
|
-
"scripts": {
|
|
14
|
-
"pretest": "xo",
|
|
15
|
-
"test": "nyc mocha",
|
|
16
|
-
"doc": "jsdoc -c jsdoc.json",
|
|
17
|
-
"coverage": "nyc report --reporter=text-lcov | coveralls"
|
|
18
|
-
},
|
|
19
7
|
"files": [
|
|
20
8
|
"lib"
|
|
21
9
|
],
|
|
10
|
+
"main": "lib",
|
|
22
11
|
"keywords": [
|
|
23
12
|
"development",
|
|
24
13
|
"dev",
|
|
@@ -32,62 +21,96 @@
|
|
|
32
21
|
"yeoman",
|
|
33
22
|
"app"
|
|
34
23
|
],
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"coveralls": "^3.0.2",
|
|
26
|
+
"eslint": "^5.10.0",
|
|
27
|
+
"eslint-config-prettier": "^3.3.0",
|
|
28
|
+
"eslint-config-xo": "^0.25.1",
|
|
29
|
+
"eslint-plugin-prettier": "^3.0.0",
|
|
30
|
+
"husky": "^1.2.1",
|
|
31
|
+
"inquirer": "^6.0.0",
|
|
32
|
+
"jsdoc": "^3.5.5",
|
|
33
|
+
"lint-staged": "^8.1.0",
|
|
34
|
+
"mocha": "^5.1.1",
|
|
35
|
+
"mockery": "^2.1.0",
|
|
36
|
+
"nock": "^10.0.4",
|
|
37
|
+
"nyc": "^13.1.0",
|
|
38
|
+
"prettier": "^1.15.3",
|
|
39
|
+
"proxyquire": "^2.0.1",
|
|
40
|
+
"sinon": "^7.2.2",
|
|
41
|
+
"tui-jsdoc-template": "^1.2.2",
|
|
42
|
+
"yeoman-assert": "^3.1.1",
|
|
43
|
+
"yeoman-test": "^1.8.0"
|
|
44
|
+
},
|
|
45
|
+
"license": "BSD-2-Clause",
|
|
46
|
+
"repository": "yeoman/generator",
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=6"
|
|
49
|
+
},
|
|
50
|
+
"scripts": {
|
|
51
|
+
"pretest": "eslint .",
|
|
52
|
+
"test": "nyc mocha",
|
|
53
|
+
"doc": "jsdoc -c jsdoc.json",
|
|
54
|
+
"coverage": "nyc report --reporter=text-lcov | coveralls",
|
|
55
|
+
"precommit": "lint-staged"
|
|
56
|
+
},
|
|
35
57
|
"dependencies": {
|
|
36
58
|
"async": "^2.6.0",
|
|
37
59
|
"chalk": "^2.3.0",
|
|
38
60
|
"cli-table": "^0.3.1",
|
|
39
61
|
"cross-spawn": "^6.0.5",
|
|
40
|
-
"dargs": "^
|
|
62
|
+
"dargs": "^6.0.0",
|
|
41
63
|
"dateformat": "^3.0.3",
|
|
42
|
-
"debug": "^
|
|
64
|
+
"debug": "^4.1.0",
|
|
43
65
|
"detect-conflict": "^1.0.0",
|
|
44
66
|
"error": "^7.0.2",
|
|
45
|
-
"find-up": "^
|
|
67
|
+
"find-up": "^3.0.0",
|
|
46
68
|
"github-username": "^4.0.0",
|
|
47
69
|
"istextorbinary": "^2.2.1",
|
|
48
70
|
"lodash": "^4.17.10",
|
|
49
71
|
"make-dir": "^1.1.0",
|
|
50
|
-
"mem-fs-editor": "^
|
|
72
|
+
"mem-fs-editor": "^5.0.0",
|
|
51
73
|
"minimist": "^1.2.0",
|
|
52
|
-
"pretty-bytes": "^
|
|
53
|
-
"read-chunk": "^
|
|
54
|
-
"read-pkg-up": "^
|
|
74
|
+
"pretty-bytes": "^5.1.0",
|
|
75
|
+
"read-chunk": "^3.0.0",
|
|
76
|
+
"read-pkg-up": "^4.0.0",
|
|
55
77
|
"rimraf": "^2.6.2",
|
|
56
78
|
"run-async": "^2.0.0",
|
|
57
79
|
"shelljs": "^0.8.0",
|
|
58
80
|
"text-table": "^0.2.0",
|
|
59
|
-
"through2": "^
|
|
81
|
+
"through2": "^3.0.0",
|
|
60
82
|
"yeoman-environment": "^2.0.5"
|
|
61
83
|
},
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
"
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
"proxyquire": "^2.0.1",
|
|
72
|
-
"sinon": "^4.5.0",
|
|
73
|
-
"tui-jsdoc-template": "^1.2.2",
|
|
74
|
-
"xo": "^0.20.3",
|
|
75
|
-
"yeoman-assert": "^3.1.1",
|
|
76
|
-
"yeoman-test": "^1.7.0"
|
|
84
|
+
"lint-staged": {
|
|
85
|
+
"*.js": [
|
|
86
|
+
"eslint --fix",
|
|
87
|
+
"git add"
|
|
88
|
+
],
|
|
89
|
+
"*.json": [
|
|
90
|
+
"prettier --write",
|
|
91
|
+
"git add"
|
|
92
|
+
]
|
|
77
93
|
},
|
|
78
|
-
"
|
|
79
|
-
"
|
|
94
|
+
"eslintConfig": {
|
|
95
|
+
"extends": [
|
|
96
|
+
"xo",
|
|
97
|
+
"prettier"
|
|
98
|
+
],
|
|
99
|
+
"env": {
|
|
100
|
+
"mocha": true,
|
|
101
|
+
"node": true
|
|
102
|
+
},
|
|
80
103
|
"rules": {
|
|
81
|
-
"
|
|
104
|
+
"prettier/prettier": [
|
|
105
|
+
"error",
|
|
106
|
+
{
|
|
107
|
+
"singleQuote": true,
|
|
108
|
+
"printWidth": 90
|
|
109
|
+
}
|
|
110
|
+
]
|
|
82
111
|
},
|
|
83
|
-
"
|
|
84
|
-
|
|
85
|
-
"files": "test/**",
|
|
86
|
-
"envs": [
|
|
87
|
-
"node",
|
|
88
|
-
"mocha"
|
|
89
|
-
]
|
|
90
|
-
}
|
|
112
|
+
"plugins": [
|
|
113
|
+
"prettier"
|
|
91
114
|
]
|
|
92
115
|
}
|
|
93
116
|
}
|