yeoman-environment 3.7.0 → 3.9.1

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/command.js CHANGED
@@ -21,7 +21,7 @@ module.exports = cls => class EnvironmentCommand extends cls {
21
21
  .option('--skip-yo-resolve', 'Ignore .yo-resolve files', false)
22
22
  /* Hidden options, used for api */
23
23
  .addOption(new Option('--skip-local-cache', 'Skip local answers cache').default(true).hideHelp())
24
- .addOption(new Option('--skip-parse-options', 'Skip legacy options parsing').default(true).hideHelp())
24
+ .addOption(new Option('--skip-parse-options', 'Skip legacy options parsing').default(false).hideHelp())
25
25
  .addOption(new Option('--experimental', 'Experimental features').default(false).hideHelp())
26
26
  .addOption(new Option('--log-cwd', 'Path for log purpose').hideHelp());
27
27
  }
@@ -13,7 +13,9 @@ const debug = require('debug')('yeoman:environment');
13
13
  const isScoped = require('is-scoped');
14
14
  const npmlog = require('npmlog');
15
15
  const semver = require('semver');
16
+ const slash = require('slash');
16
17
  const {TrackerGroup} = require('are-we-there-yet');
18
+ const {pipeline, transform} = require('p-transform');
17
19
 
18
20
  const ENVIRONMENT_VERSION = require('../package.json').version;
19
21
  const Store = require('./store');
@@ -31,7 +33,6 @@ const {
31
33
  createYoRcTransform,
32
34
  createYoResolveTransform
33
35
  } = require('./util/transform');
34
- const {pipeline, transform} = require('p-transform');
35
36
 
36
37
  /**
37
38
  * Two-step argument splitting function that first splits arguments in quotes,
@@ -146,19 +147,22 @@ class Environment extends Base {
146
147
  * @param {Class} GeneratorClass - Generator to create Command
147
148
  * @return {Command} return command
148
149
  */
149
- static prepareGeneratorCommand(command, GeneratorClass) {
150
+ static prepareGeneratorCommand(command, GeneratorClass, namespace) {
150
151
  const generator = new GeneratorClass([], {help: true, env: {}});
151
152
  Base.addGeneratorOptions(command, generator);
152
153
 
153
154
  command.action(async function () {
154
- command.env = Environment.createEnv(this.opts());
155
-
156
155
  let rootCommand = this;
157
156
  while (rootCommand.parent) {
158
157
  rootCommand = rootCommand.parent;
159
158
  }
159
+ command.env = Environment.createEnv(rootCommand.opts());
160
+
160
161
  rootCommand.emit('yeoman:environment', command.env);
161
162
 
163
+ if (namespace) {
164
+ return command.env.run([namespace, ...(this.args || [])], this.opts()).then(() => command.env);
165
+ }
162
166
  const generator = command.env.instantiate(GeneratorClass, this.args, this.opts());
163
167
  await command.env.queueGenerator(generator);
164
168
  return command.env.start().then(() => command.env);
@@ -760,16 +764,10 @@ class Environment extends Base {
760
764
  };
761
765
 
762
766
  maybeGenerator = maybeGenerator || this.get(namespaceOrPath);
763
- if (maybeGenerator && (maybeGenerator.then || maybeGenerator.prototype._postConstruct)) {
767
+ if (maybeGenerator && maybeGenerator.then) {
764
768
  return Promise.resolve(maybeGenerator)
765
769
  .then(Generator => checkGenerator(Generator))
766
- .then(Generator => this.instantiate(Generator, args, options))
767
- .then(async generator => {
768
- if (!options.help && generator._postConstruct) {
769
- await generator._postConstruct();
770
- }
771
- return generator;
772
- });
770
+ .then(Generator => this.instantiate(Generator, args, options));
773
771
  }
774
772
 
775
773
  return this.instantiate(checkGenerator(maybeGenerator), args, options);
@@ -812,6 +810,10 @@ class Environment extends Base {
812
810
  ...environmentOptions
813
811
  };
814
812
 
813
+ if (!options.help && generator._postConstruct) {
814
+ return Promise.resolve(generator._postConstruct()).then(() => generator);
815
+ }
816
+
815
817
  return generator;
816
818
  }
817
819
 
@@ -1119,28 +1121,39 @@ class Environment extends Base {
1119
1121
  throw new Error('Missing namespace');
1120
1122
  }
1121
1123
 
1124
+ // Normalize path
1125
+ let ns = slash(filepath);
1126
+
1127
+ // Ignore path before latest node_modules
1128
+ const REPOSITORY_PATH = '/node_modules/';
1129
+ if (ns.includes(REPOSITORY_PATH)) {
1130
+ ns = ns.slice(ns.lastIndexOf(REPOSITORY_PATH) + REPOSITORY_PATH.length, ns.length);
1131
+ }
1132
+
1122
1133
  // Cleanup extension and normalize path for differents OS
1123
- let ns = path.normalize(filepath.replace(new RegExp(escapeStrRe(path.extname(filepath)) + '$'), ''));
1134
+ const parsed = path.parse(ns);
1135
+ ns = parsed.dir ? `${parsed.dir}/${parsed.name}` : parsed.name;
1124
1136
 
1125
1137
  // Sort lookups by length so biggest are removed first
1126
- const nsLookups = _([...lookups, '..']).map(found => path.normalize(found)).sortBy('length').value().reverse();
1138
+ const nsLookups = _([...lookups, '..']).map(found => slash(found)).sortBy('length').value().reverse();
1127
1139
 
1128
1140
  // If `ns` contains a lookup dir in its path, remove it.
1129
- ns = nsLookups.reduce((ns, lookup) => {
1141
+ for (let lookup of nsLookups) {
1130
1142
  // Only match full directory (begin with leading slash or start of input, end with trailing slash)
1131
- lookup = new RegExp(`(?:\\\\|/|^)${escapeStrRe(lookup)}(?=\\\\|/)`, 'g');
1132
- return ns.replace(lookup, '');
1133
- }, ns);
1143
+ lookup = new RegExp(`(?:/|^)${escapeStrRe(lookup)}(?=/)`, 'g');
1144
+ ns = ns.replace(lookup, '');
1145
+ }
1134
1146
 
1135
- const folders = ns.split(path.sep);
1147
+ const folders = ns.split('/');
1136
1148
  const scope = _.findLast(folders, folder => folder.indexOf('@') === 0);
1137
1149
 
1138
1150
  // Cleanup `ns` from unwanted parts and then normalize slashes to `:`
1139
1151
  ns = ns
1152
+ .replace(/\/\//g, '') // Remove double `/`
1140
1153
  .replace(/(.*generator-)/, '') // Remove before `generator-`
1141
- .replace(/[/\\](index|main)$/, '') // Remove `/index` or `/main`
1142
- .replace(/^[/\\]+/, '') // Remove leading `/`
1143
- .replace(/[/\\]+/g, ':'); // Replace slashes by `:`
1154
+ .replace(/\/(index|main)$/, '') // Remove `/index` or `/main`
1155
+ .replace(/^\//, '') // Remove leading `/`
1156
+ .replace(/\/+/g, ':'); // Replace slashes by `:`
1144
1157
 
1145
1158
  if (scope) {
1146
1159
  ns = `${scope}/${ns}`;
@@ -194,9 +194,9 @@ class Conflicter {
194
194
  file.conflicterLog = 'create';
195
195
  return Promise.resolve(file);
196
196
  }
197
- const force = this.force || (conflicterStatus && conflicterStatus.force);
197
+ const isForce = () => this.force || (conflicterStatus && conflicterStatus.force);
198
198
 
199
- if (force) {
199
+ if (isForce()) {
200
200
  this._log('force', rfilepath);
201
201
  file.conflicter = 'force';
202
202
  return Promise.resolve(file);
@@ -222,7 +222,7 @@ class Conflicter {
222
222
 
223
223
  return new Promise((resolve, reject) => {
224
224
  this.queue.add('conflicts', next => {
225
- if (force) {
225
+ if (isForce()) {
226
226
  file.conflicter = 'force';
227
227
  this.adapter.log.force(rfilepath);
228
228
  resolve(file);
@@ -3,9 +3,11 @@ const path = require('path');
3
3
  const {WError} = require('error');
4
4
  const findUp = require('find-up');
5
5
  const minimatch = require('minimatch');
6
- const {transform, passthrough} = require('p-transform');
6
+ const {transform, passthrough, filter} = require('p-transform');
7
7
  const OOOTransform = require('./out-of-order-transform');
8
8
 
9
+ const {Minimatch} = minimatch;
10
+
9
11
  class YoResolveError extends WError {}
10
12
 
11
13
  /**
@@ -168,12 +170,10 @@ function createYoResolveTransform(conflicter, yoResolveFileName) {
168
170
  * @return {Transform} A Transform https://nodejs.org/api/stream.html#stream_class_stream_transform
169
171
  */
170
172
  function createYoRcTransform() {
171
- return passthrough(file => {
172
- // Config files should not be processed by the conflicter. Force override.
173
- if (['.yo-rc.json', '.yo-resolve', '.yo-rc-global.json'].includes(path.basename(file.path))) {
174
- file.conflicter = 'force';
175
- }
176
- }, 'environment:yo-rc');
173
+ // Config files should not be processed by the conflicter. Force override.
174
+ return patternSpy(file => {
175
+ file.conflicter = 'force';
176
+ }, '**/{.yo-rc.json,.yo-resolve,.yo-rc-global.json}', 'environment:yo-rc');
177
177
  }
178
178
 
179
179
  /**
@@ -211,7 +211,7 @@ function createConflicterStatusTransform() {
211
211
  * May break between major yo versions.
212
212
  */
213
213
  function createModifiedTransform() {
214
- return createEachFileTransform({forwardUmodified: false, logName: 'environment:modified'});
214
+ return filter(file => fileIsModified(file), 'environment:modified');
215
215
  }
216
216
 
217
217
  /**
@@ -222,6 +222,29 @@ function createCommitTransform(memFsEditor) {
222
222
  return transform(file => memFsEditor.commitFileAsync(file), 'environment:commit');
223
223
  }
224
224
 
225
+ /**
226
+ * Conditional filter on pattern.
227
+ *
228
+ * @param {String} pattern - Minimatch pattern.
229
+ * @param {Object} options - Minimatch options.
230
+ */
231
+ function patternFilter(pattern, options) {
232
+ const minimatch = new Minimatch(pattern, options);
233
+ return filter(file => minimatch.match(file.path));
234
+ }
235
+
236
+ /**
237
+ * Conditional spy on pattern.
238
+ *
239
+ * @param {Function} spy.
240
+ * @param {String} pattern - Minimatch pattern.
241
+ * @param {Object} options - Minimatch options.
242
+ */
243
+ function patternSpy(spy, pattern, options) {
244
+ const minimatch = new Minimatch(pattern, options);
245
+ return passthrough(file => (minimatch.match(file.path) ? spy(file) : undefined));
246
+ }
247
+
225
248
  module.exports = {
226
249
  createFileTransform,
227
250
  fileIsModified,
@@ -232,5 +255,7 @@ module.exports = {
232
255
  createModifiedTransform,
233
256
  createCommitTransform,
234
257
  createConflicterCheckTransform,
235
- createConflicterStatusTransform
258
+ createConflicterStatusTransform,
259
+ patternFilter,
260
+ patternSpy
236
261
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yeoman-environment",
3
- "version": "3.7.0",
3
+ "version": "3.9.1",
4
4
  "description": "Handles the lifecyle and bootstrapping of generators in a specific environment",
5
5
  "homepage": "http://yeoman.io",
6
6
  "author": "Yeoman",
@@ -12,6 +12,17 @@
12
12
  "lib"
13
13
  ],
14
14
  "main": "lib/environment.js",
15
+ "exports": {
16
+ ".": "./lib/environment.js",
17
+ "./cli/": "./cli/",
18
+ "./lib/": "./lib/",
19
+ "./lib/util/": "./lib/util/",
20
+ "./adapter": "./lib/adapter.js",
21
+ "./conflicter": "./lib/util/conflicter.js",
22
+ "./log": "./lib/util/log.js",
23
+ "./transform": "./lib/util/transform.js",
24
+ "./package.json": "./package.json"
25
+ },
15
26
  "keywords": [
16
27
  "development",
17
28
  "dev",
@@ -75,7 +86,7 @@
75
86
  "minimatch": "^3.0.4",
76
87
  "npmlog": "^5.0.1",
77
88
  "p-queue": "^6.6.2",
78
- "p-transform": "^1.2.0",
89
+ "p-transform": "^1.3.0",
79
90
  "pacote": "^12.0.2",
80
91
  "preferred-pm": "^3.0.3",
81
92
  "pretty-bytes": "^5.3.0",
@@ -99,10 +110,10 @@
99
110
  "nyc": "^15.0.0",
100
111
  "prettier": "^2.2.1",
101
112
  "proxyquire": "^2.1.3",
102
- "sinon": "^12.0.1",
103
- "sinon-test": "^3.0.0",
113
+ "sinon": "^11.1.2",
114
+ "sinon-test": "^3.1.1",
104
115
  "tui-jsdoc-template": "^1.2.2",
105
- "xo": "^0.37.1",
116
+ "xo": "0.37.1",
106
117
  "yeoman-assert": "^3.1.1",
107
118
  "yeoman-generator": "^5.1.0",
108
119
  "yeoman-test": "^6.2.0"
@@ -115,6 +126,7 @@
115
126
  ],
116
127
  "rules": {
117
128
  "import/no-dynamic-require": "off",
129
+ "import/extensions": "off",
118
130
  "prefer-spread": "off",
119
131
  "padding-line-between-statements": "off",
120
132
  "unicorn/no-hex-escape": "off",