diff --git a/packages/cli/lib/artifact-generator.js b/packages/cli/lib/artifact-generator.js index aa0ac36aa6d6..da16d6028e3e 100644 --- a/packages/cli/lib/artifact-generator.js +++ b/packages/cli/lib/artifact-generator.js @@ -8,6 +8,7 @@ const BaseGenerator = require('./base-generator'); const debug = require('./debug')('artifact-generator'); const utils = require('./utils'); const StatusConflicter = utils.StatusConflicter; +const semver = require('semver'); module.exports = class ArtifactGenerator extends BaseGenerator { // Note: arguments and options should be defined in the constructor. @@ -37,33 +38,24 @@ module.exports = class ArtifactGenerator extends BaseGenerator { /** * Checks if current directory is a LoopBack project by checking for - * keyword 'loopback' under 'keywords' attribute in package.json. - * 'keywords' is an array + * .yo-rc.json and the lbVersion is specified. */ checkLoopBackProject() { debug('Checking for loopback project'); if (this.shouldExit()) return false; - const pkg = this.fs.readJSON(this.destinationPath('package.json')); - const key = 'loopback'; - if (!pkg) { - const err = new Error( - 'No package.json found in ' + - this.destinationRoot() + - '. ' + - 'The command must be run in a LoopBack project.' - ); - this.exit(err); - return; - } - if (!pkg.keywords || !pkg.keywords.includes(key)) { - const err = new Error( - 'No `loopback` keyword found in ' + - this.destinationPath('package.json') + - '. ' + - 'The command must be run in a LoopBack project.' + let retErr; + + const version = this.config.get('lbVersion'); + if ( + semver.valid(version) === null || + semver.satisfies(version, '< 4.0.0') + ) { + retErr = new Error( + 'Invalid version. The command must be run in a LoopBack 4 project.' ); - this.exit(err); } + + if (retErr) this.exit(retErr); } promptArtifactName() { diff --git a/packages/cli/lib/project-generator.js b/packages/cli/lib/project-generator.js index 5f5c3ba4a57d..1da35c84c81f 100644 --- a/packages/cli/lib/project-generator.js +++ b/packages/cli/lib/project-generator.js @@ -6,6 +6,7 @@ 'use strict'; const BaseGenerator = require('./base-generator'); const utils = require('./utils'); +const pkg = require('../package.json'); module.exports = class ProjectGenerator extends BaseGenerator { // Note: arguments and options should be defined in the constructor. @@ -208,10 +209,23 @@ module.exports = class ProjectGenerator extends BaseGenerator { if (!this.projectInfo.mocha) { this.fs.delete(this.destinationPath('test/mocha.opts')); } + + this.writeConfig(); } install() { if (this.shouldExit()) return false; this.npmInstall(null, {}, {cwd: this.destinationRoot()}); } + + /** + * Write the default config for a generated project + */ + writeConfig() { + return this.config.defaults({ + cliVersion: pkg.version, + lbVersion: '4.0.0', + type: this.projectInfo.projectType, + }); + } }; diff --git a/packages/cli/package.json b/packages/cli/package.json index d2746902efa8..2cccfedc585e 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -42,6 +42,7 @@ "lodash": "^4.17.4", "minimist": "^1.2.0", "regenerate": "^1.3.3", + "semver": "^5.4.1", "unicode-10.0.0": "^0.7.4", "validate-npm-package-name": "^3.0.0", "yeoman-generator": "^2.0.1" diff --git a/packages/cli/test/artifact.js b/packages/cli/test/artifact.js index f2cb680bd1ee..a8a1dedad6a8 100644 --- a/packages/cli/test/artifact.js +++ b/packages/cli/test/artifact.js @@ -51,40 +51,35 @@ module.exports = function(artiGenerator) { describe('checkLoopBackProject', () => { testCheckLoopBack( - 'throws an error if no package.json is present', + 'throws an error if lbVersion is undefined', undefined, - /No package.json found/ + /Invalid version./ ); testCheckLoopBack( - 'throws an error if "keywords" key does not exist', - {foobar: 'test'}, - /No `loopback` keyword found/ - ); - testCheckLoopBack( - 'throws an error if "keywords" key does not map to an array with "loopback" as a member', - {keywords: ['foobar', 'test']}, - /No `loopback` keyword found/ + 'throws an error if version is below 4.0.0', + '3.9.9', + /Invalid version./ ); - it('passes if "keywords" maps to "loopback"', () => { + it('passes if "lbVersion" is "4.0.0" or greater', () => { let gen = testUtils.testSetUpGen(artiGenerator); - gen.fs.readJSON = sinon.stub(fs, 'readJSON'); - gen.fs.readJSON.returns({keywords: ['test', 'loopback']}); + gen.config.get = sinon.stub(gen.config, 'get'); + gen.config.get.withArgs('lbVersion').returns('4.0.0'); assert.doesNotThrow(() => { gen.checkLoopBackProject(); }, Error); - gen.fs.readJSON.restore(); + gen.config.get.restore(); }); - function testCheckLoopBack(testName, obj, expected) { + function testCheckLoopBack(testName, str, expected) { it(testName, () => { let gen = testUtils.testSetUpGen(artiGenerator); let logs = []; gen.log = function(...args) { logs = logs.concat(args); }; - gen.fs.readJSON = sinon.stub(fs, 'readJSON'); - gen.fs.readJSON.returns(obj); + gen.config.get = sinon.stub(gen.config, 'get'); + gen.config.get.withArgs('lbVersion').returns(str); gen.checkLoopBackProject(); assert(gen.exitGeneration instanceof Error); assert(gen.exitGeneration.message.match(expected)); @@ -92,7 +87,7 @@ module.exports = function(artiGenerator) { assert.deepEqual(logs, [ chalk.red('Generation is aborted:', gen.exitGeneration), ]); - gen.fs.readJSON.restore(); + gen.config.get.restore(); }); } }); diff --git a/packages/cli/test/controller.js b/packages/cli/test/controller.js index 2ec4dd764326..39c9e0bfa2d3 100644 --- a/packages/cli/test/controller.js +++ b/packages/cli/test/controller.js @@ -24,7 +24,7 @@ describe('controller-generator extending BaseGenerator', baseTests); describe('generator-loopback4:controller', tests); describe('lb4 controller', () => { - it('does not run without package.json', () => { + it('does not run without .yo-rc.json', () => { helpers .run(generator) .withPrompts(withInputProps) @@ -32,16 +32,18 @@ describe('lb4 controller', () => { assert.noFile(withInputName); }); }); - it('does not run without the loopback keyword', () => { + it('does not run without the correct lbVersion', () => { let tmpDir; helpers .run(generator) .inTmpDir(dir => { tmpDir = dir; fs.writeFileSync( - path.join(tmpDir, 'package.json'), + path.join(tmpDir, '.yo-rc.json'), JSON.stringify({ - keywords: ['foobar'], + '@loopback/cli': { + lbVersion: '4.0.0', + }, }) ); }) @@ -59,9 +61,11 @@ describe('lb4 controller', () => { .inTmpDir(dir => { tmpDir = dir; fs.writeFileSync( - path.join(tmpDir, 'package.json'), + path.join(tmpDir, '.yo-rc.json'), JSON.stringify({ - keywords: ['loopback'], + '@loopback/cli': { + lbVersion: '4.0.0', + }, }) ); }) @@ -84,9 +88,11 @@ describe('lb4 controller', () => { .inTmpDir(dir => { tmpDir = dir; fs.writeFileSync( - path.join(tmpDir, 'package.json'), + path.join(tmpDir, '.yo-rc.json'), JSON.stringify({ - keywords: ['loopback'], + '@loopback/cli': { + lbVersion: '4.0.0', + }, }) ); })