postinstall new features. Module create re-factor

This commit is contained in:
doapp-ryanp 2015-09-29 23:39:57 -05:00
parent 44980d5a09
commit 14187c212d
6 changed files with 128 additions and 64 deletions

View File

@ -88,7 +88,8 @@ program
)
.option('-l, --lambda', '[create]: create lambda. Default is create lambda and endpoint.')
.option('-e, --endpoint', '[create]: create API Gateway endpoint. Default is create lambda and endpoint.')
.option('-p, --package-manager', '[create]: creates pkg manager scaffolding along with your aws_module. Valid: npm')
.option('-r, --runtime', '[create]: lambda runtime. Valid: nodejs')
.option('-p, --package-manager', '[create]: override default pkg manager used when auto-creating scaffolding. Valid: TODO. Defaults: nodejs->npm, ')
.action(function(cmd, params, options) {
var theParams = process.argv.slice(3);
@ -109,7 +110,7 @@ program
name = theParams[1],
action = theParams[2],
runtime = options.runtime || 'nodejs',
createPkgMgrScaffold = options.packageManager || false,
pkgMgrOverride = options.packageManager || false,
modType = 'both';
if (options.lambda) {
@ -118,7 +119,7 @@ program
modType = 'endpoint';
}
execute(theCmd.run(JAWS, name, action, runtime, createPkgMgrScaffold, modType));
execute(theCmd.run(JAWS, name, action, runtime, pkgMgrOverride, modType));
} else {
console.error('Unsupported cmd ' + cmd + '. Must be install|update|create');
process.exit(1);

View File

@ -64,7 +64,8 @@ CMD.prototype.run = Promise.method(function() {
// If !allTagged, Show Dashboard
if (!_this._allTagged) {
return Promise.try(function() {})
return Promise.try(function() {
})
.bind(_this)
.then(_this._prepareResources)
.then(_this._prepareSummary)
@ -140,7 +141,7 @@ CMD.prototype.run = Promise.method(function() {
CMD.prototype._prepareResources = Promise.method(function() {
var _this = this;
return utils.findAllAwsmJsons(_this._JAWS._meta.projectRootPath)
return utils.findAllAwsmJsons(path.join(_this._JAWS._meta.projectRootPath, 'aws_modules'))
.then(function(jsonPaths) {
var hybrids = [];
@ -176,7 +177,7 @@ CMD.prototype._prepareResources = Promise.method(function() {
value: jsonPaths[i],
type: 'endpoint',
label: '/' + json.apiGateway.cloudFormation.Path
+ ' - ' + json.apiGateway.cloudFormation.Method,
+ ' - ' + json.apiGateway.cloudFormation.Method,
};
// Create path

View File

@ -86,7 +86,7 @@ module.exports.listEnv = function(JAWS, stage, region, showWhereUsed) {
var _this = this,
projRootDir = JAWS._meta.projectRootPath;
return utils.findAllAwsmJsons(projRootDir)
return utils.findAllAwsmJsons(path.join(_this._JAWS._meta.projectRootPath, 'aws_modules'))
.then(function(awsmJsonPaths) {
return [awsmJsonPaths, _this._getEnvFiles(JAWS, stage, region)];
})

View File

@ -12,6 +12,13 @@ var JawsError = require('../jaws-error'),
path = require('path'),
utils = require('../utils');
var supportedRuntimes = {
nodejs: {
defaultPkgMgr: 'npm',
validPkgMgrs: ['npm']
}
};
Promise.promisifyAll(fs);
/**
@ -20,22 +27,43 @@ Promise.promisifyAll(fs);
* @param name
* @param action
* @param runtime 'nodejs' default
* @param createPkgMgrScaffold if not false, will create pkg mgr scaffolding. Valid: 'npm' etc
* @param pkgMgrOverride override the default pkg manager for runtime with this one
* @param moduleType 'lambda','endpoint','both'
* @returns {*}
*/
module.exports.run = function(JAWS, name, action, runtime, createPkgMgrScaffold, moduleType) {
var command = new CMD(JAWS, name, action, runtime || 'nodejs', createPkgMgrScaffold || false, moduleType);
module.exports.run = function(JAWS, name, action, runtime, pkgMgrOverride, moduleType) {
var command = new CMD(JAWS, name, action, runtime, pkgMgrOverride, moduleType);
return command.run();
};
function CMD(JAWS, name, action, runtime, createPkgMgrScaffold, modType) {
/**
*
* @param JAWS
* @param name
* @param action
* @param runtime
* @param pkgMgrOverride
* @param modType
* @constructor
*/
function CMD(JAWS, name, action, runtime, pkgMgrOverride, modType) {
if (!runtime) {
runtime = 'nodejs';
}
if (!supportedRuntimes[runtime]) {
throw new JawsError('Unsupported runtime "' + runtime + '"', JawsError.errorCodes.UNKNOWN);
}
var _this = this,
supportedRuntimeObj = supportedRuntimes[runtime];
this._JAWS = JAWS;
this._module = {
this._moduleName = {
name: name,
runtime: runtime,
action: action,
createPkgMgrScaffold: createPkgMgrScaffold,
pkgMgr: pkgMgrOverride || supportedRuntimeObj.defaultPkgMgr,
type: modType,
};
this._prompts = {
@ -43,6 +71,10 @@ function CMD(JAWS, name, action, runtime, createPkgMgrScaffold, modType) {
};
this.Prompter = JawsCLI.prompt();
this.Prompter.override = {};
if (supportedRuntimeObj.validPkgMgrs.indexOf(_this._moduleName.pkgMgr) == -1) {
throw new JawsError('Unsupported package manger "' + _this._moduleName.pkgMgr + '"', JawsError.errorCodes.UNKNOWN);
}
}
CMD.prototype.constructor = CMD;
@ -52,19 +84,18 @@ CMD.prototype.constructor = CMD;
*/
CMD.prototype.run = Promise.method(function() {
var _this = this;
return _this._JAWS.validateProject()
.bind(_this)
.then(_this._sanitizeData)
.then(_this._createSkeleton)
.then(_this._createPackageMgrSkeleton())
.then(_this._createPackageMgrSkeleton)
.then(function() {
JawsCLI.log('Successfully created '
+ _this._module.name
+ _this._moduleName.name
+ '/'
+ _this._module.action);
+ _this._moduleName.action);
});
});
@ -74,31 +105,28 @@ CMD.prototype.run = Promise.method(function() {
* @returns {Promise}
*/
CMD.prototype._createPackageMgrSkeleton = function() {
if (!this._module.createPkgMgrScaffold) {
return Promise.resolve();
}
var _this = this,
deferredWrites = [];
deferredWrites = [],
modulePath = path.join(
_this._JAWS._meta.projectRootPath,
'aws_modules',
_this._moduleName.name);
switch (_this._module.runtime) {
switch (_this._moduleName.runtime) {
case 'nodejs':
if (_this._module.createPkgMgrScaffold == 'npm') {
var packageJsonTemplate = utils.readAndParseJsonSync(path.join(__dirname, '../templates/nodejs/package.json'));
if (_this._moduleName.pkgMgr == 'npm') {
var packageJsonTemplate = utils.readAndParseJsonSync(path.join(__dirname, '..', 'templates', 'nodejs', 'package.json'));
packageJsonTemplate.name = _this._name;
packageJsonTemplate.dependencies = {};
deferredWrites.push(
fs.writeFileAsync(
path.join(_this._JAWS._meta.projectRootPath, 'package.json'),
path.join(modulePath, 'package.json'),
JSON.stringify(packageJsonTemplate, null, 2)
)
);
} else {
return Promise.reject(new JawsError('Unsupported package manager', JawsError.errorCodes.UNKNOWN));
}
break;
default:
throw new JawsError('Unsupported runtime "' + _this._module.runtime + '"', JawsError.errorCodes.UNKNOWN);
break;
}
@ -113,12 +141,12 @@ CMD.prototype._sanitizeData = Promise.method(function() {
var _this = this;
_this._module.name = _this._module.name.toLowerCase().trim()
_this._moduleName.name = _this._moduleName.name.toLowerCase().trim()
.replace(/\s/g, '-')
.replace(/[^a-zA-Z-\d:]/g, '')
.substring(0, 19);
_this._module.action = _this._module.action.toLowerCase().trim()
_this._moduleName.action = _this._moduleName.action.toLowerCase().trim()
.replace(/\s/g, '-')
.replace(/[^a-zA-Z-\d:]/g, '')
.substring(0, 19);
@ -140,8 +168,8 @@ CMD.prototype._createSkeleton = Promise.method(function() {
var modulePath = path.join(
_this._JAWS._meta.projectRootPath,
'aws_modules',
_this._module.name);
var actionPath = path.join(modulePath, _this._module.action);
_this._moduleName.name);
var actionPath = path.join(modulePath, _this._moduleName.action);
// If module/action already exists, throw error
if (utils.dirExistsSync(actionPath)) {
@ -156,7 +184,7 @@ CMD.prototype._createSkeleton = Promise.method(function() {
// If module awsm.json doesn't exist, create it
if (!utils.fileExistsSync(path.join(modulePath, 'awsm.json'))) {
var moduleTemplateJson = utils.readAndParseJsonSync(path.join(templatesPath, 'module.awsm.json'));
moduleTemplateJson.name = _this._module.name;
moduleTemplateJson.name = _this._moduleName.name;
writeFilesDeferred.push(
utils.writeFile(
path.join(modulePath, 'awsm.json'),
@ -167,25 +195,14 @@ CMD.prototype._createSkeleton = Promise.method(function() {
writeFilesDeferred.push(actionPath);
// Create action awsm.json
actionTemplateJson.apiGateway.cloudFormation.Path = _this._module.name + '/' + _this._module.action;
actionTemplateJson.apiGateway.cloudFormation.Path = _this._moduleName.name + '/' + _this._moduleName.action;
actionTemplateJson.apiGateway.cloudFormation.Method = 'GET';
actionTemplateJson.apiGateway.cloudFormation.Type = 'AWS';
if (['lambda', 'both'].indexOf(_this._module.type) != -1) {
if (['lambda', 'both'].indexOf(_this._moduleName.type) != -1) {
// Create files for lambda actions
switch (_this._module.runtime) {
switch (_this._moduleName.runtime) {
case 'nodejs':
// If module package.json doesnt exist, create it
var pkgJsonPath = path.join(modulePath, 'package.json');
if (!utils.fileExistsSync(pkgJsonPath)) {
var packageTemplateJson = utils.readAndParseJsonSync(path.join(templatesPath, 'nodejs', 'package.json'));
packageTemplateJson.name = _this._module.name;
packageTemplateJson.private = true;
writeFilesDeferred.push(
utils.writeFile(pkgJsonPath, JSON.stringify(packageTemplateJson, null, 2))
);
}
var modLibPath = path.join(modulePath, 'lib');
if (!utils.dirExistsSync(modLibPath)) {
writeFilesDeferred.push(fs.mkdirAsync(modLibPath));
@ -195,8 +212,8 @@ CMD.prototype._createSkeleton = Promise.method(function() {
actionTemplateJson.lambda.cloudFormation.Runtime = 'nodejs';
actionTemplateJson.lambda.cloudFormation.Handler = path.join(
'aws_modules',
_this._module.name,
_this._module.action,
_this._moduleName.name,
_this._moduleName.action,
'handler.handler');
// Create handler.js, index.js, event.json, package.json
@ -210,17 +227,17 @@ CMD.prototype._createSkeleton = Promise.method(function() {
);
break;
default:
throw new JawsError('This runtime is not supported "' + _this._module.runtime + '"', JawsError.errorCodes.UNKNOWN);
throw new JawsError('This runtime is not supported "' + _this._moduleName.runtime + '"', JawsError.errorCodes.UNKNOWN);
break;
}
}
// Trim unnecessary JSON
if (_this._module.type === 'lambda') {
if (_this._moduleName.type === 'lambda') {
delete actionTemplateJson.apiGateway;
}
if (_this._module.type === 'endpoint') {
if (_this._moduleName.type === 'endpoint') {
delete actionTemplateJson.lambda;
}

View File

@ -30,9 +30,9 @@ function CMD(JAWS, moduleName, packageManager) {
return Promise.reject(new JawsError('Unsupported package manager', JawsError.errorCodes.UNKNOWN));
}
this._JAWS = JAWS;
this._module = moduleName;
this._moduleName = moduleName;
this._packageManager = packageManager;
this._rootAwsmJson;
this._rootAwsmJson = {};
}
CMD.prototype.constructor = CMD;
@ -48,8 +48,6 @@ CMD.prototype.run = Promise.method(function() {
return Promise.all([module, _this._saveCfTemplate(module.path)]);
})
.spread(function(module) {
JawsCLI.log('Successfully installed ' + module.name);
var deferredDepInstalls = [];
switch (_this._packageManager) {
@ -68,6 +66,16 @@ CMD.prototype.run = Promise.method(function() {
}
return Promise.all(deferredDepInstalls);
})
.then(function() {
return utils.findAllEnvVarsForAwsm(_this._JAWS._meta.projectRootPath, _this._moduleName);
})
.then(function(envVars) {
JawsCLI.log('Successfully installed ' + _this._moduleName);
if (envVars && envVars.length > 1) {
JawsCLI.log('This aws module uses env vars MAKE SURE to run jaws env list to see which ones need to be set');
}
});
});
@ -86,8 +94,8 @@ CMD.prototype._installFiles = Promise.method(function() {
pkgMgrDir = 'node_modules';
}
var srcAwsmPath = path.join(_this._JAWS._meta.projectRootPath, pkgMgrDir, _this._module, 'awsm'),
srcAwsmJsonPath = path.join(_this._JAWS._meta.projectRootPath, pkgMgrDir, _this._module, 'awsm.json'),
var srcAwsmPath = path.join(_this._JAWS._meta.projectRootPath, pkgMgrDir, _this._moduleName, 'awsm'),
srcAwsmJsonPath = path.join(_this._JAWS._meta.projectRootPath, pkgMgrDir, _this._moduleName, 'awsm.json'),
awsModsPath = path.join(_this._JAWS._meta.projectRootPath, 'aws_modules');
if (!utils.fileExistsSync(srcAwsmJsonPath)) {
@ -124,7 +132,11 @@ CMD.prototype._installFiles = Promise.method(function() {
excludeHiddenUnix: false,
});
return {name: awsmJson.name, path: targetModPath};
//Write mod root awsm.json so we can identify awsm dirs later
return utils.writeFile(path.join(targetModPath, 'awsm.json'), JSON.stringify(awsmJson, null, 2))
.then(function() {
return {name: awsmJson.name, path: targetModPath};
});
});
/**

View File

@ -18,10 +18,10 @@ Promise.promisifyAll(fs);
/**
* Find all awsm paths of given type
*
* @param projectRootPath
* @param startPath
* @param type lambda|endpoint
*/
exports.findAllAwsmPathsOfType = function(projectRootPath, type) {
exports.findAllAwsmPathsOfType = function(startPath, type) {
var _this = this,
jawsJsonAttr;
switch (type) {
@ -36,7 +36,7 @@ exports.findAllAwsmPathsOfType = function(projectRootPath, type) {
break;
}
return _this.readRecursively(projectRootPath, '*awsm.json')
return _this.readRecursively(startPath, '*awsm.json')
.then(function(jsonPaths) {
return new Promise(function(resolve, reject) {
@ -44,7 +44,7 @@ exports.findAllAwsmPathsOfType = function(projectRootPath, type) {
// Check each file to ensure it is a lambda
async.eachLimit(jsonPaths, 10, function(jsonPath, cb) {
var lambdaJawsPath = path.join(projectRootPath, jsonPath),
var lambdaJawsPath = path.join(startPath, jsonPath),
json = require(lambdaJawsPath);
if (typeof json[jawsJsonAttr] !== 'undefined') jawsPathsOfType.push(lambdaJawsPath);
@ -160,6 +160,39 @@ exports.findAllEndpoints = function(projectRootPath) {
return this.findAllAwsmPathsOfType(projectRootPath, 'endpoint');
};
/**
* Finds all env var keys that are used by all lambdas in a given aws module
*
* @param projectRootPath
* @param modName
* @returns {Promise} list of ENV var key strings
*/
exports.findAllEnvVarsForAwsm = function(projectRootPath, modName) {
var _this = this;
console.log(projectRootPath, 'aws_modules', modName);
return this.findAllAwsmPathsOfType(path.join(projectRootPath, 'aws_modules', modName), 'lambda')
.then(function(awsmJsonPaths) {
var envVarKeys = [];
awsmJsonPaths.forEach(function(awsmJsonPath) {
var awsmJson = _this.readAndParseJsonSync(awsmJsonPath);
//TODO: change to es6 set...
if (awsmJson.lambda && awsmJson.lambda.envVars) {
awsmJson.lambda.envVars.forEach(function(envVar) {
if (envVarKeys.indexOf(envVar) == -1) {
envVarKeys.push(envVar);
}
});
}
});
return envVarKeys;
});
};
/**
* Find all awsm json paths underneath given dir
*