ember-cli 4.4.0 → 4.6.0-beta.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.
Files changed (53) hide show
  1. package/.github/workflows/ci.yml +4 -4
  2. package/CHANGELOG.md +74 -0
  3. package/blueprints/addon/additional-dev-dependencies.json +1 -1
  4. package/blueprints/addon/files/.github/workflows/ci.yml +6 -3
  5. package/blueprints/addon/files/.travis.yml +2 -2
  6. package/blueprints/addon/files/CONTRIBUTING.md +1 -1
  7. package/blueprints/addon/files/README.md +1 -1
  8. package/blueprints/addon/index.js +3 -4
  9. package/blueprints/app/files/.github/workflows/ci.yml +4 -2
  10. package/blueprints/app/files/.travis.yml +2 -2
  11. package/blueprints/app/files/README.md +1 -1
  12. package/blueprints/app/files/config/environment.js +0 -4
  13. package/blueprints/app/files/package.json +11 -12
  14. package/blueprints/app/index.js +2 -0
  15. package/blueprints/blueprint/index.js +0 -16
  16. package/blueprints/in-repo-addon/index.js +6 -3
  17. package/blueprints/server/index.js +21 -4
  18. package/blueprints/vendor-shim/index.js +13 -0
  19. package/docs/build/data.json +117 -106
  20. package/lib/broccoli/ember-addon.js +1 -1
  21. package/lib/broccoli/ember-app.js +30 -4
  22. package/lib/broccoli/vendor-prefix.js +7 -0
  23. package/lib/cli/cli.js +6 -4
  24. package/lib/cli/index.js +1 -1
  25. package/lib/cli/lookup-command.js +6 -2
  26. package/lib/commands/destroy.js +1 -1
  27. package/lib/commands/generate.js +3 -3
  28. package/lib/commands/init.js +1 -2
  29. package/lib/models/addon.js +1 -18
  30. package/lib/models/blueprint.js +19 -11
  31. package/lib/models/command.js +10 -15
  32. package/lib/models/project.js +8 -8
  33. package/lib/tasks/addon-install.js +1 -1
  34. package/lib/tasks/create-and-step-into-directory.js +2 -26
  35. package/lib/tasks/generate-from-blueprint.js +1 -1
  36. package/lib/tasks/install-blueprint.js +1 -1
  37. package/lib/tasks/server/express-server.js +1 -1
  38. package/lib/tasks/server/livereload-server.js +1 -1
  39. package/lib/utilities/directory-for-package-name.js +31 -0
  40. package/lib/utilities/find-addon-by-name.js +4 -37
  41. package/lib/utilities/is-live-reload-request.js +1 -11
  42. package/lib/utilities/markdown-color.js +1 -1
  43. package/lib/utilities/sequence.js +7 -5
  44. package/package.json +28 -28
  45. package/tests/helpers/copy-fixture-files.js +4 -1
  46. package/tests/helpers/default-packager.js +0 -1
  47. package/tests/helpers/fixturify-project.js +1 -1
  48. package/tests/helpers/run-command.js +1 -1
  49. package/blueprints/server/files/server/.eslintrc.js +0 -5
  50. package/lib/errors/cli.js +0 -3
  51. package/lib/errors/silent.js +0 -19
  52. package/lib/utilities/default-targets.js +0 -5
  53. package/lib/utilities/deprecate.js +0 -9
@@ -3,7 +3,7 @@
3
3
  /**
4
4
  @module ember-cli
5
5
  */
6
- const defaultsDeep = require('ember-cli-lodash-subset').defaultsDeep;
6
+ const { defaultsDeep } = require('ember-cli-lodash-subset');
7
7
  const Funnel = require('broccoli-funnel');
8
8
  const fs = require('fs');
9
9
 
@@ -24,10 +24,7 @@ const broccoliMergeTrees = require('broccoli-merge-trees');
24
24
  const WatchedDir = require('broccoli-source').WatchedDir;
25
25
  const UnwatchedDir = require('broccoli-source').UnwatchedDir;
26
26
 
27
- const merge = require('ember-cli-lodash-subset').merge;
28
- const defaultsDeep = require('ember-cli-lodash-subset').defaultsDeep;
29
- const omitBy = require('ember-cli-lodash-subset').omitBy;
30
- const isNull = require('ember-cli-lodash-subset').isNull;
27
+ const { merge, defaultsDeep, omitBy, isNull } = require('ember-cli-lodash-subset');
31
28
  const Funnel = require('broccoli-funnel');
32
29
  const logger = require('heimdalljs-logger')('ember-cli:ember-app');
33
30
  const addonProcessTree = require('../utilities/addon-process-tree');
@@ -36,6 +33,7 @@ const emberCLIBabelConfigKey = require('../utilities/ember-cli-babel-config-key'
36
33
  const { isExperimentEnabled } = require('../experiments');
37
34
  const semver = require('semver');
38
35
  const DefaultPackager = require('./default-packager');
36
+ const { deprecate } = require('../debug');
39
37
 
40
38
  let DEFAULT_CONFIG = {
41
39
  storeConfigInMeta: true,
@@ -371,6 +369,20 @@ class EmberApp {
371
369
  this.options = defaultsDeep(options, detectedDefaultOptions, DEFAULT_CONFIG);
372
370
 
373
371
  if (this.options.addons.blacklist) {
372
+ deprecate(
373
+ 'Using the `addons.blacklist` build option is deprecated. Please use `addons.exclude` instead.',
374
+ false,
375
+ {
376
+ for: 'ember-cli',
377
+ id: 'ember-cli.blacklist-whitelist-build-options',
378
+ since: {
379
+ available: '4.4.0',
380
+ enabled: '4.4.0',
381
+ },
382
+ until: '5.0.0',
383
+ }
384
+ );
385
+
374
386
  if (this.options.addons.exclude) {
375
387
  throw new Error('Specifying both "blacklist" and "exclude" is not supported. Please use only one.');
376
388
  }
@@ -388,6 +400,20 @@ class EmberApp {
388
400
  });
389
401
 
390
402
  if (this.options.addons.whitelist) {
403
+ deprecate(
404
+ 'Using the `addons.whitelist` build option is deprecated. Please use `addons.include` instead.',
405
+ false,
406
+ {
407
+ for: 'ember-cli',
408
+ id: 'ember-cli.blacklist-whitelist-build-options',
409
+ since: {
410
+ available: '4.4.0',
411
+ enabled: '4.4.0',
412
+ },
413
+ until: '5.0.0',
414
+ }
415
+ );
416
+
391
417
  if (this.options.addons.include) {
392
418
  throw new Error('Specifying both "whitelist" and "include" is not supported. Please use only one.');
393
419
  }
@@ -6,6 +6,13 @@ window.EmberENV = (function(EmberENV, extra) {
6
6
  return EmberENV;
7
7
  })(window.EmberENV || {}, {{EMBER_ENV}});
8
8
 
9
+ // used to determine if the application should be booted immediately when `app-name.js` is evaluated
10
+ // when `runningTests` the `app-name.js` file will **not** import the applications `app/app.js` and
11
+ // call `Application.create(...)` on it. Additionally, applications can opt-out of this behavior by
12
+ // setting `autoRun` to `false` in their `ember-cli-build.js`
13
+ //
14
+ // The default `test-support.js` file will set this to `true` when it runs (so that Application.create()
15
+ // is not ran when running tests).
9
16
  var runningTests = false;
10
17
 
11
18
  {{content-for 'vendor-prefix'}}
package/lib/cli/cli.js CHANGED
@@ -151,20 +151,22 @@ class CLI {
151
151
 
152
152
  let platformCheckerToken = heimdall.start('platform-checker');
153
153
 
154
+ const emberCLIVersion = require('../../package.json').version;
154
155
  const PlatformChecker = require('../utilities/platform-checker');
155
156
  let platform = new PlatformChecker(process.version);
156
157
  let recommendation =
157
- ' We recommend that you use the most-recent "Active LTS" version of Node.js.' +
158
- ' See https://git.io/v7S5n for details.';
158
+ ' See "https://github.com/ember-cli/ember-cli/blob/master/docs/node-support.md" to find out which version of Node is best to use.';
159
159
 
160
160
  if (!this.testing) {
161
161
  if (platform.isDeprecated) {
162
- this.ui.writeDeprecateLine(`Node ${process.version} is no longer supported by Ember CLI.${recommendation}`);
162
+ this.ui.writeDeprecateLine(
163
+ `Node ${process.version} is no longer supported by Ember CLI v${emberCLIVersion}.${recommendation}`
164
+ );
163
165
  }
164
166
 
165
167
  if (!platform.isTested) {
166
168
  this.ui.writeWarnLine(
167
- `Node ${process.version} is not tested against Ember CLI on your platform.${recommendation}`
169
+ `Ember CLI v${emberCLIVersion} is not tested against Node ${process.version}.${recommendation}`
168
170
  );
169
171
  }
170
172
  }
package/lib/cli/index.js CHANGED
@@ -19,7 +19,7 @@ if (instrumentation.instrumentationEnabled()) {
19
19
  const requireAsHash = require('../utilities/require-as-hash');
20
20
  const packageConfig = require('../../package.json');
21
21
  const logger = require('heimdalljs-logger')('ember-cli:cli/index');
22
- const merge = require('ember-cli-lodash-subset').merge;
22
+ const { merge } = require('ember-cli-lodash-subset');
23
23
  const path = require('path');
24
24
  const heimdall = require('heimdalljs');
25
25
 
@@ -27,11 +27,15 @@ module.exports = function (commands, commandName, commandArgs, optionHash) {
27
27
  // Attempt to find command in ember-cli core commands
28
28
  let command = findCommand(commands, commandName);
29
29
 
30
+ let addonWithCommand;
30
31
  let addonCommand;
31
32
  // Attempt to find command within addons
32
33
  if (project && project.eachAddonCommand) {
33
34
  project.eachAddonCommand((addonName, commands) => {
34
35
  addonCommand = findCommand(commands, commandName);
36
+ if (addonCommand) {
37
+ addonWithCommand = addonName;
38
+ }
35
39
  return !addonCommand;
36
40
  });
37
41
  }
@@ -39,7 +43,7 @@ module.exports = function (commands, commandName, commandArgs, optionHash) {
39
43
  if (command && addonCommand) {
40
44
  if (addonCommand.overrideCore) {
41
45
  ui.writeWarnLine(
42
- `An ember-addon has attempted to override the core command "${command.prototype.name}". ` +
46
+ `An ember-addon (${addonWithCommand}) has attempted to override the core command "${command.prototype.name}". ` +
43
47
  `The addon command will be used as the overridding was explicit.`
44
48
  );
45
49
 
@@ -47,7 +51,7 @@ module.exports = function (commands, commandName, commandArgs, optionHash) {
47
51
  }
48
52
 
49
53
  ui.writeWarnLine(
50
- `An ember-addon has attempted to override the core command "${command.prototype.name}". ` +
54
+ `An ember-addon (${addonWithCommand}) has attempted to override the core command "${command.prototype.name}". ` +
51
55
  `The core command will be used.`
52
56
  );
53
57
  return command;
@@ -3,7 +3,7 @@
3
3
  const path = require('path');
4
4
  const Command = require('../models/command');
5
5
  const mergeBlueprintOptions = require('../utilities/merge-blueprint-options');
6
- const merge = require('ember-cli-lodash-subset').merge;
6
+ const { merge } = require('ember-cli-lodash-subset');
7
7
  const SilentError = require('silent-error');
8
8
 
9
9
  module.exports = Command.extend({
@@ -5,7 +5,7 @@ const chalk = require('chalk');
5
5
  const Command = require('../models/command');
6
6
  const Blueprint = require('../models/blueprint');
7
7
  const mergeBlueprintOptions = require('../utilities/merge-blueprint-options');
8
- const _ = require('ember-cli-lodash-subset');
8
+ const { merge, reject } = require('ember-cli-lodash-subset');
9
9
  const EOL = require('os').EOL;
10
10
  const SilentError = require('silent-error');
11
11
 
@@ -75,7 +75,7 @@ module.exports = Command.extend({
75
75
  commandOptions.in = path.resolve(relativePath);
76
76
  }
77
77
 
78
- let taskOptions = _.merge(taskArgs, commandOptions || {});
78
+ let taskOptions = merge(taskArgs, commandOptions || {});
79
79
 
80
80
  if (this.project.initializeAddons) {
81
81
  this.project.initializeAddons();
@@ -136,7 +136,7 @@ module.exports = Command.extend({
136
136
  let blueprints = collection.blueprints;
137
137
 
138
138
  if (!verbose) {
139
- blueprints = _.reject(blueprints, 'overridden');
139
+ blueprints = reject(blueprints, 'overridden');
140
140
  }
141
141
 
142
142
  let output = '';
@@ -1,7 +1,6 @@
1
1
  'use strict';
2
2
 
3
- const clone = require('ember-cli-lodash-subset').clone;
4
- const merge = require('ember-cli-lodash-subset').merge;
3
+ const { clone, merge } = require('ember-cli-lodash-subset');
5
4
  const Command = require('../models/command');
6
5
  const SilentError = require('silent-error');
7
6
  const chalk = require('chalk');
@@ -27,7 +27,7 @@ const mergeTrees = require('../broccoli/merge-trees');
27
27
  const Funnel = require('broccoli-funnel');
28
28
  const walkSync = require('walk-sync');
29
29
  const ensurePosixPath = require('ensure-posix-path');
30
- const defaultsDeep = require('ember-cli-lodash-subset').defaultsDeep;
30
+ const { defaultsDeep } = require('ember-cli-lodash-subset');
31
31
  const findAddonByName = require('../utilities/find-addon-by-name');
32
32
  const heimdall = require('heimdalljs');
33
33
  const calculateCacheKeyForTree = require('calculate-cache-key-for-tree');
@@ -1269,23 +1269,6 @@ let addonProto = {
1269
1269
  });
1270
1270
  },
1271
1271
 
1272
- /**
1273
- Returns a tree containing the addon's js files
1274
-
1275
- @private
1276
- @deprecated
1277
- @method addonJsFiles
1278
- @return {Tree} The filtered addon js files
1279
- */
1280
- addonJsFiles(tree) {
1281
- this._warn(`Addon.prototype.addonJsFiles is deprecated`);
1282
-
1283
- return new Funnel(tree, {
1284
- destDir: this.moduleName(),
1285
- annotation: 'Funnel: Addon JS',
1286
- });
1287
- },
1288
-
1289
1272
  /**
1290
1273
  Preprocesses a javascript tree.
1291
1274
 
@@ -15,7 +15,7 @@ const inflector = require('inflection');
15
15
  const minimatch = require('minimatch');
16
16
  const path = require('path');
17
17
  const stringUtils = require('ember-cli-string-utils');
18
- const _ = require('ember-cli-lodash-subset');
18
+ const { merge, zipObject, intersection, cloneDeep, compact, uniq } = require('ember-cli-lodash-subset');
19
19
  const walkSync = require('walk-sync');
20
20
  const SilentError = require('silent-error');
21
21
  const CoreObject = require('core-object');
@@ -723,7 +723,7 @@ let Blueprint = CoreObject.extend({
723
723
  };
724
724
 
725
725
  let customTokens = this.fileMapTokens(options) || options.fileMapTokens || {};
726
- return _.merge(standardTokens, customTokens);
726
+ return merge(standardTokens, customTokens);
727
727
  },
728
728
 
729
729
  /**
@@ -735,10 +735,10 @@ let Blueprint = CoreObject.extend({
735
735
  */
736
736
  generateFileMap(fileMapVariables) {
737
737
  let tokens = this._fileMapTokens(fileMapVariables);
738
- let fileMapValues = _.values(tokens);
738
+ let fileMapValues = Object.values(tokens);
739
739
  let tokenValues = fileMapValues.map((token) => token(fileMapVariables));
740
740
  let tokenKeys = Object.keys(tokens);
741
- return _.zipObject(tokenKeys, tokenValues);
741
+ return zipObject(tokenKeys, tokenValues);
742
742
  },
743
743
 
744
744
  /**
@@ -807,7 +807,7 @@ let Blueprint = CoreObject.extend({
807
807
  let files = this.files(this.options);
808
808
 
809
809
  // if we've defined targetFiles, get file info on ones that match
810
- return (targetFiles && targetFiles.length > 0 && _.intersection(files, targetFiles)) || files;
810
+ return (targetFiles && targetFiles.length > 0 && intersection(files, targetFiles)) || files;
811
811
  },
812
812
 
813
813
  /**
@@ -996,7 +996,7 @@ let Blueprint = CoreObject.extend({
996
996
  rawArgs: options.rawArgs,
997
997
  };
998
998
 
999
- return _.merge({}, standardLocals, customLocals);
999
+ return merge({}, standardLocals, customLocals);
1000
1000
  });
1001
1001
  },
1002
1002
 
@@ -1130,7 +1130,11 @@ let Blueprint = CoreObject.extend({
1130
1130
  },
1131
1131
 
1132
1132
  /**
1133
- Used to add a package to the projects `bower.json`.
1133
+ Used to add a Bower package to the projects `bower.json`.
1134
+
1135
+ Bower is a package manager that is no longer recommended
1136
+ for new projects, but you may find this hook used in older
1137
+ addons.
1134
1138
 
1135
1139
  Generally, this would be done from the `afterInstall` hook, to
1136
1140
  ensure that a package that is required by a given blueprint is
@@ -1180,6 +1184,10 @@ let Blueprint = CoreObject.extend({
1180
1184
 
1181
1185
  /**
1182
1186
  Used to add an array of packages to the projects `bower.json`.
1187
+
1188
+ Bower is a package manager that is no longer recommended
1189
+ for new projects, but you may find this hook used in older
1190
+ addons.
1183
1191
 
1184
1192
  Generally, this would be done from the `afterInstall` hook, to
1185
1193
  ensure that a package that is required by a given blueprint is
@@ -1402,7 +1410,7 @@ let Blueprint = CoreObject.extend({
1402
1410
  this._printableProperties.forEach((key) => {
1403
1411
  let value = this[key];
1404
1412
  if (key === 'availableOptions') {
1405
- value = _.cloneDeep(value);
1413
+ value = cloneDeep(value);
1406
1414
  value.forEach((option) => {
1407
1415
  if (typeof option.type === 'function') {
1408
1416
  option.type = option.type.name;
@@ -1540,7 +1548,7 @@ Blueprint.list = function (options) {
1540
1548
  let blueprint = Blueprint.load(blueprintPath);
1541
1549
  if (blueprint) {
1542
1550
  let name = blueprint.name;
1543
- blueprint.overridden = _.includes(seen, name);
1551
+ blueprint.overridden = seen.includes(name);
1544
1552
  seen.push(name);
1545
1553
 
1546
1554
  return blueprint;
@@ -1549,7 +1557,7 @@ Blueprint.list = function (options) {
1549
1557
 
1550
1558
  return {
1551
1559
  source,
1552
- blueprints: _.compact(blueprints),
1560
+ blueprints: compact(blueprints),
1553
1561
  };
1554
1562
  });
1555
1563
  };
@@ -1668,7 +1676,7 @@ function isIgnored(info) {
1668
1676
  function generateLookupPaths(lookupPaths) {
1669
1677
  lookupPaths = lookupPaths || [];
1670
1678
  lookupPaths = lookupPaths.concat(Blueprint.defaultLookupPaths());
1671
- return _.uniq(lookupPaths);
1679
+ return uniq(lookupPaths);
1672
1680
  }
1673
1681
 
1674
1682
  /**
@@ -7,7 +7,7 @@ const isGitRepo = require('is-git-url');
7
7
  const camelize = require('ember-cli-string-utils').camelize;
8
8
  const getCallerFile = require('get-caller-file');
9
9
  const printCommand = require('../utilities/print-command');
10
- const _ = require('ember-cli-lodash-subset');
10
+ const { union, defaults, uniq, uniqBy, reject } = require('ember-cli-lodash-subset');
11
11
  const EOL = require('os').EOL;
12
12
  const CoreObject = require('core-object');
13
13
  const logger = require('heimdalljs-logger')('ember-cli:command');
@@ -163,12 +163,12 @@ let Command = CoreObject.extend({
163
163
  let extendedAvailableOptions = (options && options.availableOptions) || [];
164
164
  let extendedAnonymousOptions = (options && options.anonymousOptions) || [];
165
165
 
166
- this.anonymousOptions = _.union(this.anonymousOptions.slice(0), extendedAnonymousOptions);
166
+ this.anonymousOptions = union(this.anonymousOptions.slice(0), extendedAnonymousOptions);
167
167
 
168
168
  // merge any availableOptions
169
- this.availableOptions = _.union(this.availableOptions.slice(0), extendedAvailableOptions);
169
+ this.availableOptions = union(this.availableOptions.slice(0), extendedAvailableOptions);
170
170
 
171
- let optionKeys = _.uniq(_.map(this.availableOptions, 'name'));
171
+ let optionKeys = uniq(this.availableOptions.map((option) => option.name));
172
172
 
173
173
  optionKeys.map(this.mergeDuplicateOption.bind(this));
174
174
 
@@ -345,23 +345,17 @@ let Command = CoreObject.extend({
345
345
  mergeDuplicateOption(key) {
346
346
  let duplicateOptions, mergedOption, mergedAliases;
347
347
  // get duplicates to merge
348
- duplicateOptions = _.filter(this.availableOptions, { name: key });
348
+ duplicateOptions = this.availableOptions.filter((option) => option.name === key);
349
349
 
350
350
  if (duplicateOptions.length > 1) {
351
351
  // TODO: warn on duplicates and overwriting
352
- mergedAliases = [];
353
-
354
- _.map(duplicateOptions, 'aliases').map((alias) => {
355
- alias.map((a) => {
356
- mergedAliases.push(a);
357
- });
358
- });
352
+ mergedAliases = duplicateOptions.flatMap((option) => option.aliases);
359
353
 
360
354
  // merge duplicate options
361
355
  mergedOption = Object.assign.apply(null, duplicateOptions);
362
356
 
363
357
  // replace aliases with unique aliases
364
- mergedOption.aliases = _.uniqBy(mergedAliases, (alias) => {
358
+ mergedOption.aliases = uniqBy(mergedAliases, (alias) => {
365
359
  if (typeof alias === 'object') {
366
360
  return alias[Object.keys(alias)[0]];
367
361
  }
@@ -369,9 +363,10 @@ let Command = CoreObject.extend({
369
363
  });
370
364
 
371
365
  // remove duplicates from options
372
- this.availableOptions = _.reject(this.availableOptions, { name: key });
366
+ this.availableOptions = reject(this.availableOptions, { name: key });
373
367
  this.availableOptions.push(mergedOption);
374
368
  }
369
+
375
370
  return this.availableOptions;
376
371
  },
377
372
 
@@ -589,7 +584,7 @@ let Command = CoreObject.extend({
589
584
  Object.keys(parsedOptions).map(validateParsed.bind(this));
590
585
 
591
586
  return {
592
- options: _.defaults(commandOptions, this.settings),
587
+ options: defaults(commandOptions, this.settings),
593
588
  args: parsedOptions.argv.remain,
594
589
  };
595
590
  },
@@ -8,7 +8,7 @@ const path = require('path');
8
8
  const findup = require('find-up');
9
9
  const resolve = util.promisify(require('resolve'));
10
10
  const fs = require('fs-extra');
11
- const _ = require('ember-cli-lodash-subset');
11
+ const { cloneDeep, merge, forOwn } = require('ember-cli-lodash-subset');
12
12
  const logger = require('heimdalljs-logger')('ember-cli:project');
13
13
  const versionUtils = require('../utilities/version-utils');
14
14
  const emberCLIVersion = versionUtils.emberCLIVersion;
@@ -267,7 +267,7 @@ class Project {
267
267
  config = this.configWithoutCache(_env);
268
268
  this.configCache.set(key, config);
269
269
  }
270
- return _.cloneDeep(config);
270
+ return cloneDeep(config);
271
271
  }
272
272
 
273
273
  /**
@@ -283,7 +283,7 @@ class Project {
283
283
  let appConfig = this.require(configPath)(env);
284
284
  let addonsConfig = this.getAddonsConfig(env, appConfig);
285
285
 
286
- return _.merge(addonsConfig, appConfig);
286
+ return merge(addonsConfig, appConfig);
287
287
  } else {
288
288
  return this.getAddonsConfig(env, {});
289
289
  }
@@ -311,7 +311,7 @@ class Project {
311
311
  if (fs.existsSync(`${targetsPath}.js`)) {
312
312
  this._targets = this.require(targetsPath);
313
313
  } else {
314
- this._targets = require('../utilities/default-targets');
314
+ this._targets = require('../../blueprints/app/files/config/targets');
315
315
  }
316
316
  return this._targets;
317
317
  }
@@ -328,11 +328,11 @@ class Project {
328
328
  getAddonsConfig(env, appConfig) {
329
329
  this.initializeAddons();
330
330
 
331
- let initialConfig = _.merge({}, appConfig);
331
+ let initialConfig = merge({}, appConfig);
332
332
 
333
333
  return this.addons.reduce((config, addon) => {
334
334
  if (addon.config) {
335
- _.merge(config, addon.config(env, config));
335
+ merge(config, addon.config(env, config));
336
336
  }
337
337
 
338
338
  return config;
@@ -474,9 +474,9 @@ class Project {
474
474
  */
475
475
  discoverAddons() {
476
476
  if (this._didDiscoverAddons) {
477
- this._didDiscoverAddons = true;
478
477
  return;
479
478
  }
479
+ this._didDiscoverAddons = true;
480
480
 
481
481
  let addonPackageList = this._packageInfo.discoverProjectAddons();
482
482
  this.addonPackages = this._packageInfo.generateAddonPackages(addonPackageList);
@@ -565,7 +565,7 @@ class Project {
565
565
  this.initializeAddons();
566
566
  let addonCommands = this.addonCommands();
567
567
 
568
- _.forOwn(addonCommands, (commands, addonName) => callback(addonName, commands));
568
+ forOwn(addonCommands, (commands, addonName) => callback(addonName, commands));
569
569
  }
570
570
  }
571
571
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  const Task = require('../models/task');
4
4
  const SilentError = require('silent-error');
5
- const merge = require('ember-cli-lodash-subset').merge;
5
+ const { merge } = require('ember-cli-lodash-subset');
6
6
  const getPackageBaseName = require('../utilities/get-package-base-name');
7
7
 
8
8
  class AddonInstallTask extends Task {
@@ -4,33 +4,9 @@
4
4
  // this directory.
5
5
 
6
6
  const fs = require('fs-extra');
7
- const path = require('path');
8
7
  const Task = require('../models/task');
9
8
  const SilentError = require('silent-error');
10
-
11
- // used in order to infer the directory to use, if `--directory` was specified
12
- // to `ember new`/`ember addon` it will **always** be used directly (without
13
- // modification)
14
- function chooseDirectoryName(projectName) {
15
- let isScoped = projectName[0] === '@' && projectName.includes('/');
16
-
17
- if (isScoped) {
18
- let slashIndex = projectName.indexOf('/');
19
- let scopeName = projectName.substring(1, slashIndex);
20
- let packageNameWithoutScope = projectName.substring(slashIndex + 1);
21
- let pathParts = process.cwd().split(path.sep);
22
-
23
- let parentDirectoryContainsScopeName = pathParts.includes(scopeName);
24
-
25
- if (parentDirectoryContainsScopeName) {
26
- return packageNameWithoutScope;
27
- } else {
28
- return `${scopeName}-${packageNameWithoutScope}`;
29
- }
30
- } else {
31
- return projectName;
32
- }
33
- }
9
+ const directoryForPackageName = require('../utilities/directory-for-package-name');
34
10
 
35
11
  class CreateTask extends Task {
36
12
  // Options: String directoryName, Boolean: dryRun
@@ -41,7 +17,7 @@ class CreateTask extends Task {
41
17
  }
42
18
 
43
19
  async run(options) {
44
- let directoryName = options.directoryName ? options.directoryName : chooseDirectoryName(options.projectName);
20
+ let directoryName = options.directoryName ? options.directoryName : directoryForPackageName(options.projectName);
45
21
 
46
22
  if (options.dryRun) {
47
23
  if (fs.existsSync(directoryName) && fs.readdirSync(directoryName).length) {
@@ -3,7 +3,7 @@
3
3
  const Blueprint = require('../models/blueprint');
4
4
  const Task = require('../models/task');
5
5
  const parseOptions = require('../utilities/parse-options');
6
- const merge = require('ember-cli-lodash-subset').merge;
6
+ const { merge } = require('ember-cli-lodash-subset');
7
7
  const logger = require('heimdalljs-logger')('ember-cli:generate-from-blueprint');
8
8
  const lintFix = require('../utilities/lint-fix');
9
9
 
@@ -6,7 +6,7 @@ const Task = require('../models/task');
6
6
  const util = require('util');
7
7
  const temp = require('temp');
8
8
  const path = require('path');
9
- const merge = require('ember-cli-lodash-subset').merge;
9
+ const { merge } = require('ember-cli-lodash-subset');
10
10
  const execa = require('../utilities/execa');
11
11
  const SilentError = require('silent-error');
12
12
  const npa = require('npm-package-arg');
@@ -4,7 +4,7 @@ const path = require('path');
4
4
  const EventEmitter = require('events').EventEmitter;
5
5
  const chalk = require('chalk');
6
6
  const fs = require('fs');
7
- const debounce = require('ember-cli-lodash-subset').debounce;
7
+ const { debounce } = require('ember-cli-lodash-subset');
8
8
  const mapSeries = require('promise-map-series');
9
9
  const Task = require('../../models/task');
10
10
  const SilentError = require('silent-error');
@@ -133,7 +133,7 @@ module.exports = class LiveReloadServer {
133
133
 
134
134
  // this is required to prevent tiny-lr from triggering an error
135
135
  // when checking this.server._handle during its close handler
136
- // here: https://git.io/fA7Tr
136
+ // here: https://github.com/mklabs/tiny-lr/blob/d68d983eaf80b5bae78b2dba259a1ad5e3b03a63/lib/server.js#L209
137
137
  lrServer.server = this.httpServer;
138
138
 
139
139
  return lrServer;
@@ -0,0 +1,31 @@
1
+ 'use strict';
2
+
3
+ const path = require('path');
4
+
5
+ /**
6
+ * Derive a directory name from a package name.
7
+ * Takes scoped packages into account.
8
+ *
9
+ * @method directoryForPackageName
10
+ * @param {String} packageName
11
+ * @return {String} Derived directory name.
12
+ */
13
+ module.exports = function directoryForPackageName(packageName) {
14
+ let isScoped = packageName[0] === '@' && packageName.includes('/');
15
+
16
+ if (isScoped) {
17
+ let slashIndex = packageName.indexOf('/');
18
+ let scopeName = packageName.substring(1, slashIndex);
19
+ let packageNameWithoutScope = packageName.substring(slashIndex + 1);
20
+ let pathParts = process.cwd().split(path.sep);
21
+ let parentDirectoryContainsScopeName = pathParts.includes(scopeName);
22
+
23
+ if (parentDirectoryContainsScopeName) {
24
+ return packageNameWithoutScope;
25
+ } else {
26
+ return `${scopeName}-${packageNameWithoutScope}`;
27
+ }
28
+ } else {
29
+ return packageName;
30
+ }
31
+ };