diff --git a/lib/classes/PluginManager.js b/lib/classes/PluginManager.js index ba731a133..2ae263881 100644 --- a/lib/classes/PluginManager.js +++ b/lib/classes/PluginManager.js @@ -103,9 +103,13 @@ class PluginManager { } loadHooks(pluginInstance) { - _.forEach(pluginInstance.hooks, (hook, event) => { + const pluginName = pluginInstance.constructor.name; + _.forEach(pluginInstance.hooks, (fn, event) => { this.hooks[event] = this.hooks[event] || []; - this.hooks[event].push(hook); + this.hooks[event].push({ + pluginName, + fn, + }); }); } @@ -148,6 +152,10 @@ class PluginManager { return this.plugins; } + getHooks(events) { + return _.flatMap([].concat(events), (event) => this.hooks[event] || []); + } + invoke(commandsArray, allowEntryPoints) { const command = this.getCommand(commandsArray, allowEntryPoints); @@ -155,14 +163,14 @@ class PluginManager { this.validateOptions(command); const events = this.getEvents(command); - const hooks = _.flatMap(events, (event) => this.hooks[event] || []); + const hooks = this.getHooks(events); if (hooks.length === 0) { const errorMessage = 'The command you entered did not catch on any hooks'; throw new this.serverless.classes.Error(errorMessage); } - return BbPromise.reduce(hooks, (__, hook) => hook(), null); + return BbPromise.reduce(hooks, (__, hook) => hook.fn(), null); } /** diff --git a/lib/classes/PluginManager.test.js b/lib/classes/PluginManager.test.js index c167222ef..b93e8612a 100644 --- a/lib/classes/PluginManager.test.js +++ b/lib/classes/PluginManager.test.js @@ -608,6 +608,30 @@ describe('PluginManager', () => { }); }); + describe('#getHooks()', () => { + beforeEach(function () { // eslint-disable-line prefer-arrow-callback + pluginManager.addPlugin(SynchronousPluginMock); + }); + + it('should get hooks for an event with some registered', () => { + expect(pluginManager.getHooks(['deploy:functions'])).to.be.an('Array').with.length(1); + }); + + it('should have the plugin name and function on the hook', () => { + const hooks = pluginManager.getHooks(['deploy:functions']); + expect(hooks[0].pluginName).to.equal('SynchronousPluginMock'); + expect(hooks[0].fn).to.be.a('Function'); + }); + + it('should not get hooks for an event that does not have any', () => { + expect(pluginManager.getHooks(['deploy:resources'])).to.be.an('Array').with.length(0); + }); + + it('should accept a single event in place of an array', () => { + expect(pluginManager.getHooks('deploy:functions')).to.be.an('Array').with.length(1); + }); + }); + describe('#getPlugins()', () => { beforeEach(function () { // eslint-disable-line prefer-arrow-callback mockRequire('ServicePluginMock1', ServicePluginMock1);