From b97871ed3f3d78a1db3fa7f0337c6d60c1043fbd Mon Sep 17 00:00:00 2001 From: Egor Kislitsyn Date: Mon, 8 Feb 2016 16:33:10 +0700 Subject: [PATCH 1/7] fixes ServerlessFunction scaffolding --- lib/ServerlessFunction.js | 29 +++++++++++++++-------------- lib/templates/nodejs/handler.js | 2 +- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/lib/ServerlessFunction.js b/lib/ServerlessFunction.js index e200f85ac..1a25be3cf 100644 --- a/lib/ServerlessFunction.js +++ b/lib/ServerlessFunction.js @@ -11,7 +11,7 @@ const SError = require('./ServerlessError'), BbPromise = require('bluebird'), async = require('async'), path = require('path'), - fs = require('fs'), + fs = BbPromise.promisifyAll(require('fs')), _ = require('lodash'); class ServerlessFunction { @@ -337,24 +337,25 @@ class ServerlessFunction { _create() { - let _this = this; - - return BbPromise.try(function() { - + return fs.mkdirAsync(this._config.fullPath).then(() => { let writeDeferred = []; - // Runtime: nodejs - writeDeferred.push( - fs.mkdirSync(_this._config.fullPath), - SUtils.writeFile(path.join(_this._config.fullPath, 'event.json'), '{}') - ); - if (_this.getRuntime() === 'nodejs') { + writeDeferred.push(SUtils.writeFile(path.join(this._config.fullPath, 'event.json'), '{}')); + + if (this.getRuntime() === 'nodejs') { writeDeferred.push( - SUtils.writeFile(path.join(_this._config.fullPath, 'handler.js'), fs.readFileSync(path.join(_this._S.config.serverlessPath, 'templates', 'nodejs', 'handler.js'))) + fs.readFileAsync(path.join(this._S.config.serverlessPath, 'templates', 'nodejs', 'handler.js')) + .then((template) => { + let subFolderLevel = this._config.sPath.split('/').length - 1, + libPath = _.repeat('../', subFolderLevel) + 'lib', + handlerJs = _.template(template)({libPath: libPath}); + + return SUtils.writeFile(path.join(this._config.fullPath, 'handler.js'), handlerJs) + }) ) - } else if (_this.getRuntime() === 'python2.7') { + } else if (this.getRuntime() === 'python2.7') { writeDeferred.push( - SUtils.writeFile(path.join(_this._config.fullPath, 'handler.py'), fs.readFileSync(path.join(_this._S.config.serverlessPath, 'templates', 'python2.7', 'handler.py'))) + SUtils.writeFile(path.join(this._config.fullPath, 'handler.py'), fs.readFileSync(path.join(this._S.config.serverlessPath, 'templates', 'python2.7', 'handler.py'))) ) } return BbPromise.all(writeDeferred); diff --git a/lib/templates/nodejs/handler.js b/lib/templates/nodejs/handler.js index fc117e63d..e54bec421 100644 --- a/lib/templates/nodejs/handler.js +++ b/lib/templates/nodejs/handler.js @@ -11,7 +11,7 @@ var ServerlessHelpers = require('serverless-helpers-js').loadEnv(); // Require Logic -var lib = require('../../lib'); +var lib = require('<%= libPath%>'); // Lambda Handler module.exports.handler = function(event, context) { From 03e624cbcdd5d21db4d8f4cc08e91d8bbed406c4 Mon Sep 17 00:00:00 2001 From: Egor Kislitsyn Date: Mon, 8 Feb 2016 16:40:53 +0700 Subject: [PATCH 2/7] removes unused dependencies: `insert-module-globals`, `expand-home-dir` --- package.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/package.json b/package.json index 45244fcab..b99341a0d 100644 --- a/package.json +++ b/package.json @@ -49,9 +49,7 @@ "debug": "^2.2.0", "dotenv": "^1.2.0", "download": "^4.2.0", - "expand-home-dir": "0.0.2", "fs-extra": "^0.26.4", - "insert-module-globals": "^6.5.2", "keypress": "^0.2.1", "lodash": "^3.9.0", "minimist": "^1.2.0", From 87d675f6d781763d3fe559ad14cd127e4ea8d11f Mon Sep 17 00:00:00 2001 From: Egor Kislitsyn Date: Mon, 8 Feb 2016 16:41:24 +0700 Subject: [PATCH 3/7] fixes actions/FunctionRunLambdaNodeJs --- lib/actions/FunctionRunLambdaNodeJs.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/actions/FunctionRunLambdaNodeJs.js b/lib/actions/FunctionRunLambdaNodeJs.js index a0e637fe7..bcddc138a 100644 --- a/lib/actions/FunctionRunLambdaNodeJs.js +++ b/lib/actions/FunctionRunLambdaNodeJs.js @@ -43,8 +43,8 @@ module.exports = function(SPlugin, serverlessPath) { let _this = this; _this.evt = evt; - if (!_this.evt.options.path || _this.evt.options.path.split('/').length != 3) { - return BbPromise.reject(new SError('Invalid function path. Function path should be in this format: component/module/function .')); + if (!_this.evt.options.path || _this.evt.options.path.split('/').length < 2) { + return BbPromise.reject(new SError('Invalid function path. Function path should be in this format: component/function .')); } // Instantiate Classes From 6714e241223f079f880f248de66defbe9cb5c315 Mon Sep 17 00:00:00 2001 From: Egor Kislitsyn Date: Mon, 8 Feb 2016 17:45:55 +0700 Subject: [PATCH 4/7] improves FunctionRun action: - strip trailing slashes from path - FunctionRunLambdaNodeJs: show error stack trace --- lib/actions/FunctionRun.js | 7 +++++-- lib/actions/FunctionRunLambdaNodeJs.js | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/actions/FunctionRun.js b/lib/actions/FunctionRun.js index e4d65e218..d67f5d442 100644 --- a/lib/actions/FunctionRun.js +++ b/lib/actions/FunctionRun.js @@ -113,14 +113,17 @@ module.exports = function(SPlugin, serverlessPath) { // Get all functions in CWD let sPath = _this.getSPathFromCwd(_this.S.config.projectPath); if (!sPath) { - throw new SError(`You must be in a function folder to run it`); + return BbPromise.reject(new SError(`You must be in a function folder to run it`)); } _this.evt.options.path = [sPath]; } + // strip trailing slashes from path + _this.evt.options.path = _this.evt.options.path.replace(/\/$/, ""); + let funcs = _this.S.state.getFunctions({ paths: [_this.evt.options.path] }); if (funcs.length > 1) { - throw new SError(`You must be in a function folder to run it`); + return BbPromise.reject(new SError(`You must be in a function folder to run it`)); } _this.function = funcs[0]; diff --git a/lib/actions/FunctionRunLambdaNodeJs.js b/lib/actions/FunctionRunLambdaNodeJs.js index bcddc138a..fd2f7c374 100644 --- a/lib/actions/FunctionRunLambdaNodeJs.js +++ b/lib/actions/FunctionRunLambdaNodeJs.js @@ -95,7 +95,7 @@ module.exports = function(SPlugin, serverlessPath) { SCli.log(`-----------------`); SCli.log(chalk.bold('Failed - This Error Was Thrown:')); - SCli.log(err); + SCli.log(err.stack || err); _this.evt.data.result.status = 'error'; _this.evt.data.result.response = err.message; return resolve(); From 730468689cc6af661becce3867b5decfd436022b Mon Sep 17 00:00:00 2001 From: Egor Kislitsyn Date: Mon, 8 Feb 2016 18:23:18 +0700 Subject: [PATCH 5/7] fix python function creation and run --- lib/ServerlessFunction.js | 17 ++++++++++------- lib/actions/FunctionRunLambdaPython2.js | 4 ++-- lib/templates/nodejs/handler.js | 2 +- lib/templates/python2.7/handler.py | 4 ++-- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/lib/ServerlessFunction.js b/lib/ServerlessFunction.js index 1a25be3cf..930b6c6ad 100644 --- a/lib/ServerlessFunction.js +++ b/lib/ServerlessFunction.js @@ -338,7 +338,9 @@ class ServerlessFunction { _create() { return fs.mkdirAsync(this._config.fullPath).then(() => { - let writeDeferred = []; + let writeDeferred = [], + subFolderLevel = this._config.sPath.split('/').length - 1, + fnRootPath = _.repeat('../', subFolderLevel); writeDeferred.push(SUtils.writeFile(path.join(this._config.fullPath, 'event.json'), '{}')); @@ -346,16 +348,17 @@ class ServerlessFunction { writeDeferred.push( fs.readFileAsync(path.join(this._S.config.serverlessPath, 'templates', 'nodejs', 'handler.js')) .then((template) => { - let subFolderLevel = this._config.sPath.split('/').length - 1, - libPath = _.repeat('../', subFolderLevel) + 'lib', - handlerJs = _.template(template)({libPath: libPath}); - - return SUtils.writeFile(path.join(this._config.fullPath, 'handler.js'), handlerJs) + let handler = _.template(template)({fnRootPath: fnRootPath}); + return SUtils.writeFile(path.join(this._config.fullPath, 'handler.js'), handler); }) ) } else if (this.getRuntime() === 'python2.7') { writeDeferred.push( - SUtils.writeFile(path.join(this._config.fullPath, 'handler.py'), fs.readFileSync(path.join(this._S.config.serverlessPath, 'templates', 'python2.7', 'handler.py'))) + fs.readFileAsync(path.join(this._S.config.serverlessPath, 'templates', 'python2.7', 'handler.py')) + .then((template) => { + let handler = _.template(template)({fnRootPath: fnRootPath}); + return SUtils.writeFile(path.join(this._config.fullPath, 'handler.py'), handler); + }) ) } return BbPromise.all(writeDeferred); diff --git a/lib/actions/FunctionRunLambdaPython2.js b/lib/actions/FunctionRunLambdaPython2.js index 4f9013018..c6a5fac49 100644 --- a/lib/actions/FunctionRunLambdaPython2.js +++ b/lib/actions/FunctionRunLambdaPython2.js @@ -43,8 +43,8 @@ module.exports = function(SPlugin, serverlessPath) { let _this = this; _this.evt = evt; - if (!_this.evt.options.path || _this.evt.options.path.split('/').length != 3) { - return BbPromise.reject(new SError('Invalid function path. Function path should be in this format: component/module/function .')); + if (!_this.evt.options.path || _this.evt.options.path.split('/').length < 2) { + return BbPromise.reject(new SError('Invalid function path. Function path should be in this format: component/function .')); } // Instantiate Classes diff --git a/lib/templates/nodejs/handler.js b/lib/templates/nodejs/handler.js index e54bec421..ff40e228a 100644 --- a/lib/templates/nodejs/handler.js +++ b/lib/templates/nodejs/handler.js @@ -11,7 +11,7 @@ var ServerlessHelpers = require('serverless-helpers-js').loadEnv(); // Require Logic -var lib = require('<%= libPath%>'); +var lib = require('<%= fnRootPath %>lib'); // Lambda Handler module.exports.handler = function(event, context) { diff --git a/lib/templates/python2.7/handler.py b/lib/templates/python2.7/handler.py index ffed02238..fbc16b7c3 100644 --- a/lib/templates/python2.7/handler.py +++ b/lib/templates/python2.7/handler.py @@ -10,8 +10,8 @@ log.setLevel(logging.DEBUG) import sys, os # get this file's directory independent of where it's run from here = os.path.dirname(os.path.realpath(__file__)) -sys.path.append(os.path.join(here, "../../")) -sys.path.append(os.path.join(here, "../../vendored")) +sys.path.append(os.path.join(here, "<%= fnRootPath %>")) +sys.path.append(os.path.join(here, "<%= fnRootPath %>vendored")) # import the shared library, now anything in component/lib/__init__.py can be # referenced as `lib.something` From be4a61b984b9cb284eb9a1a5bf68571d49ccd7ea Mon Sep 17 00:00:00 2001 From: Egor Kislitsyn Date: Mon, 8 Feb 2016 18:23:48 +0700 Subject: [PATCH 6/7] improves FunctionLogs - strip trailing slashes from path --- lib/actions/FunctionLogs.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/actions/FunctionLogs.js b/lib/actions/FunctionLogs.js index 6bb5b03a8..ac535c71e 100644 --- a/lib/actions/FunctionLogs.js +++ b/lib/actions/FunctionLogs.js @@ -118,6 +118,9 @@ module.exports = function(SPlugin, serverlessPath) { this.evt.options.path = [sPath]; } + // strip trailing slashes from path + this.evt.options.path = this.evt.options.path.replace(/\/$/, ""); + this.spinner = SCli.spinner(); this.CWL = require('../utils/aws/CloudWatch')({ From a0fc52deecfd91cda559aca7b6dd98bcefad3bd1 Mon Sep 17 00:00:00 2001 From: Egor Kislitsyn Date: Mon, 8 Feb 2016 18:47:44 +0700 Subject: [PATCH 7/7] fix FunctionRun log output --- lib/actions/FunctionRun.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/lib/actions/FunctionRun.js b/lib/actions/FunctionRun.js index d67f5d442..749a11ed9 100644 --- a/lib/actions/FunctionRun.js +++ b/lib/actions/FunctionRun.js @@ -7,14 +7,10 @@ module.exports = function(SPlugin, serverlessPath) { const path = require('path'), - SUtils = require( path.join( serverlessPath, 'utils' ) ), SError = require(path.join(serverlessPath, 'ServerlessError')), BbPromise = require('bluebird'), chalk = require('chalk'), - awsMisc = require(path.join(serverlessPath, 'utils/aws/Misc')), - fs = require('fs'); - - BbPromise.promisifyAll(fs); + SCli = require( path.join( serverlessPath, 'utils', 'cli')); /** * FunctionRun Class @@ -221,7 +217,7 @@ module.exports = function(SPlugin, serverlessPath) { if (reply.LogResult) { console.log(chalk.gray('--------------------------------------------------------------------')); let logResult = new Buffer(reply.LogResult, 'base64').toString(); - _.each(logResult.split('\n'), (line) => { + logResult.split('\n').forEach( line => { console.log(SCli.formatLambdaLogEvent(line)); }); }