diff --git a/lib/ServerlessFunction.js b/lib/ServerlessFunction.js index e200f85ac..930b6c6ad 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,28 @@ class ServerlessFunction { _create() { - let _this = this; + return fs.mkdirAsync(this._config.fullPath).then(() => { + let writeDeferred = [], + subFolderLevel = this._config.sPath.split('/').length - 1, + fnRootPath = _.repeat('../', subFolderLevel); - return BbPromise.try(function() { + writeDeferred.push(SUtils.writeFile(path.join(this._config.fullPath, 'event.json'), '{}')); - let writeDeferred = []; - - // Runtime: nodejs - writeDeferred.push( - fs.mkdirSync(_this._config.fullPath), - SUtils.writeFile(path.join(_this._config.fullPath, 'event.json'), '{}') - ); - if (_this.getRuntime() === 'nodejs') { + 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 handler = _.template(template)({fnRootPath: fnRootPath}); + return SUtils.writeFile(path.join(this._config.fullPath, 'handler.js'), handler); + }) ) - } 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'))) + 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/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')({ diff --git a/lib/actions/FunctionRun.js b/lib/actions/FunctionRun.js index e4d65e218..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 @@ -113,14 +109,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]; @@ -218,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)); }); } diff --git a/lib/actions/FunctionRunLambdaNodeJs.js b/lib/actions/FunctionRunLambdaNodeJs.js index a0e637fe7..fd2f7c374 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 @@ -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(); 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 fc117e63d..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('../../lib'); +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` 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",