ember-cli 3.4.4 → 3.5.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 (49) hide show
  1. package/.travis.yml +8 -7
  2. package/CHANGELOG.md +98 -6
  3. package/CONTRIBUTING.md +1 -1
  4. package/PERF_GUIDE.md +1 -1
  5. package/README.md +1 -1
  6. package/RELEASE.md +12 -10
  7. package/blueprints/addon/files/addon-config/ember-try.js +2 -2
  8. package/blueprints/addon/files/npmignore +2 -1
  9. package/blueprints/addon-import/index.js +3 -0
  10. package/blueprints/app/files/.eslintignore +2 -0
  11. package/blueprints/app/files/.eslintrc.js +1 -0
  12. package/blueprints/app/files/package.json +4 -4
  13. package/blueprints/module-unification-app/files/.eslintignore +2 -0
  14. package/blueprints/module-unification-app/files/.eslintrc.js +1 -0
  15. package/blueprints/module-unification-app/files/config/environment.js +1 -1
  16. package/blueprints/module-unification-app/files/config/targets.js +1 -1
  17. package/blueprints/module-unification-app/files/package.json +18 -17
  18. package/lib/broccoli/default-packager.js +7 -9
  19. package/lib/broccoli/ember-app.js +43 -34
  20. package/lib/commands/destroy.js +8 -0
  21. package/lib/commands/generate.js +8 -0
  22. package/lib/commands/new.js +2 -2
  23. package/lib/commands/serve.js +2 -0
  24. package/lib/errors/cli.js +4 -0
  25. package/lib/experiments/index.js +33 -12
  26. package/lib/models/addon-info.js +2 -2
  27. package/lib/models/addon.js +9 -10
  28. package/lib/models/blueprint.js +39 -7
  29. package/lib/models/builder.js +137 -17
  30. package/lib/models/command.js +2 -2
  31. package/lib/models/package-info-cache/index.js +11 -10
  32. package/lib/models/package-info-cache/package-info.js +9 -12
  33. package/lib/models/project.js +3 -3
  34. package/lib/models/watcher.js +2 -1
  35. package/lib/tasks/npm-task.js +1 -1
  36. package/lib/tasks/server/express-server.js +1 -1
  37. package/lib/tasks/server/livereload-server.js +2 -1
  38. package/lib/tasks/server/middleware/proxy-server/index.js +8 -3
  39. package/lib/utilities/default-targets.js +1 -1
  40. package/lib/utilities/find-build-file.js +2 -3
  41. package/lib/utilities/is-addon.js +6 -0
  42. package/lib/utilities/is-live-reload-request.js +17 -0
  43. package/lib/utilities/valid-project-name.js +1 -0
  44. package/package.json +8 -4
  45. package/tests/helpers/default-packager.js +1 -1
  46. package/tests/helpers/generate-utils.js +26 -0
  47. package/tests/helpers/init-app.js +14 -0
  48. package/tests/helpers/mock-project.js +5 -5
  49. package/yarn.lock +0 -5695
@@ -11,6 +11,7 @@ const findBuildFile = require('../utilities/find-build-file');
11
11
  const _resetTreeCache = require('./addon')._resetTreeCache;
12
12
  const Sync = require('tree-sync');
13
13
  const heimdall = require('heimdalljs');
14
+ const { isExperimentEnabled } = require('../experiments');
14
15
 
15
16
  /**
16
17
  * Wrapper for the Broccoli [Builder](https://github.com/broccolijs/broccoli/blob/master/lib/builder.js) class.
@@ -26,7 +27,10 @@ class Builder extends CoreObject {
26
27
  constructor(options) {
27
28
  super(options);
28
29
 
30
+ // Use Broccoli 2.0 by default, if this fails due to .read/.rebuild API, fallback to broccoli-builder
31
+ this.broccoliBuilderFallback = false;
29
32
  this.setupBroccoliBuilder();
33
+
30
34
  this._instantiationStack = (new Error()).stack.replace(/[^\n]*\n/, '');
31
35
  this._cleanup = this.cleanup.bind(this);
32
36
 
@@ -36,6 +40,21 @@ class Builder extends CoreObject {
36
40
  this._onProcessInterrupt.addHandler(this._cleanup);
37
41
  }
38
42
 
43
+ /**
44
+ * @private
45
+ * @method readBuildFile
46
+ * @param path The file path to read the build file from
47
+ */
48
+ readBuildFile(path) {
49
+ // Load the build file
50
+ let buildFile = findBuildFile('ember-cli-build.js', path);
51
+ if (buildFile) {
52
+ return buildFile({ project: this.project });
53
+ }
54
+
55
+ throw new SilentError('No ember-cli-build.js found.');
56
+ }
57
+
39
58
  /**
40
59
  * @private
41
60
  * @method setupBroccoliBuilder
@@ -44,16 +63,51 @@ class Builder extends CoreObject {
44
63
  this.environment = this.environment || 'development';
45
64
  process.env.EMBER_ENV = process.env.EMBER_ENV || this.environment;
46
65
 
47
- const broccoli = require('broccoli-builder');
66
+ this.tree = this.readBuildFile(this.project.root);
48
67
 
49
- let buildFile = findBuildFile('ember-cli-build.js');
50
- if (buildFile) {
51
- this.tree = buildFile({ project: this.project });
52
- } else {
53
- throw new SilentError('No ember-cli-build.js found.');
68
+ let broccoli, options = {};
69
+ if (isExperimentEnabled('BROCCOLI_2')) {
70
+ broccoli = require('broccoli');
71
+ let tmpDir;
72
+
73
+ // If not using system temp dir, compatability mode with broccoli-builder, tmp in root
74
+ if (!isExperimentEnabled('SYSTEM_TEMP')) {
75
+ tmpDir = `${this.project.root}/tmp`;
76
+ if (!fs.existsSync(tmpDir)) {
77
+ fs.mkdir(tmpDir);
78
+ }
79
+ }
80
+ options = {
81
+ tmpdir: tmpDir,
82
+ };
83
+
84
+ try {
85
+ this.builder = new broccoli.Builder(this.tree, options);
86
+ return;
87
+ } catch (e) {
88
+ // Catch here to trap InvalidNodeError. If this is thrown, it's because the node provided is not valid
89
+ // and likely uses the old .read/.rebuild API, so fallback to broccoli-builder that supports that API
90
+ if (
91
+ !(e instanceof broccoli.Builder.InvalidNodeError) ||
92
+ e.message.indexOf('The .read/.rebuild API is no longer supported as of Broccoli 1.0') === -1
93
+ ) {
94
+ throw e;
95
+ }
96
+
97
+ // Fallback to broccoli-builder
98
+ let error = `Invalid Broccoli2 node detected, falling back to broccoli-builder. Broccoli error:\n`;
99
+ error += `---------------\n`;
100
+ error += e.message;
101
+ error += `---------------\n`;
102
+ this.ui.writeWarnLine(error);
103
+ }
104
+ } else if (isExperimentEnabled('SYSTEM_TEMP')) {
105
+ this.ui.writeWarnLine('EMBER_CLI_SYSTEM_TEMP only works in combination with EMBER_CLI_BROCCOLI_2');
54
106
  }
55
107
 
56
- this.builder = new broccoli.Builder(this.tree);
108
+ broccoli = require('broccoli-builder');
109
+ this.broccoliBuilderFallback = true;
110
+ this.builder = new broccoli.Builder(this.tree, options);
57
111
  }
58
112
 
59
113
  /**
@@ -145,13 +199,22 @@ class Builder extends CoreObject {
145
199
  * @method build
146
200
  * @return {Promise}
147
201
  */
148
- build(willReadStringDir, resultAnnotation) {
202
+ build(addWatchDirCallback, resultAnnotation) {
149
203
  this.project._instrumentation.start('build');
150
204
 
151
- attemptNeverIndex('tmp');
205
+ if (!isExperimentEnabled('SYSTEM_TEMP')) {
206
+ attemptNeverIndex('tmp');
207
+ }
208
+
209
+ if (addWatchDirCallback && !this.broccoliBuilderFallback) {
210
+ for (let path of this.builder.watchedPaths) {
211
+ addWatchDirCallback(path);
212
+ }
213
+ }
152
214
 
153
215
  return this.processAddonBuildSteps('preBuild')
154
- .then(() => this.builder.build(willReadStringDir))
216
+ .then(() => this.builder.build(this.broccoliBuilderFallback ? addWatchDirCallback : null))
217
+ .then(this.compatNode.bind(this), this.compatBroccoliPayload.bind(this))
155
218
  .then(this.processAddonBuildSteps.bind(this, 'postBuild'))
156
219
  .then(this.processBuildResult.bind(this))
157
220
  .then(this.processAddonBuildSteps.bind(this, 'outputReady'))
@@ -190,13 +253,15 @@ class Builder extends CoreObject {
190
253
 
191
254
  let node = heimdall.start({ name: 'Builder Cleanup' });
192
255
 
193
- this._cleanupPromise = this.builder.cleanup().finally(() => {
194
- ui.stopProgress();
195
- node.stop();
196
- }).catch(err => {
197
- ui.writeLine(chalk.red('Cleanup error.'));
198
- ui.writeError(err);
199
- });
256
+ this._cleanupPromise = Promise.resolve()
257
+ .then(() => this.builder.cleanup())
258
+ .finally(() => {
259
+ ui.stopProgress();
260
+ node.stop();
261
+ }).catch(err => {
262
+ ui.writeLine(chalk.red('Cleanup error.'));
263
+ ui.writeError(err);
264
+ });
200
265
  }
201
266
 
202
267
  return this._cleanupPromise;
@@ -226,6 +291,61 @@ class Builder extends CoreObject {
226
291
  finalizeBuild() {
227
292
  this.project.configCache.clear();
228
293
  }
294
+
295
+ /**
296
+ * broccoli-builder reformats the response into {directory, graph}, this method is a backwards
297
+ * compatible shim for broccoli 1.x
298
+ * @private
299
+ * @method compatNode
300
+ * @param node The node returned from Broccoli builder
301
+ */
302
+ compatNode(node) {
303
+ if (!this.broccoliBuilderFallback) {
304
+ return {
305
+ directory: this.builder.outputPath,
306
+ graph: this.builder.outputNodeWrapper,
307
+ };
308
+ }
309
+
310
+ return node;
311
+ }
312
+
313
+ compatBroccoliPayload(err) {
314
+ // TODO fix ember-cli/console-ui to handle current broccoli broccoliPayload
315
+ let broccoliPayload = err && err.broccoliPayload;
316
+ if (broccoliPayload) {
317
+ if (!broccoliPayload.error) {
318
+ let originalError = broccoliPayload.originalError || {};
319
+ let location = broccoliPayload.location || originalError.location;
320
+ broccoliPayload.error = {
321
+ message: originalError.message,
322
+ stack: originalError.stack,
323
+ errorType: originalError.type || 'Build Error',
324
+ codeFrame: originalError.codeFrame || originalError.message,
325
+ location: location || {},
326
+ };
327
+ }
328
+ if (!broccoliPayload.broccoliNode) {
329
+ broccoliPayload.broccoliNode = {
330
+ nodeName: broccoliPayload.nodeName,
331
+ nodeAnnotation: broccoliPayload.nodeAnnotation,
332
+ instantiationStack: broccoliPayload.instantiationStack || '',
333
+ };
334
+ }
335
+ if (!broccoliPayload.versions) {
336
+ let builderVersion = this.broccoliBuilderFallback
337
+ ? require('broccoli-builder/package').version
338
+ : require('broccoli/package').version;
339
+
340
+ broccoliPayload.versions = {
341
+ 'broccoli-builder': builderVersion,
342
+ node: process.version,
343
+ };
344
+ }
345
+ }
346
+
347
+ throw err;
348
+ }
229
349
  }
230
350
 
231
351
  module.exports = Builder;
@@ -266,7 +266,7 @@ let Command = CoreObject.extend({
266
266
  @return {Promise}
267
267
  */
268
268
  validateAndRun(args) {
269
- return new Promise(resolve => {
269
+ return new Promise((resolve, reject) => {
270
270
  let commandOptions = this.parseArgs(args);
271
271
  // if the help option was passed, resolve with 'callHelp' to call help command
272
272
  if (commandOptions && (commandOptions.options.help || commandOptions.options.h)) {
@@ -280,7 +280,7 @@ let Command = CoreObject.extend({
280
280
  });
281
281
 
282
282
  if (commandOptions === null) {
283
- return resolve();
283
+ return reject();
284
284
  }
285
285
 
286
286
  if (this.works === 'outsideProject' && this.isWithinProject) {
@@ -11,6 +11,7 @@ const ErrorList = require('./error-list');
11
11
  const Errors = require('./errors');
12
12
  const PackageInfo = require('./package-info');
13
13
  const NodeModulesList = require('./node-modules-list');
14
+ const logger = require('heimdalljs-logger')('ember-cli:package-info-cache');
14
15
 
15
16
  let realFilePathCache;
16
17
  let realDirectoryPathCache;
@@ -178,29 +179,29 @@ class PackageInfoCache {
178
179
  return;
179
180
  }
180
181
 
181
- this.ui.writeWarnLine('');
182
+ logger.info('');
182
183
  let rootPath;
183
184
 
184
185
  if (obj instanceof PackageInfoCache) {
185
- this.ui.writeWarnLine('Top level errors:');
186
+ logger.info('Top level errors:');
186
187
  rootPath = this.realPath || '';
187
188
  } else {
188
189
  let typeName = (obj.project ? 'project' : 'addon');
189
190
 
190
- this.ui.writeWarnLine(`The 'package.json' file for the ${typeName} at ${obj.realPath}`);
191
+ logger.info(`The 'package.json' file for the ${typeName} at ${obj.realPath}`);
191
192
  rootPath = obj.realPath;
192
193
  }
193
194
 
194
195
  errorEntries.forEach(errorEntry => {
195
196
  switch (errorEntry.type) {
196
197
  case Errors.ERROR_PACKAGE_JSON_MISSING:
197
- this.ui.writeWarnLine(` does not exist`);
198
+ logger.info(` does not exist`);
198
199
  break;
199
200
  case Errors.ERROR_PACKAGE_JSON_PARSE:
200
- this.ui.writeWarnLine(` could not be parsed`);
201
+ logger.info(` could not be parsed`);
201
202
  break;
202
203
  case Errors.ERROR_EMBER_ADDON_MAIN_MISSING:
203
- this.ui.writeWarnLine(
204
+ logger.info(
204
205
  ` specifies a missing ember-addon 'main' file at relative path '${path.relative(
205
206
  rootPath,
206
207
  errorEntry.data
@@ -209,18 +210,18 @@ class PackageInfoCache {
209
210
  break;
210
211
  case Errors.ERROR_DEPENDENCIES_MISSING:
211
212
  if (errorEntry.data.length === 1) {
212
- this.ui.writeWarnLine(
213
+ logger.info(
213
214
  ` specifies a missing dependency '${errorEntry.data[0]}'`
214
215
  );
215
216
  } else {
216
- this.ui.writeWarnLine(` specifies some missing dependencies:`);
217
+ logger.info(` specifies some missing dependencies:`);
217
218
  errorEntry.data.forEach(dependencyName => {
218
- this.ui.writeWarnLine(` ${dependencyName}`);
219
+ logger.info(` ${dependencyName}`);
219
220
  });
220
221
  }
221
222
  break;
222
223
  case Errors.ERROR_NODEMODULES_ENTRY_MISSING:
223
- this.ui.writeWarnLine(` specifies a missing 'node_modules/${errorEntry.data}' directory`);
224
+ logger.info(` specifies a missing 'node_modules/${errorEntry.data}' directory`);
224
225
  break;
225
226
  }
226
227
  });
@@ -4,6 +4,8 @@ const path = require('path');
4
4
  const ErrorList = require('./error-list');
5
5
  const Errors = require('./errors');
6
6
  const AddonInfo = require('../addon-info');
7
+ const isAddon = require('../../utilities/is-addon');
8
+ const logger = require('heimdalljs-logger')('ember-cli:package-info-cache:package-info');
7
9
 
8
10
  function lexicographically(a, b) {
9
11
  const aIsString = typeof a.name === 'string';
@@ -218,10 +220,7 @@ class PackageInfo {
218
220
  }
219
221
 
220
222
  isAddon() {
221
- let val =
222
- Array.isArray(this.pkg.keywords) &&
223
- this.pkg.keywords.indexOf('ember-addon') >= 0;
224
- return val;
223
+ return isAddon(this.pkg.keywords);
225
224
  }
226
225
 
227
226
  /**
@@ -338,24 +337,22 @@ class PackageInfo {
338
337
 
339
338
  let invalidPackages = this.getInvalidPackages(addonPackageList);
340
339
 
341
- let ui = this.cache.ui;
342
-
343
- if (invalidPackages.length > 0 && ui && ui.writeWarnLine) {
340
+ if (invalidPackages.length > 0) {
344
341
  let typeName = (this.project ? 'project' : 'addon');
345
342
 
346
- ui.writeWarnLine('');
347
- ui.writeWarnLine(`The 'package.json' file for the ${typeName} at ${this.realPath}`);
343
+ logger.info('');
344
+ logger.info(`The 'package.json' file for the ${typeName} at ${this.realPath}`);
348
345
 
349
346
  let relativePath;
350
347
 
351
348
  if (invalidPackages.length === 1) {
352
349
  relativePath = path.relative(this.realPath, invalidPackages[0].realPath);
353
- ui.writeWarnLine(` specifies an invalid, malformed or missing addon at relative path '${relativePath}'`);
350
+ logger.info(` specifies an invalid, malformed or missing addon at relative path '${relativePath}'`);
354
351
  } else {
355
- ui.writeWarnLine(' specifies invalid, malformed or missing addons at relative paths');
352
+ logger.info(' specifies invalid, malformed or missing addons at relative paths');
356
353
  invalidPackages.forEach(packageInfo => {
357
354
  let relativePath = path.relative(this.realPath, packageInfo.realPath);
358
- ui.writeWarnLine(` '${relativePath}'`);
355
+ logger.info(` '${relativePath}'`);
359
356
  });
360
357
  }
361
358
  }
@@ -17,7 +17,6 @@ const heimdall = require('heimdalljs');
17
17
  const PackageInfoCache = require('../models/package-info-cache');
18
18
 
19
19
  const instantiateAddons = require('../models/instantiate-addons');
20
- const experiments = require('../experiments');
21
20
 
22
21
  let processCwd = process.cwd();
23
22
 
@@ -216,7 +215,8 @@ class Project {
216
215
  @return {Boolean} Whether this is using a module unification format.
217
216
  */
218
217
  isModuleUnification() {
219
- if (experiments.MODULE_UNIFICATION) {
218
+ const { isExperimentEnabled } = require('../experiments');
219
+ if (isExperimentEnabled('MODULE_UNIFICATION')) {
220
220
  return this.has('src');
221
221
  } else {
222
222
  return false;
@@ -630,7 +630,7 @@ class Project {
630
630
  Generate test file contents.
631
631
 
632
632
  This method is supposed to be overwritten by test framework addons
633
- like `ember-cli-qunit` and `ember-cli-mocha`.
633
+ like `ember-qunit` and `ember-mocha`.
634
634
 
635
635
  @public
636
636
  @method generateTestFile
@@ -20,6 +20,7 @@ class Watcher extends CoreObject {
20
20
 
21
21
  this.watcher.on('error', this.didError.bind(this));
22
22
  this.watcher.on('change', this.didChange.bind(this));
23
+ this.serveURL = serveURL;
23
24
  }
24
25
 
25
26
  constructWatcher(options) {
@@ -47,7 +48,7 @@ class Watcher extends CoreObject {
47
48
  this.ui.writeLine('');
48
49
 
49
50
  if (this.serving) {
50
- message += ` – Serving on ${serveURL(this.options, this.options.project)}`;
51
+ message += ` – Serving on ${this.serveURL(this.options, this.options.project)}`;
51
52
  }
52
53
 
53
54
  this.ui.writeLine(message);
@@ -26,7 +26,7 @@ class NpmTask extends Task {
26
26
  // The command to run: can be 'install' or 'uninstall'
27
27
  this.command = '';
28
28
 
29
- this.versionConstraints = '3 || 4 || 5';
29
+ this.versionConstraints = '3 || 4 || 5 || 6';
30
30
  }
31
31
 
32
32
  npm(args) {
@@ -214,7 +214,7 @@ class ExpressServerTask extends Task {
214
214
 
215
215
  let options = this.startOptions;
216
216
  options.httpServer = this.httpServer;
217
- let liveReloadServer = null;
217
+ let liveReloadServer;
218
218
 
219
219
  if (options.path) {
220
220
  liveReloadServer = {
@@ -8,6 +8,7 @@ const logger = require('heimdalljs-logger')('ember-cli:live-reload:');
8
8
  const fs = require('fs');
9
9
  const Promise = require('rsvp').Promise;
10
10
  const cleanBaseUrl = require('clean-base-url');
11
+ const isLiveReloadRequest = require('../../utilities/is-live-reload-request');
11
12
 
12
13
  function isNotRemoved(entryTuple) {
13
14
  let operation = entryTuple[0];
@@ -102,7 +103,7 @@ module.exports = class LiveReloadServer {
102
103
  // Reload on express server restarts
103
104
  this.app.on('restart', this.didRestart.bind(this));
104
105
  this.httpServer.on('upgrade', (req, socket, head) => {
105
- if (req.url.indexOf('/livereload') === 0) {
106
+ if (isLiveReloadRequest(req.url, this.liveReloadPrefix)) {
106
107
  this.liveReloadServer.websocketify(req, socket, head);
107
108
  }
108
109
  });
@@ -1,5 +1,8 @@
1
1
  'use strict';
2
2
 
3
+ // eslint-disable-next-line
4
+ const isLiveReloadRequest = require('../../../../utilities/is-live-reload-request');
5
+
3
6
  class ProxyServerAddon {
4
7
  constructor(project) {
5
8
  this.project = project;
@@ -18,6 +21,8 @@ class ProxyServerAddon {
18
21
  changeOrigin: true,
19
22
  xfwd: options.transparentProxy,
20
23
  preserveHeaderKeyCase: true,
24
+ proxyTimeout: options.proxyOutTimeout,
25
+ timeout: options.proxyInTimeout,
21
26
  });
22
27
 
23
28
  proxy.on('error', e => {
@@ -30,7 +35,7 @@ class ProxyServerAddon {
30
35
  options.ui.writeLine(`Proxying to ${options.proxy}`);
31
36
 
32
37
  server.on('upgrade', (req, socket, head) => {
33
- this.handleProxiedRequest(req, socket, head, options, proxy);
38
+ this.handleProxiedRequest({ req, socket, head, options, proxy });
34
39
  });
35
40
 
36
41
  app.use(morgan('dev'));
@@ -38,8 +43,8 @@ class ProxyServerAddon {
38
43
  }
39
44
  }
40
45
 
41
- handleProxiedRequest(req, socket, head, options, proxy) {
42
- if (req.url.indexOf('/livereload') === -1) {
46
+ handleProxiedRequest({ req, socket, head, options, proxy }) {
47
+ if (!isLiveReloadRequest(req.url, options.liveReloadPrefix)) {
43
48
  options.ui.writeLine(`Proxying websocket to ${req.url}`);
44
49
  proxy.ws(req, socket, head);
45
50
  }
@@ -2,7 +2,7 @@
2
2
 
3
3
  module.exports = {
4
4
  browsers: [
5
- 'ie 9',
5
+ 'ie 11',
6
6
  'last 1 Chrome versions',
7
7
  'last 1 Firefox versions',
8
8
  'last 1 Safari versions',
@@ -1,10 +1,9 @@
1
1
  'use strict';
2
-
3
2
  const findUp = require('find-up');
4
3
  const path = require('path');
5
4
 
6
- module.exports = function(file) {
7
- let buildFilePath = findUp.sync(file);
5
+ module.exports = function(file, dir) {
6
+ let buildFilePath = findUp.sync(file, { cwd: dir });
8
7
 
9
8
  // Note: In the future this should throw
10
9
  if (!buildFilePath) {
@@ -0,0 +1,6 @@
1
+ 'use strict';
2
+
3
+ module.exports = function isAddon(keywords) {
4
+ return Array.isArray(keywords) &&
5
+ keywords.indexOf('ember-addon') >= 0;
6
+ };
@@ -0,0 +1,17 @@
1
+ 'use strict';
2
+
3
+ const cleanBaseUrl = require('clean-base-url');
4
+ const deprecate = require('./deprecate');
5
+
6
+ module.exports = function isLiveReloadRequest(url, liveReloadPrefix) {
7
+ let regex = /\/livereload$/gi;
8
+ if (url === `${cleanBaseUrl(liveReloadPrefix)}livereload`) {
9
+ return true;
10
+ } else if (regex.test(url)) {
11
+ //version needs to be updated according to the this PR (https://github.com/ember-cli/ember-cli-inject-live-reload/pull/55)
12
+ //in master of ember-cli-inject-live-reload.
13
+ deprecate(`Upgrade ember-cli-inject-live-reload version to 1.10.0 or above`, true);
14
+ return true;
15
+ }
16
+ return false;
17
+ };
@@ -27,6 +27,7 @@ module.exports = function(name) {
27
27
  'ember',
28
28
  'ember-cli',
29
29
  'vendor',
30
+ 'public',
30
31
  'app',
31
32
  ];
32
33
  name = name.toLowerCase();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ember-cli",
3
- "version": "3.4.4",
3
+ "version": "3.5.1",
4
4
  "description": "Command line tool for developing ambitious ember.js apps",
5
5
  "keywords": [
6
6
  "app",
@@ -31,7 +31,7 @@
31
31
  "lint": "node tests/runner lint",
32
32
  "test": "node tests/runner",
33
33
  "test:all": "node tests/runner all",
34
- "test:cover": "istanbul cover tests/runner.js all",
34
+ "test:cover": "nyc node tests/runner all",
35
35
  "test:slow": "node tests/runner slow",
36
36
  "test:debug": "node debug tests/runner"
37
37
  },
@@ -40,7 +40,8 @@
40
40
  "babel-plugin-transform-es2015-modules-amd": "^6.24.1",
41
41
  "bower-config": "^1.3.0",
42
42
  "bower-endpoint-parser": "0.2.2",
43
- "broccoli-amd-funnel": "^1.3.0",
43
+ "broccoli": "^2.0.0",
44
+ "broccoli-amd-funnel": "^2.0.1",
44
45
  "broccoli-babel-transpiler": "^6.5.0",
45
46
  "broccoli-builder": "^0.18.14",
46
47
  "broccoli-concat": "^3.5.1",
@@ -79,6 +80,7 @@
79
80
  "filesize": "^3.6.1",
80
81
  "find-up": "^3.0.0",
81
82
  "find-yarn-workspace-root": "^1.1.0",
83
+ "fixturify": "^0.3.4",
82
84
  "fixturify-project": "^1.5.3",
83
85
  "fs-extra": "^7.0.0",
84
86
  "fs-tree-diff": "^0.5.7",
@@ -109,7 +111,7 @@
109
111
  "quick-temp": "^0.1.8",
110
112
  "resolve": "^1.8.1",
111
113
  "rsvp": "^4.8.3",
112
- "sane": "^3.0.0",
114
+ "sane": "^4.0.0",
113
115
  "semver": "^5.5.0",
114
116
  "silent-error": "^1.1.0",
115
117
  "sort-package-json": "^1.15.0",
@@ -141,6 +143,8 @@
141
143
  "mocha-eslint": "^4.1.0",
142
144
  "multiline": "^1.0.2",
143
145
  "nock": "^9.4.4",
146
+ "nyc": "^12.0.2",
147
+ "rimraf": "^2.6.2",
144
148
  "strip-ansi": "^4.0.0",
145
149
  "supertest": "^3.1.0",
146
150
  "testdouble": "^3.8.1",
@@ -127,7 +127,6 @@ const DEFAULT_SOURCE = {
127
127
  'ember-cli-htmlbars': '^3.0.0',
128
128
  'ember-cli-htmlbars-inline-precompile': '^1.0.0',
129
129
  'ember-cli-inject-live-reload': '^1.4.1',
130
- 'ember-cli-qunit': '^4.1.1',
131
130
  'ember-cli-sass': '^7.1.3',
132
131
  'ember-cli-shims': '^1.2.0',
133
132
  'ember-cli-sri': '^2.1.0',
@@ -135,6 +134,7 @@ const DEFAULT_SOURCE = {
135
134
  'ember-data': '~3.0.0-beta.1',
136
135
  'ember-export-application-global': '^2.0.0',
137
136
  'ember-load-initializers': '^1.0.0',
137
+ 'ember-qunit': '^3.4.1',
138
138
  'ember-resolver': '^4.0.0',
139
139
  'ember-source': '~3.0.0-beta.1',
140
140
  'loader.js': '^4.2.3',
@@ -0,0 +1,26 @@
1
+ 'use strict';
2
+
3
+ const RSVP = require('rsvp');
4
+ const fs = require('fs-extra');
5
+ let outputFile = RSVP.denodeify(fs.outputFile);
6
+ const ember = require('./ember');
7
+
8
+ function inRepoAddon(path) {
9
+ return ember([
10
+ 'generate',
11
+ 'in-repo-addon',
12
+ path,
13
+ ]);
14
+ }
15
+
16
+ function tempBlueprint() {
17
+ return outputFile(
18
+ 'blueprints/foo/files/__root__/foos/__name__.js',
19
+ '/* whoah, empty foo! */'
20
+ );
21
+ }
22
+
23
+ module.exports = {
24
+ inRepoAddon,
25
+ tempBlueprint,
26
+ };
@@ -0,0 +1,14 @@
1
+ 'use strict';
2
+
3
+ const ember = require('./ember');
4
+
5
+ function initApp() {
6
+ return ember([
7
+ 'init',
8
+ '--name=my-app',
9
+ '--skip-npm',
10
+ '--skip-bower',
11
+ ]);
12
+ }
13
+
14
+ module.exports = initApp;
@@ -7,10 +7,10 @@ const MockUI = require('console-ui/mock');
7
7
  // eslint-disable-next-line node/no-unpublished-require
8
8
 
9
9
  class MockProject extends Project {
10
- constructor() {
11
- let root = process.cwd();
12
- let pkg = {};
13
- let ui = new MockUI();
10
+ constructor(options = {}) {
11
+ let root = options.root || process.cwd();
12
+ let pkg = options.pkg || {};
13
+ let ui = options.ui || new MockUI();
14
14
  let instr = new Instrumentation({
15
15
  ui,
16
16
  initInstrumentation: {
@@ -18,7 +18,7 @@ class MockProject extends Project {
18
18
  node: null,
19
19
  },
20
20
  });
21
- let cli = {
21
+ let cli = options.cli || {
22
22
  instrumentation: instr,
23
23
  };
24
24