Repository: ember-cli/ember-cli
Pull request #9530 (2021-05-10 16:18:30)

Drop Node 10 support


Patch:
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 855499fde..4779dc117 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -54,7 +54,7 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        node-version: [10.x, 12.x, 14.x]
+        node-version: [12.x, 14.x]
         os: [ubuntu, windows]
 
     steps:
diff --git a/blueprints/addon/files/.travis.yml b/blueprints/addon/files/.travis.yml
index b8a36f02d..a13eaecc5 100644
--- a/blueprints/addon/files/.travis.yml
+++ b/blueprints/addon/files/.travis.yml
@@ -3,7 +3,7 @@ language: node_js
 node_js:
   # we recommend testing addons with the same minimum supported node version as Ember CLI
   # so that your addon works for all apps
-  - "10"
+  - "12"
 
 dist: xenial
 
diff --git a/blueprints/addon/files/README.md b/blueprints/addon/files/README.md
index e6972a912..2ec7757b7 100644
--- a/blueprints/addon/files/README.md
+++ b/blueprints/addon/files/README.md
@@ -9,7 +9,7 @@ Compatibility
 
 * Ember.js v3.20 or above
 * Ember CLI v3.20 or above
-* Node.js v10 or above
+* Node.js v12 or above
 
 
 Installation
diff --git a/blueprints/app/files/.travis.yml b/blueprints/app/files/.travis.yml
index 6547c8648..bf9a217b2 100644
--- a/blueprints/app/files/.travis.yml
+++ b/blueprints/app/files/.travis.yml
@@ -1,7 +1,7 @@
 ---
 language: node_js
 node_js:
-  - "10"
+  - "12"
 
 dist: xenial
 
diff --git a/docs/node-support.md b/docs/node-support.md
index 4360be065..98216207b 100644
--- a/docs/node-support.md
+++ b/docs/node-support.md
@@ -12,7 +12,7 @@
 | 7.x              | 2.10.0 - 2.16.x              |
 | 8.x              | 2.13.3 - 3.16.x              |
 | 9.x              | 2.16.2 - 3.2.x               |
-| 10.x             | 3.1.3 - Current              |
+| 10.x             | 3.1.3 - 3.28.0               |
 | 11.x             | 3.9.0 - 3.13.0               |
 | 12.x             | 3.10.0 - Current             |
 | 13.x             | 3.15.0 - 3.20.0              |
@@ -30,8 +30,6 @@ Node.js](https://github.com/nodejs/LTS#lts_schedule).
 
 ## Current support:
 
-* v10: Released as stable version then converted to LTS.
-  * Supported by ember-cli/ember-cli#master until: 2021-04-30.
 * v12: Released as stable version then converted to LTS.
   * Supported by ember-cli/ember-cli#master until: 2022-04-30.
 * v14: Released as stable version then converted to LTS.
diff --git a/lib/models/package-info-cache/package-info.js b/lib/models/package-info-cache/package-info.js
index 6e30cf80b..9e4358f7b 100644
--- a/lib/models/package-info-cache/package-info.js
+++ b/lib/models/package-info-cache/package-info.js
@@ -390,18 +390,17 @@ class PackageInfo {
     // TODO: Future work - allow a time budget for loading each addon and warn
     // or error for those that take too long.
     let module = require(this.addonMainPath);
-    let mainDir = path.dirname(this.addonMainPath);
 
     let ctor;
 
     if (typeof module === 'function') {
       ctor = module;
-      ctor.prototype.root = ctor.prototype.root || mainDir;
+      ctor.prototype.root = this.realPath;
       ctor.prototype.pkg = ctor.prototype.pkg || this.pkg;
     } else {
       const Addon = require('../addon'); // done here because of circular dependency
 
-      ctor = Addon.extend(Object.assign({ root: mainDir, pkg: this.pkg }, module));
+      ctor = Addon.extend(Object.assign({ root: this.realPath, pkg: this.pkg }, module));
     }
 
     ctor._meta_ = {
diff --git a/package.json b/package.json
index 56b00a62e..63b89225d 100644
--- a/package.json
+++ b/package.json
@@ -165,7 +165,7 @@
     "yuidocjs": "0.10.2"
   },
   "engines": {
-    "node": "10.* || >= 12"
+    "node": ">= 12"
   },
   "publishConfig": {
     "registry": "https://registry.npmjs.org"


Test patch:
diff --git a/tests/fixtures/addon/defaults/.travis.yml b/tests/fixtures/addon/defaults/.travis.yml
index 22e0715e9..7c3c34809 100644
--- a/tests/fixtures/addon/defaults/.travis.yml
+++ b/tests/fixtures/addon/defaults/.travis.yml
@@ -3,7 +3,7 @@ language: node_js
 node_js:
   # we recommend testing addons with the same minimum supported node version as Ember CLI
   # so that your addon works for all apps
-  - "10"
+  - "12"
 
 dist: xenial
 
diff --git a/tests/fixtures/addon/defaults/README.md b/tests/fixtures/addon/defaults/README.md
index f863b52d5..c4dcf008b 100644
--- a/tests/fixtures/addon/defaults/README.md
+++ b/tests/fixtures/addon/defaults/README.md
@@ -9,7 +9,7 @@ Compatibility
 
 * Ember.js v3.20 or above
 * Ember CLI v3.20 or above
-* Node.js v10 or above
+* Node.js v12 or above
 
 
 Installation
diff --git a/tests/fixtures/addon/simple/lib/ember-super-button/lib/ember-with-addon-main/lib/main.js b/tests/fixtures/addon/simple/lib/ember-super-button/lib/ember-with-addon-main/lib/main.js
new file mode 100644
index 000000000..3ad817af8
--- /dev/null
+++ b/tests/fixtures/addon/simple/lib/ember-super-button/lib/ember-with-addon-main/lib/main.js
@@ -0,0 +1,5 @@
+'use strict';
+
+module.exports = {
+  name: require('../package').name,
+};
diff --git a/tests/fixtures/addon/simple/lib/ember-super-button/lib/ember-with-addon-main/package.json b/tests/fixtures/addon/simple/lib/ember-super-button/lib/ember-with-addon-main/package.json
new file mode 100644
index 000000000..6cf2ccf37
--- /dev/null
+++ b/tests/fixtures/addon/simple/lib/ember-super-button/lib/ember-with-addon-main/package.json
@@ -0,0 +1,9 @@
+{
+  "name": "ember-with-addon-main",
+  "keywords": [
+    "ember-addon"
+  ],
+  "ember-addon": {
+    "main": "lib/main.js"
+  }
+}
diff --git a/tests/fixtures/addon/simple/lib/ember-super-button/package.json b/tests/fixtures/addon/simple/lib/ember-super-button/package.json
index d493c4084..a2c50d4bb 100644
--- a/tests/fixtures/addon/simple/lib/ember-super-button/package.json
+++ b/tests/fixtures/addon/simple/lib/ember-super-button/package.json
@@ -4,9 +4,12 @@
     "ember-addon"
   ],
   "ember-addon": {
-    "paths": ["./lib/ember-ng"]
+    "paths": [
+      "./lib/ember-ng",
+      "./lib/ember-with-addon-main"
+    ]
   },
   "dependencies": {
     "ember-yagni": "0"
   }
-}
+}
\ No newline at end of file
diff --git a/tests/fixtures/addon/simple/lib/extend-from-addon-directly/index.js b/tests/fixtures/addon/simple/lib/extend-from-addon-directly/index.js
new file mode 100644
index 000000000..03ebd576c
--- /dev/null
+++ b/tests/fixtures/addon/simple/lib/extend-from-addon-directly/index.js
@@ -0,0 +1,7 @@
+'use strict';
+
+const Addon = require('../../../../../../lib/models/addon');
+
+module.exports = Addon.extend({
+  name: require('./package').name,
+});
diff --git a/tests/fixtures/addon/simple/lib/extend-from-addon-directly/package.json b/tests/fixtures/addon/simple/lib/extend-from-addon-directly/package.json
new file mode 100644
index 000000000..c7c4edefd
--- /dev/null
+++ b/tests/fixtures/addon/simple/lib/extend-from-addon-directly/package.json
@@ -0,0 +1,7 @@
+{
+  "name": "extend-from-addon-directly",
+  "keywords": [
+    "ember-addon"
+  ],
+  "dependencies": {}
+}
\ No newline at end of file
diff --git a/tests/fixtures/addon/simple/lib/odd-inheritance-addon/index.js b/tests/fixtures/addon/simple/lib/odd-inheritance-addon/index.js
new file mode 100644
index 000000000..a2803136e
--- /dev/null
+++ b/tests/fixtures/addon/simple/lib/odd-inheritance-addon/index.js
@@ -0,0 +1,7 @@
+'use strict';
+
+const AddonToExtendFrom = require('../extend-from-addon-directly');
+
+module.exports = AddonToExtendFrom.extend({
+  name: require('./package').name,
+});
diff --git a/tests/fixtures/addon/simple/lib/odd-inheritance-addon/package.json b/tests/fixtures/addon/simple/lib/odd-inheritance-addon/package.json
new file mode 100644
index 000000000..a96531aca
--- /dev/null
+++ b/tests/fixtures/addon/simple/lib/odd-inheritance-addon/package.json
@@ -0,0 +1,7 @@
+{
+  "name": "odd-inheritance-addon",
+  "keywords": [
+    "ember-addon"
+  ],
+  "dependencies": {}
+}
\ No newline at end of file
diff --git a/tests/fixtures/addon/simple/package.json b/tests/fixtures/addon/simple/package.json
index e1db417e4..54a32d955 100644
--- a/tests/fixtures/addon/simple/package.json
+++ b/tests/fixtures/addon/simple/package.json
@@ -5,7 +5,12 @@
     "something-else": "latest"
   },
   "ember-addon": {
-    "paths": ["./lib/ember-super-button"]
+    "paths": [
+      "./lib/ember-super-button",
+      "./lib/ember-super-button/lib/ember-with-addon-main",
+      "./lib/extend-from-addon-directly",
+      "./lib/odd-inheritance-addon"
+    ]
   },
   "devDependencies": {
     "ember-resolver": "^7.0.0",
@@ -20,4 +25,4 @@
     "ember-addon-with-dependencies": "latest",
     "loader.js": "latest"
   }
-}
+}
\ No newline at end of file
diff --git a/tests/fixtures/addon/yarn/.travis.yml b/tests/fixtures/addon/yarn/.travis.yml
index 3fb60c542..14cf05af6 100644
--- a/tests/fixtures/addon/yarn/.travis.yml
+++ b/tests/fixtures/addon/yarn/.travis.yml
@@ -3,7 +3,7 @@ language: node_js
 node_js:
   # we recommend testing addons with the same minimum supported node version as Ember CLI
   # so that your addon works for all apps
-  - "10"
+  - "12"
 
 dist: xenial
 
diff --git a/tests/fixtures/addon/yarn/README.md b/tests/fixtures/addon/yarn/README.md
index f863b52d5..c4dcf008b 100644
--- a/tests/fixtures/addon/yarn/README.md
+++ b/tests/fixtures/addon/yarn/README.md
@@ -9,7 +9,7 @@ Compatibility
 
 * Ember.js v3.20 or above
 * Ember CLI v3.20 or above
-* Node.js v10 or above
+* Node.js v12 or above
 
 
 Installation
diff --git a/tests/fixtures/app/defaults/.travis.yml b/tests/fixtures/app/defaults/.travis.yml
index 5b5ce9da2..bf02ddcad 100644
--- a/tests/fixtures/app/defaults/.travis.yml
+++ b/tests/fixtures/app/defaults/.travis.yml
@@ -1,7 +1,7 @@
 ---
 language: node_js
 node_js:
-  - "10"
+  - "12"
 
 dist: xenial
 
diff --git a/tests/fixtures/app/npm/.travis.yml b/tests/fixtures/app/npm/.travis.yml
index 5b5ce9da2..bf02ddcad 100644
--- a/tests/fixtures/app/npm/.travis.yml
+++ b/tests/fixtures/app/npm/.travis.yml
@@ -1,7 +1,7 @@
 ---
 language: node_js
 node_js:
-  - "10"
+  - "12"
 
 dist: xenial
 
diff --git a/tests/fixtures/app/with-blueprint-override-lint-fail/.travis.yml b/tests/fixtures/app/with-blueprint-override-lint-fail/.travis.yml
index 5b5ce9da2..bf02ddcad 100644
--- a/tests/fixtures/app/with-blueprint-override-lint-fail/.travis.yml
+++ b/tests/fixtures/app/with-blueprint-override-lint-fail/.travis.yml
@@ -1,7 +1,7 @@
 ---
 language: node_js
 node_js:
-  - "10"
+  - "12"
 
 dist: xenial
 
diff --git a/tests/fixtures/app/yarn/.travis.yml b/tests/fixtures/app/yarn/.travis.yml
index aa771282f..d908403ee 100644
--- a/tests/fixtures/app/yarn/.travis.yml
+++ b/tests/fixtures/app/yarn/.travis.yml
@@ -1,7 +1,7 @@
 ---
 language: node_js
 node_js:
-  - "10"
+  - "12"
 
 dist: xenial
 
diff --git a/tests/unit/models/package-info-cache/package-info-cache-test.js b/tests/unit/models/package-info-cache/package-info-cache-test.js
index 3687a48fb..0541d4cc0 100644
--- a/tests/unit/models/package-info-cache/package-info-cache-test.js
+++ b/tests/unit/models/package-info-cache/package-info-cache-test.js
@@ -64,13 +64,13 @@ describe('models/package-info-cache/package-info-cache-test.js', function () {
   });
 
   describe('packageInfo contents tests on valid project', function () {
-    let projectPath, packageJsonPath, packageContents, projectPackageInfo;
+    let project, projectPath, packageJsonPath, packageContents, projectPackageInfo;
 
     beforeEach(function () {
       projectPath = path.resolve(addonFixturePath, 'simple');
       packageJsonPath = path.join(projectPath, 'package.json');
       packageContents = require(packageJsonPath);
-      let project = new Project(projectPath, packageContents, ui, cli);
+      project = new Project(projectPath, packageContents, ui, cli);
       let pic = project.packageInfoCache;
 
       projectPackageInfo = pic.getEntry(projectPath);
@@ -151,12 +151,29 @@ describe('models/package-info-cache/package-info-cache-test.js', function () {
       expect(packageAndErrorNames).to.deep.equal(devDependencyNames);
     });
 
-    it('shows projectPackageInfo has 1 in-repo addon named "ember-super-button"', function () {
+    it('shows projectPackageInfo has 4 in-repo addons', function () {
       let inRepoAddons = projectPackageInfo.inRepoAddons;
+
       expect(inRepoAddons).to.exist;
-      expect(inRepoAddons.length).to.equal(1);
+      expect(inRepoAddons.length).to.equal(4);
+
       expect(inRepoAddons[0].realPath.indexOf(`simple${path.sep}lib${path.sep}ember-super-button`)).to.be.above(0);
       expect(inRepoAddons[0].pkg.name).to.equal('ember-super-button');
+
+      expect(
+        inRepoAddons[1].realPath.indexOf(
+          `simple${path.sep}lib${path.sep}ember-super-button${path.sep}lib${path.sep}ember-with-addon-main`
+        )
+      ).to.be.above(0);
+      expect(inRepoAddons[1].pkg.name).to.equal('ember-with-addon-main');
+
+      expect(inRepoAddons[2].realPath.indexOf(`simple${path.sep}lib${path.sep}extend-from-addon-directly`)).to.be.above(
+        0
+      );
+      expect(inRepoAddons[2].pkg.name).to.equal('extend-from-addon-directly');
+
+      expect(inRepoAddons[3].realPath.indexOf(`simple${path.sep}lib${path.sep}odd-inheritance-addon`)).to.be.above(0);
+      expect(inRepoAddons[3].pkg.name).to.equal('odd-inheritance-addon');
     });
 
     it('shows projectPackageInfo has 7 internal addon packages', function () {
@@ -172,6 +189,88 @@ describe('models/package-info-cache/package-info-cache-test.js', function () {
       expect(nodeModules.entries).to.exist;
       expect(Object.keys(nodeModules.entries).length).to.equal(9);
     });
+
+    it('returns stable package infos for a package info representing the same addon', function () {
+      project.initializeAddons();
+
+      const findAddonsByName = (projectOrAddon, addonToFind, _foundAddons = []) => {
+        if (!projectOrAddon) {
+          return _foundAddons;
+        }
+
+        projectOrAddon.addons.forEach((addon) => {
+          if (addon.name === addonToFind) {
+            _foundAddons.push(addon);
+          }
+
+          findAddonsByName(addon, addonToFind, _foundAddons);
+        });
+
+        return _foundAddons;
+      };
+
+      const findAllInRepoPackageInfosByPredicate = (packageInfo, predicate, _foundPackageInfos = []) => {
+        if (predicate(packageInfo)) {
+          _foundPackageInfos.push(packageInfo);
+        }
+
+        (packageInfo.inRepoAddons || []).forEach((addonPackageInfo) =>
+          findAllInRepoPackageInfosByPredicate(addonPackageInfo, predicate, _foundPackageInfos)
+        );
+
+        return _foundPackageInfos;
+      };
+
+      let allAddonsWithAddonMain = findAddonsByName(project, 'ember-with-addon-main');
+
+      let projectAddonWithMainPackageInfo = findAllInRepoPackageInfosByPredicate(
+        project._packageInfo,
+        (packageInfo) =>
+          typeof packageInfo.addonMainPath === 'string' &&
+          packageInfo.addonMainPath.endsWith(path.join('ember-with-addon-main', 'lib', 'main.js'))
+      );
+
+      let allPackageInfosForAddonWithMain = [
+        ...allAddonsWithAddonMain.map((addon) => addon._packageInfo),
+        ...projectAddonWithMainPackageInfo,
+      ];
+
+      let areAllPackageInfosEqual = allPackageInfosForAddonWithMain.every(
+        (packageInfo) => packageInfo === allPackageInfosForAddonWithMain[0]
+      );
+
+      expect(allAddonsWithAddonMain.length).to.equal(2);
+      expect(allPackageInfosForAddonWithMain.length).to.equal(4);
+      expect(areAllPackageInfosEqual).to.equal(true);
+    });
+
+    it('returns has the correct `root` for addons that export a function for its constructor', function () {
+      project.initializeAddons();
+
+      let inRepoAddons = projectPackageInfo.inRepoAddons;
+
+      let ExtendFromAddonDirectlyConstructor = inRepoAddons[2].getAddonConstructor();
+      let OddInheritanceAddonConstructor = inRepoAddons[3].getAddonConstructor();
+
+      expect(ExtendFromAddonDirectlyConstructor.prototype.root).to.equal(
+        path.resolve(__dirname, '../../../fixtures/addon/simple/lib/extend-from-addon-directly')
+      );
+
+      expect(OddInheritanceAddonConstructor.prototype.root).to.equal(
+        path.resolve(__dirname, '../../../fixtures/addon/simple/lib/odd-inheritance-addon')
+      );
+
+      let extendFromAddonInstance = new ExtendFromAddonDirectlyConstructor(project, project);
+      let oddInheritanceAddonInstance = new OddInheritanceAddonConstructor(project, project);
+
+      expect(extendFromAddonInstance.root).to.equal(
+        path.resolve(__dirname, '../../../fixtures/addon/simple/lib/extend-from-addon-directly')
+      );
+
+      expect(oddInheritanceAddonInstance.root).to.equal(
+        path.resolve(__dirname, '../../../fixtures/addon/simple/lib/odd-inheritance-addon')
+      );
+    });
   });
 
   describe('packageInfo', function () {
diff --git a/tests/unit/models/project-test.js b/tests/unit/models/project-test.js
index c24f0fbe4..77d262214 100644
--- a/tests/unit/models/project-test.js
+++ b/tests/unit/models/project-test.js
@@ -347,6 +347,9 @@ describe('models/project.js', function () {
         'ember-non-root-addon',
         'ember-random-addon',
         'ember-super-button',
+        'ember-with-addon-main',
+        'extend-from-addon-directly',
+        'odd-inheritance-addon',
       ];
       expect(Object.keys(project.addonPackages)).to.deep.equal(expected);
     });
diff --git a/tests/unit/utilities/platform-checker-test.js b/tests/unit/utilities/platform-checker-test.js
index ca2212756..e29ce4b00 100644
--- a/tests/unit/utilities/platform-checker-test.js
+++ b/tests/unit/utilities/platform-checker-test.js
@@ -15,7 +15,7 @@ describe('platform-checker', function () {
     }
 
     check('v8.0.0', { isTested: false, isDeprecated: true, isValid: false });
-    check('v10.0.0', { isTested: true, isDeprecated: false, isValid: true });
+    check('v10.0.0', { isTested: false, isDeprecated: true, isValid: false });
     check('v12.0.0', { isTested: true, isDeprecated: false, isValid: true });
     check('v13.0.0', { isTested: false, isDeprecated: false, isValid: true });
     check('v14.0.0', { isTested: true, isDeprecated: false, isValid: true });