diff --git a/lib/Jaws.js b/lib/Jaws.js index 5fd934191..1bd5bac25 100644 --- a/lib/Jaws.js +++ b/lib/Jaws.js @@ -1,11 +1,11 @@ 'use strict'; const path = require('path'), - utils = require('./utils/index'), - JawsCLI = require('./utils/cli'), - JawsError = require('./jaws-error'), - Promise = require('bluebird'), - AWSUtils = require('./utils/aws'); + utils = require('./utils/index'), + JawsCLI = require('./utils/cli'), + JawsError = require('./jaws-error'), + Promise = require('bluebird'), + AWSUtils = require('./utils/aws'); /** * Jaws base Class @@ -133,21 +133,21 @@ class Jaws { * Set Action */ - action(actionName, actionGenerator) { + action(actionName, action) { // Check action is valid if (!this.actions[actionName]) { } - this.actions[actionName] = actionGenerator; + this.actions[actionName] = action; } /** * Set Hook */ - hook(hookName, hookGenerator, index) { + hook(hookName, hook, index) { // Check hook is valid if (!this.hooks[hookName]) { @@ -155,7 +155,7 @@ class Jaws { } index = (!index && index !== 0) ? this.hooks[hookName].length : index; - this.hooks[hookName].splice(index, 0, hookGenerator); + this.hooks[hookName].splice(index, 0, hook); } @@ -181,32 +181,25 @@ class Jaws { this._queue = this._queue.concat(this.hooks.PreProjectCreate); this._queue.push(this.actions.ProjectCreate.bind({}, options)); this._queue = this._queue.concat(this.hooks.PostProjectCreate); - this._executeQueue(); - return Promise.resolve(); + return this._executeQueue(); } /** * Execute Queue - * - Recursive function - * - Leverages Promise.coroutine to: - * -- iterate yields in a generator - * -- wait for yielded promises to resolve (necessary for async) - * -- push data back to generator */ _executeQueue() { let _this = this; - return Promise.coroutine(_this._queue[0])() - .then(function() { - _this._queue.splice(0, 1); //todo: change to .shift() - if (_this._queue.length) return _this._executeQueue(); - return; - }) - .catch(function(error) { - console.log('JAWS Plugin Error: ', error, error.stack); - return; - }); + return Promise.try(function() { + return _this._queue; + }) + .each(function(p) { + return p; + }) + .catch(function(error) { + throw new JawsError(error); + }); } /** diff --git a/lib/defaults/actions/ProjectCreate.js b/lib/defaults/actions/ProjectCreate.js index a7fefb10a..8f0ae9227 100644 --- a/lib/defaults/actions/ProjectCreate.js +++ b/lib/defaults/actions/ProjectCreate.js @@ -5,25 +5,27 @@ */ const JawsPlugin = require('../../JawsPlugin'), - JawsError = require('../../jaws-error'), - JawsCLI = require('../../utils/cli'), - Promise = require('bluebird'), - fs = require('fs'), - path = require('path'), - os = require('os'), - AWSUtils = require('../../utils/aws'), - utils = require('../../utils'), - shortid = require('shortid'); + JawsError = require('../../jaws-error'), + JawsCLI = require('../../utils/cli'), + Promise = require('bluebird'), + fs = require('fs'), + path = require('path'), + os = require('os'), + AWSUtils = require('../../utils/aws'), + utils = require('../../utils'), + shortid = require('shortid'); /** * ProjectCreate Class */ + class ProjectCreate extends JawsPlugin { /** * @param Jaws class object * @param config object */ + constructor(Jaws, config) { super(Jaws, config); } @@ -31,6 +33,7 @@ class ProjectCreate extends JawsPlugin { /** * @returns {Promise} upon completion of all registrations */ + registerActions() { this.Jaws.action('ProjectCreate', this._action()); return Promise.resolve(); @@ -42,6 +45,7 @@ class ProjectCreate extends JawsPlugin { * @returns {generator} * @private */ + _action() { let _this = this; @@ -107,6 +111,7 @@ class ProjectCreate extends JawsPlugin { /** * Generate ShortId */ + _generateShortId(maxLen) { return shortid.generate().replace(/\W+/g, '').substring(0, maxLen).replace(/[_-]/g, ''); } @@ -116,6 +121,7 @@ class ProjectCreate extends JawsPlugin { * @returns {*} * @private */ + _prompt() { utils.jawsDebug('Prompting for new project information'); @@ -229,63 +235,64 @@ class ProjectCreate extends JawsPlugin { // Show Prompts return _this.Prompter.getAsync(_this._prompts) - .then(function(answers) { - _this._name = answers.name; - _this._domain = answers.domain; - _this._stage = answers.stage.toLowerCase(); - _this._notificationEmail = answers.notificationEmail; - _this._awsAdminKeyId = answers.awsAdminKeyId; - _this._awsAdminSecretKey = answers.awsAdminSecretKey; + .then(function(answers) { + _this._name = answers.name; + _this._domain = answers.domain; + _this._stage = answers.stage.toLowerCase(); + _this._notificationEmail = answers.notificationEmail; + _this._awsAdminKeyId = answers.awsAdminKeyId; + _this._awsAdminSecretKey = answers.awsAdminSecretKey; - // If region exists, skip select prompt - if (_this._region) return; + // If region exists, skip select prompt + if (_this._region) return; - // Prompt: region select - let choices = []; - AWSUtils.validLambdaRegions.forEach(function(r) { - choices.push({ - key: '', - value: r, - label: r, + // Prompt: region select + let choices = []; + AWSUtils.validLambdaRegions.forEach(function(r) { + choices.push({ + key: '', + value: r, + label: r, + }); }); + + return JawsCLI.select('Select a region for your project: ', choices, false) + .then(function(results) { + _this._region = results[0].value; + }); + }) + .then(function() { + + // If profile exists, skip select prompt + if (_this._profile) return Promise.resolve(); + + // If aws credentials were passed, skip select prompt + if (_this._awsAdminKeyId && _this._awsAdminSecretKey) return Promise.resolve(); + + // Prompt: profile select + let profilesList = AWSUtils.profilesMap(), + profiles = Object.keys(profilesList), + choices = []; + + for (let i = 0; i < profiles.length; i++) { + choices.push({ + key: '', + value: profiles[i], + label: profiles[i], + }); + } + + return JawsCLI.select('Select an AWS profile for your project: ', choices, false) + .then(function(results) { + _this._profile = results[0].value; + }); }); - - return JawsCLI.select('Select a region for your project: ', choices, false) - .then(function(results) { - _this._region = results[0].value; - }); - }) - .then(function() { - - // If profile exists, skip select prompt - if (_this._profile) return Promise.resolve(); - - // If aws credentials were passed, skip select prompt - if (_this._awsAdminKeyId && _this._awsAdminSecretKey) return Promise.resolve(); - - // Prompt: profile select - let profilesList = AWSUtils.profilesMap(), - profiles = Object.keys(profilesList), - choices = []; - - for (let i = 0; i < profiles.length; i++) { - choices.push({ - key: '', - value: profiles[i], - label: profiles[i], - }); - } - - return JawsCLI.select('Select an AWS profile for your project: ', choices, false) - .then(function(results) { - _this._profile = results[0].value; - }); - }); } /** * Prepare Project Data */ + _prepareProjectData() { let _this = this; @@ -324,5 +331,4 @@ class ProjectCreate extends JawsPlugin { } } - module.exports = ProjectCreate; \ No newline at end of file diff --git a/package.json b/package.json index c4f0a3acf..0dd3f6ada 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,8 @@ }, "dependencies": { "async": "^0.9.0", + "asynquence": "^0.8.2", + "asynquence-contrib": "^0.22.0", "aws-sdk": "^2.2.4", "babelify": "^6.3.0", "bluebird": "^2.9.34", @@ -46,6 +48,7 @@ "chalk": "^1.1.0", "cli-spinner": "^0.2.1", "commander": "^2.5.0", + "commop": "^1.2.0", "debug": "^2.2.0", "dotenv": "^1.2.0", "download": "^4.2.0", diff --git a/tests/all.js b/tests/all.js index bbbceb351..d08a675c7 100644 --- a/tests/all.js +++ b/tests/all.js @@ -15,6 +15,7 @@ describe('AllTests', function() { }); //require tests vs inline so we can run sequentially + require('./cli/TestPlugins'); //require('./cli/tag'); //require('./cli/env'); //require('./cli/module_create'); @@ -28,5 +29,5 @@ describe('AllTests', function() { //require('./cli/deploy_resources'); //require('./cli/deploy_endpoint'); //require('./cli/new_stage_region'); - require('./cli/TestActionProjectCreate'); + //require('./cli/TestActionProjectCreate'); }); \ No newline at end of file diff --git a/tests/cli/TestActionProjectCreate.js b/tests/cli/TestActionProjectCreate.js index 8f97cad07..99e3fc1ac 100644 --- a/tests/cli/TestActionProjectCreate.js +++ b/tests/cli/TestActionProjectCreate.js @@ -51,7 +51,9 @@ describe('Test Project Create', function() { Jaws.projectCreate(prjConfig) .then(function() { - let jawsJson = utils.readAndParseJsonSync(path.join(os.tmpdir(), config.newName, 'jaws.json')); + let jawsJson = utils.readAndParseJsonSync( + path.join(os.tmpdir(), config.newName, 'jaws.json')); + let region = false; for (let i = 0; i < jawsJson.stages[config.stage].length; i++) { diff --git a/tests/cli/TestPlugins.js b/tests/cli/TestPlugins.js new file mode 100644 index 000000000..9115e75c5 --- /dev/null +++ b/tests/cli/TestPlugins.js @@ -0,0 +1,108 @@ +'use strict'; + +/** + * Test: Plugins + */ + +let JAWS = require('../../lib/Jaws.js'), + JawsPlugin = require('../../lib/JawsPlugin'), + JawsError = require('../../lib/jaws-error'), + path = require('path'), + os = require('os'), + utils = require('../../lib/utils'), + assert = require('chai').assert, + shortid = require('shortid'), + config = require('../config'), + Promise = require('bluebird'); + +/** + * JAWS + */ + +let Jaws = new JAWS({ + awsAdminKeyId: '123', + awsAdminSecretKey: '123', + interactive: false, +}); + +/** + * Define Plugin + */ + +class PromisePlugin extends JawsPlugin { + + constructor(Jaws, config) { + super(Jaws, config); + } + + registerActions() { + this.Jaws.action('ProjectCreate', this._actionProjectCreate()); + } + + registerHooks() { + this.Jaws.hook('PreProjectCreate', this._hookPreProjectCreate()); + this.Jaws.hook('PostProjectCreate', this._hookPostProjectCreate()); + } + + _hookPreProjectCreate() { + let _this = this; + return new Promise(function(resolve, reject) { + _this.Jaws.generatorPluginHookPre = true; + return resolve(); + }) + } + + _actionProjectCreate() { + let _this = this; + return Promise.delay(500) + .then(function() { + _this.Jaws.generatorPluginHookAction = true; + }); + } + + _hookPostProjectCreate() { + let _this = this; + return Promise.delay(500) + .then(function() { + _this.Jaws.generatorPluginHookPost = true; + }); + } +} + +/** + * Run Tests + */ + +describe('Test Promise Plugins', function() { + + before(function(done) { + Jaws.addPlugin(new PromisePlugin(Jaws, {})); + done(); + }); + + after(function(done) { + done(); + }); + + describe('Test Promise Plugins', function() { + it('should run and attach values to context', function(done) { + + Jaws.projectCreate({ + name: 'test', + stage: 'test', + region: 'us-east-1', + domain: 'test.com', + notificationEmail: 'test@test.com', + }) + .then(function() { + assert.isTrue(Jaws.generatorPluginHookPre); + assert.isTrue(Jaws.generatorPluginHookPost); + assert.isTrue(Jaws.generatorPluginHookAction); + done(); + }) + .catch(function(e) { + done(e); + }); + }); + }); +}); \ No newline at end of file