forked from serverless/serverless
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request serverless#1128 from serverless/add-plugin-managem…
…ent-class Add PluginManagement class
- Loading branch information
Showing
8 changed files
with
585 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
'use strict'; | ||
|
||
const Utils = require('./Utils'); | ||
const path = require('path'); | ||
const has = require('lodash').has; | ||
const forEach = require('lodash').forEach; | ||
|
||
class PluginManager { | ||
constructor(serverless) { | ||
this.serverless = serverless; | ||
this.plugins = []; | ||
this.commandsList = []; | ||
this.commands = {}; | ||
} | ||
|
||
loadAllPlugins(servicePlugins) { | ||
this.loadCorePlugins(); | ||
this.loadServicePlugins(servicePlugins); | ||
} | ||
|
||
runCommand(commandsArray) { | ||
const events = this.getEvents(commandsArray, this.commands); | ||
// collect all relevant hooks | ||
let hooks = []; | ||
events.forEach((event) => { | ||
const hooksForEvent = []; | ||
this.plugins.forEach((pluginInstance) => { | ||
forEach(pluginInstance.hooks, (hook, hookKey) => { | ||
if (hookKey === event) { | ||
hooksForEvent.push(hook); | ||
} | ||
}); | ||
}); | ||
hooks = hooks.concat(hooksForEvent); | ||
}); | ||
|
||
if (hooks.length === 0) { | ||
throw new Error('The command you entered was not found. Did you spell it correctly?'); | ||
} | ||
|
||
// run all relevant hooks one after another | ||
hooks.forEach((hook) => { | ||
const returnValue = hook(); | ||
|
||
// check if a Promise is returned | ||
if (returnValue && returnValue.then instanceof Function) { | ||
returnValue.then((value) => { | ||
return value; | ||
}); | ||
} | ||
}); | ||
} | ||
|
||
addPlugin(Plugin) { | ||
this.plugins.push(new Plugin()); | ||
|
||
this.loadCommands(Plugin); | ||
} | ||
|
||
loadCorePlugins() { | ||
const utils = new Utils(); | ||
const pluginsDirectoryPath = path.join(__dirname, '../plugins'); | ||
|
||
const corePlugins = utils.readFileSync(path.join(pluginsDirectoryPath, 'Plugins.json')).plugins; | ||
|
||
corePlugins.forEach((corePlugin) => { | ||
const Plugin = require(path.join(pluginsDirectoryPath, corePlugin)); | ||
|
||
this.addPlugin(Plugin); | ||
}); | ||
} | ||
|
||
loadServicePlugins(servicePlugins) { | ||
servicePlugins = (typeof servicePlugins !== 'undefined' ? servicePlugins : []); | ||
|
||
servicePlugins.forEach((servicePlugins) => { | ||
this.addPlugin(servicePlugins); | ||
}); | ||
} | ||
|
||
loadCommands(Plugin) { | ||
this.commandsList.push((new Plugin()).commands); | ||
|
||
// TODO: refactor ASAP as it slows down overall performance | ||
// rebuild the commands | ||
forEach(this.commandsList, (commands) => { | ||
forEach(commands, (commandDetails, command) => { | ||
this.commands[command] = commandDetails; | ||
}); | ||
}); | ||
} | ||
|
||
getEvents(commandsArray, availableCommands, prefix) { | ||
prefix = (typeof prefix !== 'undefined' ? prefix : ''); | ||
const commandPart = commandsArray[0]; | ||
|
||
if (has(availableCommands, commandPart)) { | ||
const commandDetails = availableCommands[commandPart]; | ||
if (commandsArray.length === 1) { | ||
const events = []; | ||
commandDetails.lifeCycleEvents.forEach((event) => { | ||
events.push(`before:${prefix}${commandPart}:${event}`); | ||
events.push(`${prefix}${commandPart}:${event}`); | ||
events.push(`after:${prefix}${commandPart}:${event}`); | ||
}); | ||
return events; | ||
} | ||
if (has(commandDetails, 'commands')) { | ||
return this.getEvents(commandsArray.slice(1, commandsArray.length), | ||
commandDetails.commands, `${commandPart}:`); | ||
} | ||
} | ||
|
||
return []; | ||
} | ||
} | ||
|
||
module.exports = PluginManager; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
'use strict'; | ||
|
||
class HelloWorld { | ||
constructor() { | ||
this.commands = { | ||
greet: { | ||
usage: 'Run this command to get greeted.', | ||
lifeCycleEvents: [ | ||
'printGoodMorning', | ||
'printHello', | ||
'printGoodEvening' | ||
] | ||
}, | ||
}; | ||
|
||
this.hooks = { | ||
'before:greet:printHello': this.printGoodMorning, | ||
'greet:printHello': this.printHello, | ||
'after:greet:printHello': this.printGoodEvening, | ||
}; | ||
} | ||
|
||
printGoodMorning() { | ||
const message = 'Good morning'; | ||
console.log(message); | ||
return message; | ||
} | ||
|
||
printHello() { | ||
const message = 'Hello'; | ||
console.log(message); | ||
return message; | ||
} | ||
|
||
printGoodEvening() { | ||
const message = 'Good evening'; | ||
console.log(message); | ||
return message; | ||
} | ||
} | ||
|
||
module.exports = HelloWorld; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# Hello world | ||
This plugin is a simple "Hello World" plugin which shows how the plugin system works. | ||
|
||
## Setup | ||
Run `npm install` to install all dependencies. | ||
|
||
## Tests | ||
Tests live inside the `tests` directory. Run `npm test` inside the root of this plugin to run the tests. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{ | ||
"name": "serverless-plugins-hello-world", | ||
"version": "0.0.1", | ||
"description": "", | ||
"license": "MIT", | ||
"scripts": { | ||
"test": "node_modules/.bin/mocha ./tests/HelloWorld.js" | ||
}, | ||
"devDependencies": { | ||
"chai": "^3.5.0", | ||
"mocha": "^2.4.5" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
'use strict'; | ||
|
||
/** | ||
* Test: HelloWorld Plugin | ||
*/ | ||
|
||
const expect = require('chai').expect; | ||
const HelloWorld = require('../HelloWorld'); | ||
|
||
|
||
describe('HelloWorld', () => { | ||
let helloWorld; | ||
|
||
beforeEach(() => { | ||
helloWorld = new HelloWorld(); | ||
}); | ||
|
||
describe('#constructor()', () => { | ||
it('should have commands', () => { | ||
expect(helloWorld.commands).to.be.not.empty; | ||
}); | ||
|
||
it('should have hooks', () => { | ||
expect(helloWorld.hooks).to.be.not.empty; | ||
}); | ||
}); | ||
|
||
describe('#printGoodMorning()', () => { | ||
it('should print "Good morning"', () => { | ||
const greeting = helloWorld.printGoodMorning(); | ||
|
||
expect(greeting).to.equal('Good morning'); | ||
}); | ||
}); | ||
|
||
describe('#printHello()', () => { | ||
it('should print "Hello"', () => { | ||
const greeting = helloWorld.printHello(); | ||
|
||
expect(greeting).to.equal('Hello'); | ||
}); | ||
}); | ||
|
||
describe('#printGoodEvening()', () => { | ||
it('should print "Good evening"', () => { | ||
const greeting = helloWorld.printGoodEvening(); | ||
|
||
expect(greeting).to.equal('Good evening'); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"plugins": [ | ||
"./HelloWorld/HelloWorld.js" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.