Skip to content

Commit 0a742d7

Browse files
committed
feat(cli): replace hard-coded loopback module version in templates
Use package.json version or config.loopbackVersion to derive the range for loopback module dependencies Use lib/dependencies.json to track dependencies used by our CLI code-gen templates Add bin/_update-template-deps.js to refresh dependencies.json
1 parent e623b0b commit 0a742d7

File tree

8 files changed

+167
-32
lines changed

8 files changed

+167
-32
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#!/usr/bin/env node
2+
// Copyright IBM Corp. 2017,2018. All Rights Reserved.
3+
// Node module: @loopback/cli
4+
// This file is licensed under the MIT License.
5+
// License text available at https://opensource.org/licenses/MIT
6+
7+
'use strict';
8+
9+
/**
10+
* This is an internal utility to update `lib/dependencies.json`, which declares
11+
* a set of dependencies used by our CLI templates for projects.
12+
*
13+
* Usage:
14+
* ```
15+
* node bin/_update-template-deps.js >lib/dependencies.json
16+
* ```
17+
*/
18+
19+
// Load dependencies from `@loopback/build`
20+
const buildDeps = require('@loopback/build/package.json').dependencies;
21+
22+
// LoopBack modules
23+
const lbModules = {
24+
// Comments
25+
'//1': 'This file contains dependency/version used by project templates',
26+
'//2':
27+
'It can be updated by running `node bin/_update-template-deps.js >lib/dependencies.json`',
28+
// LoopBack packages
29+
'@loopback/authentication': '',
30+
'@loopback/boot': '',
31+
'@loopback/context': '',
32+
'@loopback/core': '',
33+
'@loopback/metadata': '',
34+
'@loopback/openapi-spec-builder': '',
35+
'@loopback/openapi-spec': '',
36+
'@loopback/openapi-v2': '',
37+
'@loopback/openapi-v3-types': '',
38+
'@loopback/openapi-v3': '',
39+
'@loopback/repository-json-schema': '',
40+
'@loopback/repository': '',
41+
'@loopback/rest': '',
42+
'@loopback/testlab': '',
43+
};
44+
45+
// Load dependencies from `../lib/dependencies.json`
46+
const currentDeps = require('../lib/dependencies.json');
47+
48+
// Add entries from build deps
49+
const deps = Object.assign({}, lbModules, currentDeps, buildDeps);
50+
51+
// Convert to JSON
52+
const json = JSON.stringify(deps, null, 2);
53+
54+
console.log(json);

packages/cli/generators/project/templates/package.json.ejs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -57,25 +57,25 @@
5757
"dist"
5858
],
5959
"dependencies": {
60-
"@loopback/context": "^0.1.0",
61-
"@loopback/boot": "^0.1.0",
60+
"@loopback/context": "<%= project.dependencies['@loopback/context'] -%>",
61+
"@loopback/boot": "<%= project.dependencies['@loopback/boot'] -%>",
6262
<% if (project.projectType === 'application') { -%>
63-
"@loopback/core": "^0.1.0",
64-
"@loopback/rest": "^0.1.0",
65-
"@loopback/openapi-v2": "^0.1.0"
63+
"@loopback/core": "<%= project.dependencies['@loopback/core'] -%>",
64+
"@loopback/rest": "<%= project.dependencies['@loopback/rest'] -%>",
65+
"@loopback/openapi-v2": "<%= project.dependencies['@loopback/openapi-v2'] -%>"
6666
<% } else { -%>
67-
"@loopback/core": "^0.1.0"
67+
"@loopback/core": "<%= project.dependencies['@loopback/core'] -%>"
6868
<% } -%>
6969
},
7070
"devDependencies": {
71-
"@loopback/build": "^0.1.0",
71+
"@loopback/build": "<%= project.dependencies['@loopback/build'] -%>",
7272
<% if (project.mocha) { -%>
73-
"@loopback/testlab": "^0.1.0",
74-
"@types/mocha": "^2.2.43",
75-
"mocha": "^4.0.1",
76-
"source-map-support": "^0.5.2"
73+
"@loopback/testlab": "<%= project.dependencies['@loopback/testlab'] -%>",
74+
"@types/mocha": "<%= project.dependencies['@types/mocha'] -%>",
75+
"mocha": "<%= project.dependencies['mocha'] -%>",
76+
"source-map-support": "<%= project.dependencies['source-map-support'] -%>"
7777
<% } else { -%>
78-
"@loopback/testlab": "^0.1.0"
78+
"@loopback/testlab": "<%= project.dependencies['@loopback/testlab'] -%>"
7979
<% } -%>
8080
}
8181
}

packages/cli/generators/project/templates/package.plain.json.ejs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -57,29 +57,29 @@
5757
"dist"
5858
],
5959
"dependencies": {
60-
"@loopback/context": "^0.1.0",
61-
"@loopback/boot": "^0.1.0",
60+
"@loopback/context": "<%= project.dependencies['@loopback/context'] -%>",
61+
"@loopback/boot": "<%= project.dependencies['@loopback/boot'] -%>",
6262
<% if (project.projectType === 'application') { -%>
63-
"@loopback/core": "^0.1.0",
64-
"@loopback/rest": "^0.1.0",
65-
"@loopback/openapi-v2": "^0.1.0"
63+
"@loopback/core": "<%= project.dependencies['@loopback/core'] -%>",
64+
"@loopback/rest": "<%= project.dependencies['@loopback/rest'] -%>",
65+
"@loopback/openapi-v2": "<%= project.dependencies['@loopback/openapi-v2'] -%>"
6666
<% } else { -%>
67-
"@loopback/core": "^0.1.0"
67+
"@loopback/core": "<%= project.dependencies['@loopback/core'] -%>"
6868
<% } -%>
6969
},
7070
"devDependencies": {
7171
<% if (project.prettier) { -%>
72-
"prettier": "^1.7.3",
72+
"prettier": "<%= project.dependencies['prettier'] -%>",
7373
<% } -%>
7474
<% if (project.tslint) { -%>
75-
"tslint": "^5.7.0",
75+
"tslint": "<%= project.dependencies['tslint'] -%>",
7676
<% } -%>
77-
"@loopback/testlab": "^0.1.0",
77+
"@loopback/testlab": "<%= project.dependencies['@loopback/testlab'] -%>",
7878
<% if (project.mocha) { -%>
79-
"@types/mocha": "^2.2.43",
80-
"mocha": "^4.0.1",
81-
"source-map-support": "^0.5.2",
79+
"@types/mocha": "<%= project.dependencies['@types/mocha'] -%>",
80+
"mocha": "<%= project.dependencies['mocha'] -%>",
81+
"source-map-support": "<%= project.dependencies['source-map-support'] -%>",
8282
<% } -%>
83-
"typescript": "^2.5.3"
83+
"typescript": "<%= project.dependencies['typescript'] -%>"
8484
}
8585
}

packages/cli/lib/dependencies.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"//1": "This file contains dependency/version used by project templates",
3+
"//2": "It can be updated by running `node bin/_update-template-deps.js >lib/dependencies.json`",
4+
"@loopback/context": "",
5+
"@loopback/boot": "",
6+
"@loopback/core": "",
7+
"@loopback/rest": "",
8+
"@loopback/openapi-v2": "",
9+
"@loopback/build": "",
10+
"@loopback/testlab": "",
11+
"@types/mocha": "^2.2.48",
12+
"mocha": "^5.0.1",
13+
"source-map-support": "^0.5.3",
14+
"prettier": "^1.11.1",
15+
"tslint": "^5.9.1",
16+
"typescript": "^2.7.2"
17+
}

packages/cli/lib/project-generator.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,10 @@ module.exports = class ProjectGenerator extends BaseGenerator {
8383
}
8484

8585
setOptions() {
86-
this.projectInfo = {projectType: this.projectType};
86+
this.projectInfo = {
87+
projectType: this.projectType,
88+
dependencies: utils.getDependencies(),
89+
};
8790
this.projectOptions = ['name', 'description', 'outdir'].concat(
8891
this.buildOptions
8992
);

packages/cli/lib/utils.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const debug = require('../lib/debug')('utils');
99
const fs = require('fs');
1010
const path = require('path');
1111
const util = require('util');
12+
var semver = require('semver');
1213
const regenerate = require('regenerate');
1314
const _ = require('lodash');
1415
const pascalCase = require('change-case').pascalCase;
@@ -183,3 +184,27 @@ exports.getArtifactList = function(dir, artifactType, addSuffix, reader) {
183184
});
184185
});
185186
};
187+
188+
/**
189+
* Check package.json and dependencies.json to find out versions for generated
190+
* dependencies
191+
*/
192+
exports.getDependencies = function() {
193+
const pkg = require('../package.json');
194+
let version = pkg.version;
195+
// First look for config.loopbackVersion
196+
if (pkg.config && pkg.config.loopbackVersion) {
197+
version = pkg.config.loopbackVersion;
198+
}
199+
// Set it to be `^x.y.0`
200+
let loopbackVersion =
201+
'^' + semver.major(version) + '.' + semver.minor(version) + '.0';
202+
203+
const deps = {};
204+
const dependencies = require('./dependencies.json');
205+
for (const i in dependencies) {
206+
// Default to loopback version if the version for a given dependency is ""
207+
deps[i] = dependencies[i] || loopbackVersion;
208+
}
209+
return deps;
210+
};

packages/cli/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
"minimist": "^1.2.0",
4848
"regenerate": "^1.3.3",
4949
"request": "^2.83.0",
50+
"semver": "^5.5.0",
5051
"tar-fs": "^1.16.0",
5152
"unicode-10.0.0": "^0.7.4",
5253
"validate-npm-package-name": "^3.0.0",

packages/cli/test/project.js

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const yeoman = require('yeoman-environment');
1010
const testUtils = require('./test-utils');
1111
const sinon = require('sinon');
1212
const path = require('path');
13+
const deps = require('../lib/utils').getDependencies();
1314

1415
module.exports = function(projGenerator, props, projectType) {
1516
return function() {
@@ -114,6 +115,14 @@ module.exports = function(projGenerator, props, projectType) {
114115
};
115116
gen.setOptions();
116117
assert(gen.projectInfo.name === 'foobar');
118+
assert(
119+
gen.projectInfo.dependencies['@loopback/context'] ===
120+
deps['@loopback/context']
121+
);
122+
assert(
123+
gen.projectInfo.dependencies['@loopback/core'] ===
124+
deps['@loopback/core']
125+
);
117126
assert(gen.projectInfo.description !== null);
118127
assert(gen.projectInfo.prettier === true);
119128
});
@@ -208,19 +217,37 @@ module.exports = function(projGenerator, props, projectType) {
208217
]);
209218

210219
if (projectType === 'application') {
211-
assert.fileContent('package.json', '"@loopback/core"');
212-
assert.fileContent('package.json', '"@loopback/context"');
213-
assert.fileContent('package.json', '"@loopback/rest"');
214-
assert.fileContent('package.json', '"@loopback/openapi-v2"');
220+
assert.fileContent(
221+
'package.json',
222+
`"@loopback/core": "${deps['@loopback/core']}"`
223+
);
224+
assert.fileContent(
225+
'package.json',
226+
`"@loopback/context": "${deps['@loopback/context']}"`
227+
);
228+
assert.fileContent(
229+
'package.json',
230+
`"@loopback/rest": "${deps['@loopback/rest']}"`
231+
);
232+
assert.fileContent(
233+
'package.json',
234+
`"@loopback/openapi-v2": "${deps['@loopback/openapi-v2']}"`
235+
);
215236
assert.jsonFileContent('package.json', {
216237
scripts: {
217238
start: 'npm run build && node .',
218239
},
219240
});
220241
}
221242
if (projectType === 'extension') {
222-
assert.fileContent('package.json', '"@loopback/core"');
223-
assert.fileContent('package.json', '"@loopback/context"');
243+
assert.fileContent(
244+
'package.json',
245+
`"@loopback/core": "${deps['@loopback/core']}"`
246+
);
247+
assert.fileContent(
248+
'package.json',
249+
`"@loopback/context": "${deps['@loopback/context']}"`
250+
);
224251
assert.noFileContent('package.json', '"@loopback/rest"');
225252
assert.noFileContent('package.json', '"@loopback/openapi-v2"');
226253
assert.noJsonFileContent('package.json', {
@@ -250,6 +277,14 @@ module.exports = function(projGenerator, props, projectType) {
250277

251278
it('creates files', () => {
252279
assert.jsonFileContent('package.json', props);
280+
assert.fileContent(
281+
'package.json',
282+
`"@loopback/core": "${deps['@loopback/core']}"`
283+
);
284+
assert.fileContent(
285+
'package.json',
286+
`"@loopback/context": "${deps['@loopback/context']}"`
287+
);
253288
assert.noFileContent([
254289
['package.json', '@loopback/build'],
255290
['tslint.json', '@loopback/build'],

0 commit comments

Comments
 (0)