Skip to content

Commit e67e639

Browse files
authored
Refactor edition detection for emberjs/rfcs#558. (#4)
Refactor edition detection for emberjs/rfcs#558.
2 parents 7a78306 + 8257925 commit e67e639

File tree

4 files changed

+1283
-55
lines changed

4 files changed

+1283
-55
lines changed

index.js

+38-9
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1+
const fs = require('fs');
2+
const path = require('path');
3+
14
/**
2-
Sets the Edition that the application should be considered
3-
a part of.
5+
Sets the Edition that the application should be considered a part of. This
6+
method is deprecated, and will be phased out in the next major release.
47
58
@public
9+
@deprecated
610
@param {string} editionName the Edition name that your application is authored in
711
*/
812
function setEdition(editionName) {
@@ -12,9 +16,11 @@ function setEdition(editionName) {
1216
/**
1317
Resets the local state _as if_ no edition were specified. In general, this
1418
will be used by various addons' own local blueprint tests when testing
15-
generators.
19+
generators. This method is deprecated, and will be phased out in the next
20+
major release.
1621
1722
@public
23+
@deprecated
1824
*/
1925
function clearEdition() {
2026
delete process.env.EMBER_EDITION;
@@ -26,8 +32,32 @@ function clearEdition() {
2632
@private
2733
@returns {boolean}
2834
*/
29-
function _getEdition() {
30-
let edition = process.env.EMBER_EDITION;
35+
function _getEdition(projectRoot = process.cwd()) {
36+
let pkgPath = path.join(projectRoot, 'package.json');
37+
let hasPackageJson = false;
38+
39+
try {
40+
require.resolve(pkgPath);
41+
hasPackageJson = true;
42+
} catch (e) {
43+
// ignore errors, this signifies that there is no package.json in the
44+
// projectRoot so we _only_ check for the legacy environment variables
45+
}
46+
47+
let edition;
48+
49+
if (hasPackageJson) {
50+
let pkgContents = fs.readFileSync(pkgPath, { encoding: 'utf8' });
51+
let pkg = JSON.parse(pkgContents);
52+
53+
if ('ember' in pkg && 'edition' in pkg.ember) {
54+
edition = pkg.ember.edition;
55+
}
56+
}
57+
58+
if (edition === undefined) {
59+
edition = process.env.EMBER_EDITION;
60+
}
3161

3262
if (edition === undefined) {
3363
// check fallback "old" location
@@ -49,13 +79,12 @@ function _getEdition() {
4979
will return `true`, and if the edition in use by the application is _older_
5080
than the requested edition it will return `false`.
5181
52-
53-
5482
@param {string} requestedEditionName the Edition name that the application/addon is requesting
83+
@param {string} [projectRoot=process.cwd()] the base directory of the project
5584
*/
56-
function has(_requestedEditionName) {
85+
function has(_requestedEditionName, projectRoot) {
5786
let requestedEditionName = _requestedEditionName.toLowerCase();
58-
let edition = _getEdition();
87+
let edition = _getEdition(projectRoot);
5988

6089
if (requestedEditionName === 'classic') {
6190
// everything is classic :)

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"test": "qunit test.js"
1111
},
1212
"devDependencies": {
13+
"broccoli-test-helper": "^2.0.0",
1314
"qunit": "^2.9.2",
1415
"release-it": "^12.2.1",
1516
"release-it-lerna-changelog": "^1.0.3"

test.js

+85-31
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,126 @@
1+
const { createTempDir } = require('broccoli-test-helper');
12
const { setEdition, has, _getEdition } = require('./index');
23

34
const { test } = QUnit;
45

56
const OriginalConsole = Object.assign({}, console);
7+
const ROOT = process.cwd();
68

79
QUnit.module('@ember/edition-utils', function(hooks) {
8-
// only a test helper **because** we don't want folks to
9-
// use this in actual shared packages, they should instead
10-
// use `has`
11-
function getEdition() {
12-
return process.env.EMBER_EDITION;
13-
}
14-
15-
hooks.afterEach(function() {
10+
let project;
11+
12+
hooks.beforeEach(async function() {
13+
project = await createTempDir();
14+
process.chdir(project.path());
15+
});
16+
17+
hooks.afterEach(async function() {
1618
delete process.env.EMBER_EDITION;
1719
delete process.env.EMBER_VERSION;
1820
Object.assign(console, OriginalConsole);
21+
22+
process.chdir(ROOT);
23+
await project.dispose();
1924
});
2025

2126
QUnit.module('setEdition', function() {
2227
test('the edition name that is passed, sets the edition', function(assert) {
28+
assert.notOk(has('octane'), 'precond');
29+
2330
setEdition('octane');
2431

25-
assert.strictEqual(getEdition(), 'octane');
32+
assert.ok(has('octane'));
2633
});
2734

2835
test('normalizes the edition name that is passed in (lowercasing)', function(assert) {
36+
assert.notOk(has('octane'), 'precond');
37+
2938
setEdition('OCTANE');
3039

31-
assert.strictEqual(getEdition(), 'octane');
40+
assert.ok(has('octane'));
3241
});
3342
});
3443

3544
QUnit.module('has', function() {
36-
test('should be considered "classic" without an edition set', function(assert) {
37-
assert.ok(has('classic'));
38-
});
45+
function setupProject(edition) {
46+
let pkg = {
47+
name: 'dummy',
48+
version: '0.0.0',
49+
};
50+
51+
if (edition) {
52+
pkg.ember = { edition };
53+
}
3954

40-
test('should be considered "octane" when passing octane', function(assert) {
41-
setEdition('octane');
55+
project.write({
56+
'package.json': JSON.stringify(pkg, null, 2),
57+
});
58+
}
59+
60+
test('should be octane if project package.json is setup with edition: octane', function(assert) {
61+
setupProject('octane');
4262

4363
assert.ok(has('octane'));
4464
});
4565

46-
test('should match case insensitively', function(assert) {
47-
setEdition('octane');
66+
test('should be octane if project package.json in custom root is setup with edition: octane', function(assert) {
67+
process.chdir(ROOT);
4868

49-
assert.ok(has('OCTANE'));
50-
});
69+
setupProject('octane');
5170

71+
assert.ok(has('octane', project.path()));
72+
});
5273

53-
test('should not "have" octane, when edition is classic', function(assert) {
54-
setEdition('classic');
74+
test('has("classic") should be true when octane is set', function(assert) {
75+
setupProject('octane');
5576

56-
assert.notOk(has('octane'));
77+
assert.ok(has('classic'));
5778
});
5879

59-
test('should infer edition from process.env.EMBER_VERSION with a warning', function(assert) {
60-
assert.expect(2);
80+
QUnit.module('deprecated setEdition fallback', function() {
81+
test('project package.json "wins" over setEdition', function(assert) {
82+
setupProject('classic');
6183

62-
process.env.EMBER_VERSION = 'octane';
63-
console.log = (...args) => {
64-
assert.deepEqual(args, [
65-
'Please update to using @ember/edition-utils. Using process.env.EMBER_VERSION to declare your application / addon as "octane" ready is deprecated.',
66-
]);
67-
}
84+
setEdition('octane');
85+
86+
assert.ok(has('classic'));
87+
});
88+
89+
test('should be considered "classic" without an edition set', function(assert) {
90+
assert.ok(has('classic'));
91+
});
92+
93+
test('should be considered "octane" when passing octane', function(assert) {
94+
setEdition('octane');
95+
96+
assert.ok(has('octane'));
97+
});
98+
99+
test('should match case insensitively', function(assert) {
100+
setEdition('octane');
101+
102+
assert.ok(has('OCTANE'));
103+
});
104+
105+
106+
test('should not be octane, when edition is setEdition("classic") [deprecated]', function(assert) {
107+
setEdition('classic');
108+
109+
assert.notOk(has('octane'));
110+
});
111+
112+
test('should infer edition from process.env.EMBER_VERSION with a warning', function(assert) {
113+
assert.expect(2);
114+
115+
process.env.EMBER_VERSION = 'octane';
116+
console.log = (...args) => {
117+
assert.deepEqual(args, [
118+
'Please update to using @ember/edition-utils. Using process.env.EMBER_VERSION to declare your application / addon as "octane" ready is deprecated.',
119+
]);
120+
}
68121

69-
assert.ok(has('octane'), 'finds process.env.EMBER_VERSION');
122+
assert.ok(has('octane'), 'finds process.env.EMBER_VERSION');
123+
});
70124
});
71125
});
72126
});

0 commit comments

Comments
 (0)