mirror of
https://github.com/serverless/serverless.git
synced 2026-01-18 14:58:43 +00:00
FunctionCreate: start refactoring to only use sPath
This commit is contained in:
parent
055d7b9501
commit
f95d92f720
@ -58,7 +58,6 @@ class Serverless {
|
||||
this.cli = null;
|
||||
this.state = new this.classes.State(this);
|
||||
|
||||
|
||||
// If project
|
||||
if (this.config.projectPath) {
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
const SError = require('./ServerlessError'),
|
||||
SUtils = require('./utils/index'),
|
||||
SCli = require('./utils/cli'),
|
||||
path = require('path'),
|
||||
awsMisc = require('./utils/aws/Misc'),
|
||||
BbPromise = require('bluebird');
|
||||
|
||||
@ -44,6 +45,34 @@ class ServerlessPlugin {
|
||||
return BbPromise.resolve();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sPath From CWD
|
||||
* - Gets the sPath of the cwd, if any.
|
||||
* - Returns false if project root or outside project
|
||||
*/
|
||||
|
||||
getSPathFromCwd(projectPath) {
|
||||
|
||||
let cwd = process.cwd();
|
||||
|
||||
// Check if in project
|
||||
if (cwd.indexOf(projectPath) == -1) return false;
|
||||
|
||||
// Strip project path from cwd
|
||||
cwd = cwd.replace(projectPath, '').split(path.sep);
|
||||
|
||||
// In component
|
||||
if (cwd.length === 2) return cwd[1];
|
||||
// In component subfolder 1
|
||||
if (cwd.length === 3) return cwd[1] + '/' + cwd[2];
|
||||
// In component subfolder 2
|
||||
if (cwd.length === 4) return cwd[1] + '/' + cwd[2] + '/' + cwd[3];
|
||||
// In component subfolder 3
|
||||
if (cwd.length === 5) return cwd[1] + '/' + cwd[2] + '/' + cwd[3] + '/' + cwd[4];
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* CLI: Prompt Input
|
||||
* - Handy CLI Prompt Input function for Plugins
|
||||
@ -202,36 +231,6 @@ class ServerlessPlugin {
|
||||
return results[0].value;
|
||||
});
|
||||
}
|
||||
|
||||
cliPromptSelectComponent(message, component) {
|
||||
|
||||
let _this = this;
|
||||
|
||||
if (component || !_this.S.config.interactive) return BbPromise.resolve(component);
|
||||
|
||||
let componentChoices = Object.keys(_this.S.state.project.components),
|
||||
choices = [];
|
||||
|
||||
if(componentChoices.length === 0) {
|
||||
return BbPromise.reject(new SError('Your project has no components.', SError.errorCodes.UNKNOWN));
|
||||
}
|
||||
|
||||
if(componentChoices.length === 1) return BbPromise.resolve(componentChoices[0]);
|
||||
|
||||
componentChoices.forEach(function(r) {
|
||||
choices.push({
|
||||
key: '',
|
||||
value: r,
|
||||
label: r
|
||||
});
|
||||
});
|
||||
|
||||
return _this.cliPromptSelect(message, choices, false)
|
||||
.then(results => {
|
||||
return results[0].value;
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ServerlessPlugin;
|
||||
|
||||
@ -9,7 +9,6 @@
|
||||
*
|
||||
* Event Options:
|
||||
* - sPath: (String) The relative path of the function from project root
|
||||
* - name: (String) Name of the new function for your existing component
|
||||
*/
|
||||
|
||||
module.exports = function(SPlugin, serverlessPath) {
|
||||
@ -43,13 +42,7 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
usage: serverless function create <function>`,
|
||||
context: 'function',
|
||||
contextAction: 'create',
|
||||
options: [
|
||||
{
|
||||
option: 'name',
|
||||
shortcut: 'n',
|
||||
description: 'The name of your new function'
|
||||
}
|
||||
],
|
||||
options: [],
|
||||
parameters: [
|
||||
{
|
||||
parameter: 'sPath',
|
||||
@ -70,11 +63,14 @@ usage: serverless function create <function>`,
|
||||
let _this = this;
|
||||
_this.evt = evt;
|
||||
|
||||
|
||||
|
||||
return _this._prompt()
|
||||
.bind(_this)
|
||||
.then(_this._validateAndPrepare)
|
||||
.then(_this._validateAndPrepare())
|
||||
.then(_this._createFunctionSkeleton)
|
||||
.then(function() {
|
||||
|
||||
SCli.log('Successfully created function: "' + _this.evt.options.name + '"');
|
||||
|
||||
/**
|
||||
@ -87,7 +83,7 @@ usage: serverless function create <function>`,
|
||||
}
|
||||
|
||||
/**
|
||||
* Prompt sPath & function if they're missing
|
||||
* Prompt component, module & function if they're missing
|
||||
*/
|
||||
|
||||
_prompt() {
|
||||
@ -95,15 +91,12 @@ usage: serverless function create <function>`,
|
||||
let _this = this,
|
||||
overrides = {};
|
||||
|
||||
if (!_this.S.config.interactive) return BbPromise.resolve();
|
||||
|
||||
['name'].forEach(memberVarKey => {
|
||||
overrides[memberVarKey] = _this.evt.options[memberVarKey];
|
||||
});
|
||||
// If non-interactive or sPath exists, skip
|
||||
if (!_this.S.config.interactive || _this.evt.options.sPath) return BbPromise.resolve();
|
||||
|
||||
let prompts = {
|
||||
properties: {
|
||||
name: {
|
||||
function: {
|
||||
description: 'Enter a new function name: '.yellow,
|
||||
message: 'Function name must contain only letters, numbers, hyphens, or underscores.',
|
||||
required: true,
|
||||
@ -116,11 +109,10 @@ usage: serverless function create <function>`,
|
||||
|
||||
return _this.cliPromptInput(prompts, overrides)
|
||||
.then(function(answers) {
|
||||
_this.evt.options.name = answers.name;
|
||||
_this.evt.options.sPath = answers.function;
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Validate and prepare data before creating module
|
||||
*/
|
||||
@ -129,23 +121,10 @@ usage: serverless function create <function>`,
|
||||
|
||||
let _this = this;
|
||||
|
||||
// Validate: check name
|
||||
if (!_this.evt.options.name) {
|
||||
return BbPromise.reject(new SError('name is required.'));
|
||||
}
|
||||
|
||||
// Validate: If interactive and no sPath, check they are in a component, and get sPath
|
||||
if (_this.S.config.interactive && !_this.evt.options.sPath) {
|
||||
|
||||
let cwdArray = process.cwd().split(path.sep);
|
||||
|
||||
if (SUtils.fileExistsSync(path.join(process.cwd(), 's-component.json'))) {
|
||||
_this.evt.options.sPath = cwdArray.splice(cwdArray.length - 1, 1).join('/')
|
||||
} else if (SUtils.fileExistsSync(path.join(process.cwd(), '..', 's-component.json'))) {
|
||||
_this.evt.options.sPath = cwdArray.splice(cwdArray.length - 2, 2).join('/')
|
||||
} else if (SUtils.fileExistsSync(path.join(process.cwd(), '..', '..', 's-component.json'))) {
|
||||
_this.evt.options.sPath = cwdArray.splice(cwdArray.length - 3, 3).join('/')
|
||||
} else {
|
||||
_this.evt.options.sPath = _this.getSPathFromCwd(_this.S.config.projectPath);
|
||||
if (!_this.evt.options.sPath) {
|
||||
return BbPromise.reject(new SError('You must be in a component or two subfolders max in a component to create a function'));
|
||||
}
|
||||
}
|
||||
@ -156,7 +135,7 @@ usage: serverless function create <function>`,
|
||||
}
|
||||
|
||||
// Validate: Don't allow function creation within a function
|
||||
if (SUtils.fileExistsSync(path.join(_this.S.config.projectPath, _this.evt.options.sPath.split('/').join(path.sep), 's-function.json'))) {
|
||||
if (_this.S.state.getFunctions({ paths: [ _this.evt.options.sPath ] }).length) {
|
||||
return BbPromise.reject(new SError('You cannot create a function in another function'));
|
||||
}
|
||||
|
||||
@ -168,7 +147,7 @@ usage: serverless function create <function>`,
|
||||
// If component does not exist in project, throw error
|
||||
if (!_this.S.state.getComponents({ paths: [_this.evt.options.sPath] }).length) {
|
||||
return BbPromise.reject(new SError(
|
||||
'Component does NOT exist in ' + _this.evt.options.sPath,
|
||||
'Component (' + _this.evt.options.sPath.split('/')[0] + ') does not exist in project',
|
||||
SError.errorCodes.INVALID_PROJECT_SERVERLESS
|
||||
));
|
||||
}
|
||||
|
||||
@ -185,9 +185,6 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
// If CLI and no functions targeted, deploy from CWD if Function, otherwise error
|
||||
if (_this.S.cli &&
|
||||
!_this.evt.options.paths.length &&
|
||||
!_this.evt.options.component &&
|
||||
!_this.evt.options.module &&
|
||||
!_this.evt.options.function &&
|
||||
!_this.evt.options.all) {
|
||||
|
||||
if (SUtils.fileExistsSync(path.join(process.cwd(), 's-function.json'))) {
|
||||
|
||||
@ -72,6 +72,11 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
let _this = this;
|
||||
_this.evt = evt;
|
||||
|
||||
// Ensure in component
|
||||
if (!_this.getSPathFromCwd(_this.S.config.projectPath)) {
|
||||
return BbPromise.reject('You must be in a function folder to run a function');
|
||||
}
|
||||
|
||||
// Instantiate Classes
|
||||
_this.project = _this.S.state.project.get();
|
||||
|
||||
@ -83,8 +88,7 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
let moduleName = path.basename(path.join(process.cwd(), '..'));
|
||||
let functionName = path.basename(process.cwd());
|
||||
_this.evt.options.path = componentName + "/" + moduleName + "/" + functionName;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return BbPromise.reject(new SError('Missing required function path param. Run from within a function directory, or add a function path in this format: componentName/moduleName/functionName'));
|
||||
}
|
||||
}
|
||||
@ -100,7 +104,7 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
.then(_this._runByRuntime)
|
||||
.then(function(evt) {
|
||||
|
||||
// delete temp stage/region env var
|
||||
// Delete temp stage/region env var
|
||||
if (this.evt.options.stage && this.evt.options.region) {
|
||||
fs.unlinkSync(path.join(this.S.config.projectPath, this.evt.options.path.split('/')[0], '.env'));
|
||||
}
|
||||
@ -154,7 +158,7 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
_runByRuntime() {
|
||||
|
||||
let _this = this,
|
||||
runtime = _this.S.state.getComponents({"paths": [_this.function._config.component]})[0].runtime
|
||||
runtime = _this.S.state.getComponents({ "paths": [_this.function._config.sPath] })[0].runtime
|
||||
|
||||
let newOptions = {
|
||||
options: {
|
||||
|
||||
@ -14,7 +14,6 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
chalk = require('chalk'),
|
||||
context = require(path.join(serverlessPath, 'utils/context'));
|
||||
|
||||
|
||||
class FunctionRunLambdaNodeJs extends SPlugin {
|
||||
|
||||
constructor(S, config) {
|
||||
@ -48,20 +47,8 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
return BbPromise.reject(new SError('Invalid function path. Function path should be in this format: component/module/function .'));
|
||||
}
|
||||
|
||||
_this.component = _this.evt.options.path.split('/')[0];
|
||||
_this.module = _this.evt.options.path.split('/')[1];
|
||||
_this.function = _this.evt.options.path.split('/')[2];
|
||||
|
||||
|
||||
if (!SUtils.doesFunctionExist(_this.function, _this.component, _this.S.config.projectPath)) {
|
||||
return BbPromise.reject(new SError(
|
||||
'This function path does not exist',
|
||||
SError.errorCodes.INVALID_PROJECT_SERVERLESS
|
||||
));
|
||||
}
|
||||
|
||||
// Instantiate Classes
|
||||
_this.functionData = _this.S.state.getFunctions({ paths: [_this.evt.options.path] })[0];
|
||||
_this.function = _this.S.state.getFunctions({ paths: [_this.evt.options.path] })[0];
|
||||
|
||||
// Prepare result object
|
||||
_this.evt.data.result = { status: false };
|
||||
@ -69,20 +56,19 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
// Run Function
|
||||
return new BbPromise(function(resolve) {
|
||||
|
||||
SCli.log(`Running ${_this.functionData._config.sPath}...`);
|
||||
SCli.log(`Running ${_this.function._config.sPath}...`);
|
||||
|
||||
try {
|
||||
|
||||
// Load function file & handler
|
||||
let functionFile = _this.functionData.handler.split('/').pop().split('.')[0];
|
||||
let functionHandler = _this.functionData.handler.split('/').pop().split('.')[1];
|
||||
let functionPath = path.join(_this.S.config.projectPath, _this.component, _this.module, _this.functionData.name);
|
||||
functionFile = path.join(functionPath, (functionFile + '.js'));
|
||||
let functionFile = _this.function.handler.split('/').pop().split('.')[0];
|
||||
let functionHandler = _this.function.handler.split('/').pop().split('.')[1];
|
||||
functionFile = path.join(_this.function._config.fullPath, (functionFile + '.js'));
|
||||
functionHandler = require(functionFile)[functionHandler];
|
||||
|
||||
// Fire function
|
||||
let functionEvent = SUtils.readAndParseJsonSync(path.join(functionPath, 'event.json'));
|
||||
functionHandler(functionEvent, context(_this.functionData.name, function (err, result) {
|
||||
let functionEvent = SUtils.readAndParseJsonSync(path.join(_this.function._config.fullPath, 'event.json'));
|
||||
functionHandler(functionEvent, context(_this.function.name, function (err, result) {
|
||||
|
||||
SCli.log(`-----------------`);
|
||||
|
||||
|
||||
@ -14,7 +14,6 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
chalk = require('chalk'),
|
||||
context = require(path.join(serverlessPath, 'utils/context'));
|
||||
|
||||
|
||||
class FunctionRunLambdaPython2 extends SPlugin {
|
||||
|
||||
constructor(S, config) {
|
||||
@ -48,19 +47,8 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
return BbPromise.reject(new SError('Invalid function path. Function path should be in this format: component/module/function .'));
|
||||
}
|
||||
|
||||
_this.component = _this.evt.options.path.split('/')[0];
|
||||
_this.module = _this.evt.options.path.split('/')[1];
|
||||
_this.function = _this.evt.options.path.split('/')[2];
|
||||
|
||||
if (!SUtils.doesFunctionExist(_this.function, _this.component, _this.S.config.projectPath)) {
|
||||
return BbPromise.reject(new SError(
|
||||
'This function path does not exist',
|
||||
SError.errorCodes.INVALID_PROJECT_SERVERLESS
|
||||
));
|
||||
}
|
||||
|
||||
// Instantiate Classes
|
||||
_this.functionData = _this.S.state.getFunctions({ paths: [_this.evt.options.path] })[0];
|
||||
_this.function = _this.S.state.getFunctions({ paths: [_this.evt.options.path] })[0];
|
||||
|
||||
// Prepare result object
|
||||
_this.evt.data.result = { status: false };
|
||||
@ -68,25 +56,23 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
// Run Function
|
||||
return new BbPromise(function(resolve) {
|
||||
|
||||
SCli.log(`Running ${_this.functionData._config.sPath}...`);
|
||||
SCli.log(`Running ${_this.function._config.sPath}...`);
|
||||
|
||||
try {
|
||||
|
||||
// Load function file & handler
|
||||
let functionFile = _this.functionData.handler.split('/').pop().split('.')[0];
|
||||
let functionHandler = _this.functionData.handler.split('/').pop().split('.')[1];
|
||||
let functionPath = path.join(_this.S.config.projectPath, _this.component, _this.module, _this.functionData.name);
|
||||
let functionEvent = SUtils.readAndParseJsonSync(path.join(functionPath, 'event.json'));
|
||||
let functionFile = _this.function.handler.split('/').pop().split('.')[0];
|
||||
let functionHandler = _this.function.handler.split('/').pop().split('.')[1];
|
||||
let functionEvent = SUtils.readAndParseJsonSync(path.join(_this.function._config.fullPath, 'event.json'));
|
||||
|
||||
functionFile = path.join(functionPath, (functionFile + '.py'));
|
||||
//functionHandler = require(functionFile)[functionHandler];
|
||||
functionFile = path.join(_this.function._config.fullPath, (functionFile + '.py'));
|
||||
|
||||
var child = spawnSync(
|
||||
"serverless-run-python-handler",
|
||||
[
|
||||
'--event', JSON.stringify(functionEvent),
|
||||
'--handler-path', functionFile,
|
||||
'--handler-function', functionHandler,
|
||||
'--handler-function', functionHandler
|
||||
],
|
||||
{}
|
||||
);
|
||||
|
||||
@ -109,7 +109,7 @@ exports.getProjectPath = function(startDir) {
|
||||
}
|
||||
|
||||
// Check up to 10 parent levels
|
||||
let previous = './',
|
||||
let previous = './',
|
||||
projRootPath = false;
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
|
||||
@ -24,8 +24,8 @@ describe('All Tests', function() {
|
||||
//require('./tests/actions/EnvList');
|
||||
//require('./tests/actions/EnvGet');
|
||||
//require('./tests/actions/EnvSetUnset');
|
||||
require('./tests/actions/ResourcesDeploy');
|
||||
//require('./tests/actions/FunctionRun');
|
||||
//require('./tests/actions/ResourcesDeploy');
|
||||
require('./tests/actions/FunctionRun');
|
||||
//require('./tests/actions/FunctionDeploy');
|
||||
//require('./tests/actions/EndpointDeploy');
|
||||
//require('./tests/actions/ProjectInit');
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user