diff --git a/lib/plugins/plugin/install/install.js b/lib/plugins/plugin/install/install.js index c2df8ffa7..3b5982e92 100644 --- a/lib/plugins/plugin/install/install.js +++ b/lib/plugins/plugin/install/install.js @@ -7,8 +7,8 @@ const path = require('path'); const _ = require('lodash'); const userStats = require('../../../utils/userStats'); const yamlAstParser = require('../../../utils/yamlAstParser'); -const pluginUtils = require('../lib/utils'); const fileExists = require('../../../utils/fs/fileExists'); +const pluginUtils = require('../lib/utils'); class PluginInstall { constructor(serverless, options) { @@ -43,13 +43,7 @@ class PluginInstall { } install() { - let pluginInfo; - if (this.options.name.startsWith('@')) { - pluginInfo = _.split(this.options.name.slice(1), '@', 2); - pluginInfo[0] = `@${pluginInfo[0]}`; - } else { - pluginInfo = _.split(this.options.name, '@', 2); - } + const pluginInfo = pluginUtils.getPluginInfo(this.options.name); this.options.pluginName = pluginInfo[0]; this.options.pluginVersion = pluginInfo[1] || 'latest'; @@ -58,21 +52,20 @@ class PluginInstall { .then(this.getPlugins) .then(plugins => { const plugin = plugins.find(item => item.name === this.options.pluginName); - if (plugin) { - return BbPromise.bind(this) - .then(this.pluginInstall) - .then(this.addPluginToServerlessFile) - .then(this.installPeerDependencies) - .then(() => { - const message = [ - 'Successfully installed', - ` "${this.options.pluginName}@${this.options.pluginVersion}"`, - ].join(''); - this.serverless.cli.log(message); - }); + if (!plugin) { + this.serverless.cli.log('Plugin not found in serverless registry, continuing to install'); } - const message = `Plugin "${this.options.pluginName}" not found. Did you spell it correct?`; - throw new this.serverless.classes.Error(message); + return BbPromise.bind(this) + .then(this.pluginInstall) + .then(this.addPluginToServerlessFile) + .then(this.installPeerDependencies) + .then(() => { + const message = [ + 'Successfully installed', + ` "${this.options.pluginName}@${this.options.pluginVersion}"`, + ].join(''); + this.serverless.cli.log(message); + }); }); } diff --git a/lib/plugins/plugin/install/install.test.js b/lib/plugins/plugin/install/install.test.js index d9666cc83..8c96653e0 100644 --- a/lib/plugins/plugin/install/install.test.js +++ b/lib/plugins/plugin/install/install.test.js @@ -178,7 +178,7 @@ describe('PluginInstall', () => { }); }); - it('should not install the plugin if it can not be found in the registry', () => { + it('should install the plugin even if it can not be found in the registry', () => { // serverless.yml const serverlessYml = { service: 'plugin-service', @@ -186,15 +186,15 @@ describe('PluginInstall', () => { }; serverless.utils.writeFileSync(serverlessYmlFilePath, YAML.dump(serverlessYml)); - pluginInstall.options.name = 'serverless-not-available-plugin'; - return expect(pluginInstall.install()).to.be.rejected.then(() => { + pluginInstall.options.name = 'serverless-not-in-registry-plugin'; + return expect(pluginInstall.install()).to.be.fulfilled.then(() => { expect(validateStub.calledOnce).to.equal(true); expect(getPluginsStub.calledOnce).to.equal(true); - expect(pluginInstallStub.calledOnce).to.equal(false); - expect(consoleLogStub.called).to.equal(false); - expect(serverlessErrorStub.calledOnce).to.equal(true); - expect(addPluginToServerlessFileStub.calledOnce).to.equal(false); - expect(installPeerDependenciesStub.calledOnce).to.equal(false); + expect(pluginInstallStub.calledOnce).to.equal(true); + expect(consoleLogStub.called).to.equal(true); + expect(serverlessErrorStub.calledOnce).to.equal(false); + expect(addPluginToServerlessFileStub.calledOnce).to.equal(true); + expect(installPeerDependenciesStub.calledOnce).to.equal(true); }); }); diff --git a/lib/plugins/plugin/lib/utils.js b/lib/plugins/plugin/lib/utils.js index f4eeffe3d..4558925c1 100644 --- a/lib/plugins/plugin/lib/utils.js +++ b/lib/plugins/plugin/lib/utils.js @@ -69,6 +69,17 @@ module.exports = { .then(json => json); }, + getPluginInfo(name) { + let pluginInfo; + if (name.startsWith('@')) { + pluginInfo = _.split(name.slice(1), '@', 2); + pluginInfo[0] = `@${pluginInfo[0]}`; + } else { + pluginInfo = _.split(name, '@', 2); + } + return pluginInfo; + }, + display(plugins) { let message = ''; if (plugins && plugins.length) { diff --git a/lib/plugins/plugin/lib/utils.test.js b/lib/plugins/plugin/lib/utils.test.js index 1a797062f..055ef876b 100644 --- a/lib/plugins/plugin/lib/utils.test.js +++ b/lib/plugins/plugin/lib/utils.test.js @@ -149,6 +149,23 @@ describe('PluginUtils', () => { }); }); + describe('#getPluginInfo()', () => { + it('should return the plugins name', () => { + expect(pluginUtils.getPluginInfo('some-plugin')).to.deep.equal(['some-plugin']); + }); + + it('should return the plugins name and version', () => { + expect(pluginUtils.getPluginInfo('some-plugin@0.1.0')).to.deep.equal([ + 'some-plugin', + '0.1.0', + ]); + }); + + it('should support scoped names', () => { + expect(pluginUtils.getPluginInfo('@acme/some-plugin')).to.deep.equal(['@acme/some-plugin']); + }); + }); + describe('#display()', () => { it('should display the plugins if present', () => { let expectedMessage = ''; diff --git a/lib/plugins/plugin/uninstall/uninstall.js b/lib/plugins/plugin/uninstall/uninstall.js index 5d539c66a..bc61114b1 100644 --- a/lib/plugins/plugin/uninstall/uninstall.js +++ b/lib/plugins/plugin/uninstall/uninstall.js @@ -5,9 +5,9 @@ const childProcess = BbPromise.promisifyAll(require('child_process')); const fse = require('../../../utils/fs/fse'); const path = require('path'); const _ = require('lodash'); -const pluginUtils = require('../lib/utils'); const userStats = require('../../../utils/userStats'); const yamlAstParser = require('../../../utils/yamlAstParser'); +const pluginUtils = require('../lib/utils'); class PluginUninstall { constructor(serverless, options) { @@ -43,7 +43,7 @@ class PluginUninstall { } uninstall() { - const pluginInfo = _.split(this.options.name, '@', 2); + const pluginInfo = pluginUtils.getPluginInfo(this.options.name); this.options.pluginName = pluginInfo[0]; return BbPromise.bind(this) @@ -51,18 +51,19 @@ class PluginUninstall { .then(this.getPlugins) .then(plugins => { const plugin = plugins.find(item => item.name === this.options.pluginName); - if (plugin) { - return BbPromise.bind(this) - .then(this.uninstallPeerDependencies) - .then(this.pluginUninstall) - .then(this.removePluginFromServerlessFile) - .then(() => { - this.serverless.cli.log(`Successfully uninstalled "${this.options.pluginName}"`); - return BbPromise.resolve(); - }); + if (!plugin) { + this.serverless.cli.log( + 'Plugin not found in serverless registry, continuing to uninstall' + ); } - const message = `Plugin "${this.options.pluginName}" not found. Did you spell it correct?`; - throw new this.serverless.classes.Error(message); + return BbPromise.bind(this) + .then(this.uninstallPeerDependencies) + .then(this.pluginUninstall) + .then(this.removePluginFromServerlessFile) + .then(() => { + this.serverless.cli.log(`Successfully uninstalled "${this.options.pluginName}"`); + return BbPromise.resolve(); + }); }); } diff --git a/lib/plugins/plugin/uninstall/uninstall.test.js b/lib/plugins/plugin/uninstall/uninstall.test.js index 2c84c7c9b..a88cb9c87 100644 --- a/lib/plugins/plugin/uninstall/uninstall.test.js +++ b/lib/plugins/plugin/uninstall/uninstall.test.js @@ -155,7 +155,7 @@ describe('PluginUninstall', () => { }); }); - it('should not uninstall the plugin if it can not be found in the registry', () => { + it('should uninstall the plugin even if it can not be found in the registry', () => { // serverless.yml const serverlessYml = { service: 'plugin-service', @@ -163,15 +163,16 @@ describe('PluginUninstall', () => { }; serverless.utils.writeFileSync(serverlessYmlFilePath, YAML.dump(serverlessYml)); - pluginUninstall.options.name = 'serverless-not-available-plugin'; - return expect(pluginUninstall.uninstall()).to.be.rejected.then(() => { + pluginUninstall.options.name = 'serverless-not-in-registry-plugin'; + + return expect(pluginUninstall.uninstall()).to.be.fulfilled.then(() => { expect(validateStub.calledOnce).to.equal(true); expect(getPluginsStub.calledOnce).to.equal(true); - expect(pluginUninstallStub.calledOnce).to.equal(false); - expect(consoleLogStub.called).to.equal(false); - expect(serverlessErrorStub.calledOnce).to.equal(true); - expect(removePluginFromServerlessFileStub.calledOnce).to.equal(false); - expect(uninstallPeerDependenciesStub.calledOnce).to.equal(false); + expect(pluginUninstallStub.calledOnce).to.equal(true); + expect(consoleLogStub.called).to.equal(true); + expect(serverlessErrorStub.calledOnce).to.equal(false); + expect(removePluginFromServerlessFileStub.calledOnce).to.equal(true); + expect(uninstallPeerDependenciesStub.calledOnce).to.equal(true); }); });