mirror of
https://github.com/serverless/serverless.git
synced 2026-01-25 15:07:39 +00:00
mergeMerge branch 'Nopik-arch-refactor' into v0.5
This commit is contained in:
commit
c010cdbe4a
@ -7,10 +7,9 @@ let argv = require('minimist')(process.argv.slice(2));
|
||||
if (argv.debug) process.env.DEBUG = '*';
|
||||
|
||||
let S = require('../lib/Serverless'),
|
||||
SUtils = require('../lib/utils/index'),
|
||||
serverless = new S({
|
||||
interactive: typeof process.env.CI !== 'undefined' ? false : true,
|
||||
projectPath: SUtils.getProjectPath(process.cwd())
|
||||
Project = require('../lib/ServerlessProject'),
|
||||
serverless = new S( Project.findProject(process.cwd()), {
|
||||
interactive: typeof process.env.CI !== 'undefined' ? false : true
|
||||
});
|
||||
|
||||
serverless.command(argv);
|
||||
@ -25,7 +25,7 @@ BbPromise.longStackTraces();
|
||||
|
||||
class Serverless {
|
||||
|
||||
constructor(config) {
|
||||
constructor(project, config) {
|
||||
|
||||
// Add version
|
||||
this._version = require('./../package.json').version;
|
||||
@ -36,18 +36,11 @@ class Serverless {
|
||||
interactive: false,
|
||||
awsAdminKeyId: null,
|
||||
awsAdminSecretKey: null,
|
||||
projectPath: null,
|
||||
serverlessPath: __dirname
|
||||
};
|
||||
|
||||
// Add Config Settings
|
||||
this.updateConfig(config);
|
||||
|
||||
// Add Defaults
|
||||
this.actions = {};
|
||||
this.hooks = {};
|
||||
this.commands = {};
|
||||
this.classes = {
|
||||
this.classes = {
|
||||
// TODO: add Stage, Region
|
||||
State: require('./ServerlessState'),
|
||||
Meta: require('./ServerlessMeta'),
|
||||
Project: require('./ServerlessProject'),
|
||||
@ -56,16 +49,26 @@ class Serverless {
|
||||
Endpoint: require('./ServerlessEndpoint'),
|
||||
Event: require('./ServerlessEvent')
|
||||
};
|
||||
|
||||
this.setProject( project );
|
||||
|
||||
// Add Config Settings
|
||||
this.updateConfig(config);
|
||||
|
||||
// Add Defaults
|
||||
this.actions = {};
|
||||
this.hooks = {};
|
||||
this.commands = {};
|
||||
this.cli = null;
|
||||
this.state = new this.classes.State(this);
|
||||
|
||||
// If project
|
||||
if (this.config.projectPath) {
|
||||
if (this.hasProject()) {
|
||||
// TODO: move this to Project class, along with credentials
|
||||
|
||||
// Load Admin ENV information
|
||||
require('dotenv').config({
|
||||
silent: true, // Don't display dotenv load failures for admin.env if we already have the required environment variables
|
||||
path: path.join(this.config.projectPath, 'admin.env')
|
||||
path: path.join(this.getProject().getRootPath(), 'admin.env')
|
||||
});
|
||||
|
||||
this._setCredentials();
|
||||
@ -74,11 +77,27 @@ class Serverless {
|
||||
// Load Plugins: Framework Defaults
|
||||
let defaults = require('./Actions.json');
|
||||
this._loadPlugins(__dirname, defaults.plugins);
|
||||
this.loadProjectPlugins();
|
||||
}
|
||||
|
||||
// Load Plugins: Project
|
||||
if (this.config.projectPath && SUtils.fileExistsSync(path.join(this.config.projectPath, 's-project.json'))) {
|
||||
let projectJson = require(path.join(this.config.projectPath, 's-project.json'));
|
||||
if (projectJson.plugins) this._loadPlugins(this.config.projectPath, projectJson.plugins);
|
||||
getProject() {
|
||||
return this._project;
|
||||
}
|
||||
|
||||
hasProject() {
|
||||
return this._project != undefined;
|
||||
}
|
||||
|
||||
setProject( project ) {
|
||||
if( _.isString( project ) ){
|
||||
project = this.classes.Project.findProject( project );
|
||||
}
|
||||
|
||||
this._project = project;
|
||||
|
||||
if( project != undefined ){
|
||||
// TODO: get rid of this? Seems like responsibility of Serverless and Project classes is too tangled together
|
||||
project.setServerless( this );
|
||||
}
|
||||
}
|
||||
|
||||
@ -139,7 +158,7 @@ class Serverless {
|
||||
options: extend(_this.cli.options, _this.cli.params)
|
||||
};
|
||||
|
||||
if (_this.config.projectPath) return _this.init();
|
||||
if (_this.hasProject()) return _this.init();
|
||||
|
||||
} else {
|
||||
|
||||
@ -220,6 +239,12 @@ class Serverless {
|
||||
this.config = extend(this.config, config);
|
||||
}
|
||||
|
||||
loadProjectPlugins() {
|
||||
if( this.hasProject() ) {
|
||||
this._loadPlugins( this.getProject().getRootPath(), this.getProject().getPlugins() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load Plugins
|
||||
* - @param relDir string path to start from when rel paths are specified
|
||||
@ -316,7 +341,7 @@ class Serverless {
|
||||
}
|
||||
|
||||
// if not in project root and not creating project, throw error
|
||||
if (!this.config.projectPath && _this.cli.context != 'project') {
|
||||
if (!this.hasProject() && _this.cli.context != 'project') {
|
||||
return BbPromise.reject(new SError('This command can only be run inside a Serverless project.'));
|
||||
}
|
||||
|
||||
|
||||
@ -29,10 +29,27 @@ class ServerlessComponent {
|
||||
|
||||
// Default Properties
|
||||
_this.name = _this._config.sPath || 'component' + SUtils.generateShortId(6);
|
||||
_this.runtime = config.runtime || 'nodejs';
|
||||
_this.custom = {};
|
||||
_this.functions = {};
|
||||
_this.templates = {};
|
||||
|
||||
_this.setRuntime( config.runtime || 'nodejs' );
|
||||
}
|
||||
|
||||
getRuntime() {
|
||||
return this._runtime;
|
||||
}
|
||||
|
||||
setRuntime( runtimeName ) {
|
||||
let runtime = SUtils.supportedRuntimes[ runtimeName ];
|
||||
|
||||
if( runtime ) {
|
||||
// TODO: get rid of that set()/get()/_.assign/_.cloneDeep so this can be cleaner
|
||||
this.runtime = runtimeName;
|
||||
this._runtime = new runtime( this._S );
|
||||
} else {
|
||||
throw new SError( `Runtime ${runtimeName} is not supported!` );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -54,8 +71,8 @@ class ServerlessComponent {
|
||||
}
|
||||
|
||||
// Make full path
|
||||
if (this._S.config.projectPath && this._config.sPath) {
|
||||
this._config.fullPath = path.join(this._S.config.projectPath, this._config.sPath);
|
||||
if (this._S.hasProject() && this._config.sPath) {
|
||||
this._config.fullPath = this._S.getProject().getFilePath(this._config.sPath);
|
||||
}
|
||||
}
|
||||
|
||||
@ -87,7 +104,7 @@ class ServerlessComponent {
|
||||
return BbPromise.try(function() {
|
||||
|
||||
// Validate: Check project path is set
|
||||
if (!_this._S.config.projectPath) throw new SError('Component could not be loaded because no project path has been set on Serverless instance');
|
||||
if (!_this._S.hasProject()) throw new SError('Component could not be loaded because no project path has been set on Serverless instance');
|
||||
|
||||
// Validate: Check component exists
|
||||
if (!SUtils.fileExistsSync(path.join(_this._config.fullPath, 's-component.json'))) {
|
||||
@ -155,6 +172,9 @@ class ServerlessComponent {
|
||||
.then(function() {
|
||||
|
||||
// Merge
|
||||
_this.setRuntime( componentJson.runtime );
|
||||
delete componentJson.runtime;
|
||||
|
||||
_.assign(_this, componentJson);
|
||||
return _this;
|
||||
});
|
||||
@ -179,6 +199,9 @@ class ServerlessComponent {
|
||||
}
|
||||
|
||||
// Merge in
|
||||
_this.setRuntime( data.runtime );
|
||||
delete data.runtime;
|
||||
|
||||
_this = _.extend(_this, data);
|
||||
return _this;
|
||||
}
|
||||
@ -210,7 +233,7 @@ class ServerlessComponent {
|
||||
if (!options.stage || !options.region) throw new SError('Both "stage" and "region" params are required');
|
||||
|
||||
// Validate: Check project path is set
|
||||
if (!_this._S.config.projectPath) throw new SError('Component could not be populated because no project path has been set on Serverless instance');
|
||||
if (!_this._S.hasProject()) throw new SError('Component could not be populated because no project path has been set on Serverless instance');
|
||||
|
||||
// Populate
|
||||
let clone = _this.get();
|
||||
@ -249,7 +272,7 @@ class ServerlessComponent {
|
||||
return new BbPromise.try(function() {
|
||||
|
||||
// Validate: Check project path is set
|
||||
if (!_this._S.config.projectPath) throw new SError('Component could not be saved because no project path has been set on Serverless instance');
|
||||
if (!_this._S.hasProject()) throw new SError('Component could not be saved because no project path has been set on Serverless instance');
|
||||
|
||||
// Create if does not exist
|
||||
if (!SUtils.fileExistsSync(path.join(_this._config.fullPath, 's-component.json'))) {
|
||||
@ -298,40 +321,14 @@ class ServerlessComponent {
|
||||
*/
|
||||
|
||||
_create() {
|
||||
let _this = this;
|
||||
|
||||
let _this = this,
|
||||
writeDeferred = [];
|
||||
return BbPromise.try(function() {
|
||||
fs.mkdirSync(_this._config.fullPath);
|
||||
fs.mkdirSync(path.join(_this._config.fullPath, 'lib'));
|
||||
|
||||
return BbPromise.try(function() {
|
||||
|
||||
writeDeferred.push(
|
||||
fs.mkdirSync(_this._config.fullPath),
|
||||
fs.mkdirSync(path.join(_this._config.fullPath, 'lib'))
|
||||
);
|
||||
// Runtime: nodejs
|
||||
if (_this.runtime === 'nodejs') {
|
||||
let packageJsonTemplate = SUtils.readAndParseJsonSync(path.join(_this._S.config.serverlessPath, 'templates', 'nodejs', 'package.json')),
|
||||
libJs = fs.readFileSync(path.join(_this._S.config.serverlessPath, 'templates', 'nodejs', 'index.js'));
|
||||
|
||||
writeDeferred.push(
|
||||
SUtils.writeFile(path.join(_this._config.fullPath, 'lib', 'index.js'), libJs),
|
||||
SUtils.writeFile(path.join(_this._config.fullPath, 'package.json'), JSON.stringify(packageJsonTemplate, null, 2))
|
||||
);
|
||||
} else if (_this.runtime === 'python2.7') {
|
||||
let requirements = fs.readFileSync(path.join(_this._S.config.serverlessPath, 'templates', 'python2.7', 'requirements.txt')),
|
||||
initPy = fs.readFileSync(path.join(_this._S.config.serverlessPath, 'templates', 'python2.7', '__init__.py')),
|
||||
blankInitPy = fs.readFileSync(path.join(_this._S.config.serverlessPath, 'templates', 'python2.7', 'blank__init__.py'));
|
||||
|
||||
writeDeferred.push(
|
||||
fs.mkdirSync(path.join(_this._config.fullPath, 'vendored')),
|
||||
SUtils.writeFile(path.join(_this._config.fullPath, 'lib', '__init__.py'), initPy),
|
||||
SUtils.writeFile(path.join(_this._config.fullPath, 'vendored', '__init__.py'), blankInitPy),
|
||||
SUtils.writeFile(path.join(_this._config.fullPath, 'requirements.txt'), requirements)
|
||||
);
|
||||
}
|
||||
|
||||
return BbPromise.all(writeDeferred);
|
||||
});
|
||||
return( _this.getRuntime().populateComponentFolder( _this._config.fullPath ) );
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -340,7 +337,7 @@ class ServerlessComponent {
|
||||
*/
|
||||
|
||||
getProject() {
|
||||
return this._S.state.project;
|
||||
return this._S.getProject();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -69,11 +69,8 @@ class ServerlessEndpoint {
|
||||
}
|
||||
|
||||
// Make full path
|
||||
if (this._S.config.projectPath && this._config.sPath) {
|
||||
this._config.fullPath = path.join(
|
||||
this._S.config.projectPath,
|
||||
this._config.sPath.split('@')[0].split('/').join(path.sep)
|
||||
);
|
||||
if (this._S.hasProject() && this._config.sPath) {
|
||||
this._config.fullPath = this._S.getProject().getFilePath( this._config.sPath.split('@')[0].split('/').join(path.sep) );
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,7 +87,7 @@ class ServerlessEndpoint {
|
||||
return new BbPromise(function(resolve) {
|
||||
|
||||
// Validate: Check project path is set
|
||||
if (!_this._S.config.projectPath) throw new SError('Endpoint could not be loaded because no project path has been set on Serverless instance');
|
||||
if (!_this._S.hasProject()) throw new SError('Endpoint could not be loaded because no project path has been set on Serverless instance');
|
||||
|
||||
// Validate: Check function exists
|
||||
if (!SUtils.fileExistsSync(path.join(_this._config.fullPath, 's-function.json'))) {
|
||||
@ -152,7 +149,7 @@ class ServerlessEndpoint {
|
||||
if (!options.stage || !options.region) throw new SError('Both "stage" and "region" params are required');
|
||||
|
||||
// Validate: Check project path is set
|
||||
if (!_this._S.config.projectPath) throw new SError('Endpoint could not be populated because no project path has been set on Serverless instance');
|
||||
if (!_this._S.hasProject()) throw new SError('Endpoint could not be populated because no project path has been set on Serverless instance');
|
||||
|
||||
// Populate
|
||||
let clone = _this.get();
|
||||
@ -187,7 +184,7 @@ class ServerlessEndpoint {
|
||||
return new BbPromise(function(resolve) {
|
||||
|
||||
// Validate: Check project path is set
|
||||
if (!_this._S.config.projectPath) throw new SError('Endpoint could not be saved because no project path has been set on Serverless instance');
|
||||
if (!_this._S.hasProject()) throw new SError('Endpoint could not be saved because no project path has been set on Serverless instance');
|
||||
|
||||
// Validate: Check function exists
|
||||
if (!SUtils.fileExistsSync(path.join(_this._config.fullPath, 's-function.json'))) {
|
||||
@ -219,7 +216,7 @@ class ServerlessEndpoint {
|
||||
*/
|
||||
|
||||
getProject() {
|
||||
return this._S.state.project;
|
||||
return this._S.getProject();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -53,9 +53,8 @@ class ServerlessEvent {
|
||||
}
|
||||
|
||||
// Make full path
|
||||
if (this._S.config.projectPath && this._config.sPath) {
|
||||
this._config.fullPath = path.join(
|
||||
this._S.config.projectPath,
|
||||
if (this._S.hasProject() && this._config.sPath) {
|
||||
this._config.fullPath = this._S.getProject().getFilePath(
|
||||
this._config.sPath.split('#')[0].split('/').join(path.sep)
|
||||
);
|
||||
}
|
||||
@ -74,7 +73,7 @@ class ServerlessEvent {
|
||||
return new BbPromise(function(resolve) {
|
||||
|
||||
// Validate: Check project path is set
|
||||
if (!_this._S.config.projectPath) throw new SError('Event could not be loaded because no project path has been set on Serverless instance');
|
||||
if (!_this._S.hasProject()) throw new SError('Event could not be loaded because no project has been set on Serverless instance');
|
||||
|
||||
// Validate: Check function exists
|
||||
if (!SUtils.fileExistsSync(path.join(_this._config.fullPath, 's-function.json'))) {
|
||||
@ -135,8 +134,8 @@ class ServerlessEvent {
|
||||
// Validate: Check Stage & Region
|
||||
if (!options.stage || !options.region) throw new SError('Both "stage" and "region" params are required');
|
||||
|
||||
// Validate: Check project path is set
|
||||
if (!_this._S.config.projectPath) throw new SError('Event could not be populated because no project path has been set on Serverless instance');
|
||||
// Validate: Check project is set
|
||||
if (!_this._S.hasProject()) throw new SError('Event could not be populated because no project has been set on Serverless instance');
|
||||
|
||||
// Populate
|
||||
let clone = _this.get();
|
||||
@ -171,7 +170,7 @@ class ServerlessEvent {
|
||||
return new BbPromise(function(resolve) {
|
||||
|
||||
// Validate: Check project path is set
|
||||
if (!_this._S.config.projectPath) throw new SError('Event could not be saved because no project path has been set on Serverless instance');
|
||||
if (!_this._S.hasProject()) throw new SError('Event could not be saved because no project has been set on Serverless instance');
|
||||
|
||||
// Validate: Check function exists
|
||||
if (!SUtils.fileExistsSync(path.join(_this._config.fullPath, 's-function.json'))) {
|
||||
|
||||
@ -103,8 +103,8 @@ class ServerlessFunction {
|
||||
}
|
||||
|
||||
// Make full path
|
||||
if (this._S.config.projectPath && this._config.sPath) {
|
||||
this._config.fullPath = path.join(this._S.config.projectPath, this._config.sPath.split('/').join(path.sep));
|
||||
if (this._S.hasProject() && this._config.sPath) {
|
||||
this._config.fullPath = this._S.getProject().getFilePath( this._config.sPath.split('/').join(path.sep) );
|
||||
}
|
||||
}
|
||||
|
||||
@ -122,7 +122,7 @@ class ServerlessFunction {
|
||||
return BbPromise.try(function() {
|
||||
|
||||
// Validate: Check project path is set
|
||||
if (!_this._S.config.projectPath) throw new SError('Function could not be loaded because no project path has been set on Serverless instance');
|
||||
if (!_this._S.hasProject()) throw new SError('Function could not be loaded because no project path has been set on Serverless instance');
|
||||
|
||||
// Validate: Check function exists
|
||||
if (!SUtils.fileExistsSync(path.join(_this._config.fullPath, 's-function.json'))) {
|
||||
@ -233,15 +233,14 @@ class ServerlessFunction {
|
||||
throw new SError(`Stage and region options are required`);
|
||||
}
|
||||
|
||||
let name = this.getProject().name + '-' + this.getComponent().name;
|
||||
let name = this.getProject().getName() + '-' + this.getComponent().name;
|
||||
|
||||
// Backwards Compatibility Support
|
||||
// TODO: Remove in V1 because will result in breaking change
|
||||
if (this._config.sPath.split('/').length == 3) {
|
||||
|
||||
// Check if s-module.json exists in subfolder
|
||||
if (SUtils.fileExistsSync(path.join(
|
||||
this._S.config.projectPath,
|
||||
if (SUtils.fileExistsSync(this._S.getProject().getFilePath(
|
||||
this._config.sPath.split('/').splice(0, 2).join(path.sep),
|
||||
's-module.json'))) {
|
||||
name = name + '-' + this._config.sPath.split('/')[1];
|
||||
@ -277,7 +276,7 @@ class ServerlessFunction {
|
||||
if (!options.stage || !options.region) throw new SError('Both "stage" and "region" params are required');
|
||||
|
||||
// Validate: Check project path is set
|
||||
if (!_this._S.config.projectPath) throw new SError('Function could not be populated because no project path has been set on Serverless instance');
|
||||
if (!_this._S.hasProject()) throw new SError('Function could not be populated because no project path has been set on Serverless instance');
|
||||
|
||||
// Populate
|
||||
let clone = _this.get();
|
||||
@ -316,7 +315,7 @@ class ServerlessFunction {
|
||||
return new BbPromise.try(function() {
|
||||
|
||||
// Validate: Check project path is set
|
||||
if (!_this._S.config.projectPath) throw new SError('Function could not be saved because no project path has been set on Serverless instance');
|
||||
if (!_this._S.hasProject()) throw new SError('Function could not be saved because no project path has been set on Serverless instance');
|
||||
|
||||
// Create if does not exist
|
||||
if (!SUtils.fileExistsSync(path.join(_this._config.fullPath, 's-function.json'))) {
|
||||
@ -373,31 +372,13 @@ class ServerlessFunction {
|
||||
_create() {
|
||||
|
||||
return fs.mkdirAsync(this._config.fullPath).then(() => {
|
||||
let writeDeferred = [],
|
||||
subFolderLevel = this._config.sPath.split('/').length - 1,
|
||||
let subFolderLevel = this._config.sPath.split('/').length - 1,
|
||||
fnRootPath = _.repeat('../', subFolderLevel);
|
||||
|
||||
writeDeferred.push(SUtils.writeFile(path.join(this._config.fullPath, 'event.json'), '{}'));
|
||||
|
||||
if (this.getRuntime() === 'nodejs') {
|
||||
writeDeferred.push(
|
||||
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') {
|
||||
writeDeferred.push(
|
||||
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);
|
||||
|
||||
return BbPromise.all([
|
||||
SUtils.writeFile(path.join(this._config.fullPath, 'event.json'), '{}'),
|
||||
this.getRuntime().populateFunctionFolder( fnRootPath, this._config.fullPath )
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
||||
@ -405,7 +386,7 @@ class ServerlessFunction {
|
||||
let _this = this;
|
||||
let component = _this._S.state.getComponents({ paths: [_this._config.sPath] })[0];
|
||||
if (!component) throw new SError('The component containing runtime information for this function could not be found');
|
||||
return component.runtime;
|
||||
return component.getRuntime();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -414,7 +395,7 @@ class ServerlessFunction {
|
||||
*/
|
||||
|
||||
getProject() {
|
||||
return this._S.state.project;
|
||||
return this._S.getProject();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -16,7 +16,6 @@ class ServerlessMeta
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* - options.projectPath: absolute path to project
|
||||
*/
|
||||
|
||||
constructor(Serverless) {
|
||||
@ -40,27 +39,25 @@ class ServerlessMeta
|
||||
return BbPromise.try(function() {
|
||||
|
||||
// Validate: Check project path is set
|
||||
if (!_this._S.config.projectPath) throw new SError('No project path has been set on Serverless instance');
|
||||
if (!_this._S.hasProject()) throw new SError('No project path has been set on Serverless instance');
|
||||
|
||||
// Validate: Check variables exist
|
||||
if (SUtils.dirExistsSync(path.join(_this._S.config.projectPath, '_meta', 'variables'))) {
|
||||
if (SUtils.dirExistsSync(_this._S.getProject().getFilePath('_meta', 'variables'))) {
|
||||
|
||||
let variableFiles = fs.readdirSync(path.join(_this._S.config.projectPath, '_meta', 'variables'));
|
||||
let variableFiles = fs.readdirSync(_this._S.getProject().getFilePath('_meta', 'variables'));
|
||||
|
||||
for (let i = 0; i < variableFiles.length; i++) {
|
||||
|
||||
// Skip unrelated and hidden files
|
||||
if (!variableFiles[i] || variableFiles[i].charAt(0) === '.' || variableFiles[i].indexOf('s-variables') == -1) continue;
|
||||
|
||||
let variableFile = SUtils.readAndParseJsonSync(path.join(_this._S.config.projectPath, '_meta', 'variables', variableFiles[i]));
|
||||
|
||||
// Parse file name to get stage/region
|
||||
let file = variableFiles[i].replace('s-variables-', '').replace('.json', '');
|
||||
|
||||
if (file === 'common') {
|
||||
|
||||
// Set Common variables
|
||||
_this.variables = SUtils.readAndParseJsonSync(path.join(_this._S.config.projectPath, '_meta', 'variables', variableFiles[i]));
|
||||
_this.variables = SUtils.readAndParseJsonSync(_this._S.getProject().getFilePath('_meta', 'variables', variableFiles[i]));
|
||||
|
||||
} else {
|
||||
|
||||
@ -74,7 +71,7 @@ class ServerlessMeta
|
||||
if (file.length === 1) {
|
||||
|
||||
// Set Stage Variables
|
||||
_this.stages[file[0]].variables = SUtils.readAndParseJsonSync(path.join(_this._S.config.projectPath, '_meta', 'variables', variableFiles[i]));
|
||||
_this.stages[file[0]].variables = SUtils.readAndParseJsonSync(_this._S.getProject().getFilePath('_meta', 'variables', variableFiles[i]));
|
||||
|
||||
} else if (file.length === 2) {
|
||||
|
||||
@ -85,7 +82,7 @@ class ServerlessMeta
|
||||
if (file[1] === 'euwest1') region = 'eu-west-1';
|
||||
if (file[1] === 'apnortheast1') region = 'ap-northeast-1';
|
||||
if (!_this.stages[file[0]].regions[region]) _this.stages[file[0]].regions[region] = {
|
||||
variables: SUtils.readAndParseJsonSync(path.join(_this._S.config.projectPath, '_meta', 'variables', variableFiles[i]))
|
||||
variables: SUtils.readAndParseJsonSync(_this._S.getProject().getFilePath('_meta', 'variables', variableFiles[i]))
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -154,25 +151,25 @@ class ServerlessMeta
|
||||
return BbPromise.try(function() {
|
||||
|
||||
// Validate: Check project path is set
|
||||
if (!_this._S.config.projectPath) throw new SError('Meta could not be saved because no project path has been set on Serverless instance');
|
||||
if (!_this._S.hasProject()) throw new SError('Meta could not be saved because no project path has been set on Serverless instance');
|
||||
|
||||
// Create meta folder if does not exist
|
||||
if (!SUtils.dirExistsSync(path.join(_this._S.config.projectPath, '_meta'))) {
|
||||
fs.mkdirSync(path.join(_this._S.config.projectPath, '_meta'));
|
||||
if (!SUtils.dirExistsSync(_this._S.getProject().getFilePath('_meta'))) {
|
||||
fs.mkdirSync(_this._S.getProject().getFilePath('_meta'));
|
||||
}
|
||||
|
||||
// Create meta/resources folder, if does not exist
|
||||
if (!SUtils.dirExistsSync(path.join(_this._S.config.projectPath, '_meta', 'resources'))) {
|
||||
fs.mkdirSync(path.join(_this._S.config.projectPath, '_meta', 'resources'));
|
||||
if (!SUtils.dirExistsSync(_this._S.getProject().getFilePath('_meta', 'resources'))) {
|
||||
fs.mkdirSync(_this._S.getProject().getFilePath('_meta', 'resources'));
|
||||
}
|
||||
|
||||
// Create meta/variables folder, if does not exist
|
||||
if (!SUtils.dirExistsSync(path.join(_this._S.config.projectPath, '_meta', 'variables'))) {
|
||||
fs.mkdirSync(path.join(_this._S.config.projectPath, '_meta', 'variables'));
|
||||
if (!SUtils.dirExistsSync(_this._S.getProject().getFilePath('_meta', 'variables'))) {
|
||||
fs.mkdirSync(_this._S.getProject().getFilePath('_meta', 'variables'));
|
||||
}
|
||||
|
||||
// Save Common Variables
|
||||
fs.writeFileSync(path.join(_this._S.config.projectPath, '_meta', 'variables', 's-variables-common.json'),
|
||||
fs.writeFileSync(_this._S.getProject().getFilePath('_meta', 'variables', 's-variables-common.json'),
|
||||
JSON.stringify(clone.variables, null, 2));
|
||||
|
||||
// Save Stage & Region Variables
|
||||
@ -181,12 +178,12 @@ class ServerlessMeta
|
||||
let stage = clone.stages[Object.keys(clone.stages)[i]];
|
||||
|
||||
// Save Stage Variables
|
||||
fs.writeFileSync(path.join(_this._S.config.projectPath, '_meta', 'variables', 's-variables-' + Object.keys(clone.stages)[i] + '.json'),
|
||||
fs.writeFileSync(_this._S.getProject().getFilePath('_meta', 'variables', 's-variables-' + Object.keys(clone.stages)[i] + '.json'),
|
||||
JSON.stringify(stage.variables, null, 2));
|
||||
|
||||
// Save Stage Region Variables
|
||||
for (let j = 0; j < Object.keys(stage.regions).length; j++) {
|
||||
fs.writeFileSync(path.join(_this._S.config.projectPath, '_meta', 'variables', 's-variables-' + Object.keys(clone.stages)[i] + '-' + Object.keys(stage.regions)[j].replace(/-/g, '') + '.json'),
|
||||
fs.writeFileSync(_this._S.getProject().getFilePath('_meta', 'variables', 's-variables-' + Object.keys(clone.stages)[i] + '-' + Object.keys(stage.regions)[j].replace(/-/g, '') + '.json'),
|
||||
JSON.stringify(stage.regions[Object.keys(stage.regions)[j]].variables, null, 2));
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,14 +61,11 @@ class ServerlessPlugin {
|
||||
// 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];
|
||||
cwd.shift();
|
||||
|
||||
if( cwd.length > 0 ) {
|
||||
return path.join.apply( path, cwd )
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -19,10 +19,11 @@ class ServerlessProject {
|
||||
* Constructor
|
||||
*/
|
||||
|
||||
constructor(Serverless) {
|
||||
constructor(rootPath) {
|
||||
|
||||
let _this = this;
|
||||
this._S = Serverless;
|
||||
|
||||
_this.rootPath = rootPath;
|
||||
|
||||
// Default properties
|
||||
_this.name = 'serverless' + SUtils.generateShortId(6);
|
||||
@ -38,6 +39,56 @@ class ServerlessProject {
|
||||
_this.resourceVars = [];
|
||||
}
|
||||
|
||||
//TODO: get rid of this?
|
||||
setServerless( Serverless ) {
|
||||
this._S = Serverless;
|
||||
}
|
||||
|
||||
static findProject( startDir ){
|
||||
let jsonName = 's-project.json';
|
||||
|
||||
// Check up to 10 parent levels
|
||||
let previous = '.',
|
||||
project = undefined,
|
||||
i = 10;
|
||||
|
||||
while( i >= 0 ) {
|
||||
let fullPath = path.resolve(startDir, previous);
|
||||
|
||||
if (SUtils.fileExistsSync(path.join(fullPath, jsonName))) {
|
||||
let projectJson = require(path.join(fullPath, jsonName));
|
||||
if (typeof projectJson.name !== 'undefined') {
|
||||
project = new ServerlessProject( fullPath );
|
||||
project.load();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
previous = path.join(previous, '..');
|
||||
i--;
|
||||
}
|
||||
|
||||
return project;
|
||||
}
|
||||
|
||||
getPlugins(){
|
||||
return this.plugins;
|
||||
}
|
||||
|
||||
getRootPath(){
|
||||
return this.rootPath;
|
||||
}
|
||||
|
||||
getFilePath(){
|
||||
let args = _.toArray( arguments );
|
||||
args.unshift( this.getRootPath() );
|
||||
return path.join.apply( path, args );
|
||||
}
|
||||
|
||||
getName(){
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load
|
||||
* - Load from source (i.e., file system)
|
||||
@ -51,19 +102,15 @@ class ServerlessProject {
|
||||
projectContents;
|
||||
|
||||
return BbPromise.try(function () {
|
||||
|
||||
// Validate: Check project path is set
|
||||
if (!_this._S.config.projectPath) throw new SError('Project could not be loaded because no project path has been set on Serverless instance');
|
||||
|
||||
// Validate: Check project exists
|
||||
if (!SUtils.fileExistsSync(path.join(_this._S.config.projectPath, 's-project.json'))) {
|
||||
if (!SUtils.fileExistsSync(_this.getFilePath('s-project.json'))) {
|
||||
throw new SError('Project could not be loaded because it does not exist');
|
||||
}
|
||||
|
||||
projectJson = SUtils.readAndParseJsonSync(path.join(_this._S.config.projectPath, 's-project.json'));
|
||||
projectJson = SUtils.readAndParseJsonSync(_this.getFilePath('s-project.json'));
|
||||
projectJson.components = {};
|
||||
projectJson.templates = {};
|
||||
projectContents = fs.readdirSync(_this._S.config.projectPath);
|
||||
projectContents = fs.readdirSync(_this.getRootPath());
|
||||
|
||||
return projectContents;
|
||||
})
|
||||
@ -71,12 +118,12 @@ class ServerlessProject {
|
||||
|
||||
// If template, load template
|
||||
if (c.indexOf('s-template') !== -1) {
|
||||
projectJson.templates = _.assign(projectJson.templates, SUtils.readAndParseJsonSync(path.join(_this._S.config.projectPath, c)));
|
||||
projectJson.templates = _.assign(projectJson.templates, SUtils.readAndParseJsonSync(_this.getFilePath(c)));
|
||||
return;
|
||||
}
|
||||
|
||||
// If component, load component
|
||||
if (SUtils.fileExistsSync(path.join(_this._S.config.projectPath, c, 's-component.json'))) {
|
||||
if (SUtils.fileExistsSync(_this.getFilePath(c, 's-component.json'))) {
|
||||
|
||||
let component = new _this._S.classes.Component(_this._S, {
|
||||
sPath: c
|
||||
@ -147,9 +194,6 @@ class ServerlessProject {
|
||||
// Validate: Check Stage & Region
|
||||
if (!options.stage || !options.region) throw new SError('Both "stage" and "region" params are required');
|
||||
|
||||
// Validate: Check project path is set
|
||||
if (!_this._S.config.projectPath) throw new SError('Project could not be populated because no project path has been set on Serverless instance');
|
||||
|
||||
// Populate components
|
||||
let clone = _this.get();
|
||||
clone = SUtils.populate(_this._S.state.getMeta(), _this.getTemplates(), clone, options.stage, options.region);
|
||||
@ -322,14 +366,11 @@ class ServerlessProject {
|
||||
let _this = this,
|
||||
files = [];
|
||||
|
||||
// Validate: Check project path is set
|
||||
if (!_this._S.config.projectPath) throw new SError('Project could not be saved because no project path has been set on Serverless instance');
|
||||
|
||||
return new BbPromise.try(function () {
|
||||
|
||||
// If project folder does not exist, create it
|
||||
if (!SUtils.dirExistsSync(path.join(_this._S.config.projectPath))) {
|
||||
fs.mkdirSync(path.join(_this._S.config.projectPath));
|
||||
if (!SUtils.dirExistsSync(_this.getRootPath())) {
|
||||
fs.mkdirSync(_this.getRootPath());
|
||||
}
|
||||
|
||||
// Save all nested components
|
||||
@ -351,7 +392,7 @@ class ServerlessProject {
|
||||
if (clone.templates) delete clone.templates;
|
||||
|
||||
// Save s-project.json
|
||||
files.push(SUtils.writeFile(path.join(_this._S.config.projectPath, 's-project.json'),
|
||||
files.push(SUtils.writeFile(_this.getFilePath('s-project.json'),
|
||||
JSON.stringify(clone, null, 2)));
|
||||
|
||||
// Write files
|
||||
|
||||
55
lib/ServerlessRuntimeBase.js
Normal file
55
lib/ServerlessRuntimeBase.js
Normal file
@ -0,0 +1,55 @@
|
||||
'use strict';
|
||||
|
||||
const SError = require('./ServerlessError'),
|
||||
BbPromise = require('bluebird'),
|
||||
SUtils = require('./utils/index'),
|
||||
fs = require('fs'),
|
||||
path = require('path');
|
||||
|
||||
/**
|
||||
* This is the base class that all Serverless Runtimes should extend.
|
||||
*/
|
||||
|
||||
class ServerlessRuntimeBase {
|
||||
constructor(S, name) {
|
||||
this.S = S;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
populateComponentFolder( componentPath ) {
|
||||
return BbPromise.reject(new SError(`Runtime ${this.name} should implement populateComponentFolder()`));
|
||||
}
|
||||
|
||||
populateFunctionFolder( fnRootPath, fnFullPath ) {
|
||||
return BbPromise.reject(new SError(`Runtime ${this.name} should implement populateFunctionFolder()`));
|
||||
}
|
||||
|
||||
installDepedencies( dir ) {
|
||||
return BbPromise.reject(new SError(`Runtime ${this.name} should implement installDepedencies()`));
|
||||
}
|
||||
|
||||
getFunctionRunActionName() {
|
||||
throw new SError(`Runtime ${this.name} should implement getFunctionRunAction()`);
|
||||
}
|
||||
|
||||
// Helper methods for derived classes
|
||||
|
||||
getName(){
|
||||
return this.name;
|
||||
}
|
||||
|
||||
copyFileFromTemplate(from, to, transform) {
|
||||
from = path.join.apply( path, from );
|
||||
to = path.join.apply( path, to );
|
||||
|
||||
let content = fs.readFileSync(path.join(this.S.config.serverlessPath, 'templates', this.name, from));
|
||||
|
||||
if( transform ){
|
||||
content = transform( content );
|
||||
}
|
||||
|
||||
SUtils.writeFile(to, content);
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = ServerlessRuntimeBase;
|
||||
40
lib/ServerlessRuntimeNode.js
Normal file
40
lib/ServerlessRuntimeNode.js
Normal file
@ -0,0 +1,40 @@
|
||||
'use strict';
|
||||
|
||||
const SError = require('./ServerlessError'),
|
||||
RuntimeBase = require('./ServerlessRuntimeBase'),
|
||||
SCli = require('./utils/cli'),
|
||||
SUtils = require('./utils/index'),
|
||||
_ = require('lodash'),
|
||||
BbPromise = require('bluebird');
|
||||
|
||||
class ServerlessRuntimeNode extends RuntimeBase {
|
||||
constructor(S) {
|
||||
super( S, 'nodejs' );
|
||||
}
|
||||
|
||||
populateComponentFolder( componentPath ) {
|
||||
BbPromise.all([
|
||||
this.copyFileFromTemplate( [ 'index.js' ], [ componentPath, 'lib', 'index.js' ] ),
|
||||
this.copyFileFromTemplate( [ 'package.json' ], [ componentPath, 'package.json' ] )
|
||||
]);
|
||||
}
|
||||
|
||||
populateFunctionFolder( fnRootPath, fnFullPath ) {
|
||||
this.copyFileFromTemplate( [ 'handler.js' ], [ fnFullPath, 'handler.js' ], function(template){
|
||||
return _.template(template)({fnRootPath: fnRootPath});
|
||||
} );
|
||||
}
|
||||
|
||||
getFunctionRunActionName() {
|
||||
return 'functionRunLambdaNodeJs';
|
||||
}
|
||||
|
||||
installDepedencies( dir ) {
|
||||
SCli.log('Installing "serverless-helpers" for this component via NPM...');
|
||||
SCli.log(`-----------------`);
|
||||
SUtils.npmInstall(this.S.getProject().getFilePath(dir));
|
||||
SCli.log(`-----------------`);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ServerlessRuntimeNode;
|
||||
58
lib/ServerlessRuntimePython27.js
Normal file
58
lib/ServerlessRuntimePython27.js
Normal file
@ -0,0 +1,58 @@
|
||||
'use strict';
|
||||
|
||||
const SError = require('./ServerlessError'),
|
||||
SCli = require('./utils/cli'),
|
||||
RuntimeBase = require('./ServerlessRuntimeBase'),
|
||||
BbPromise = require('bluebird'),
|
||||
path = require('path'),
|
||||
_ = require('lodash'),
|
||||
fs = require('fs');
|
||||
|
||||
/**
|
||||
* Pip install using prefix strategy (not virtualenv), requires a modern `pip` version
|
||||
*/
|
||||
function pipPrefixInstall(requirements, dir) {
|
||||
if (exec(`pip install -t "${dir}" -r "${requirements}"`, { silent: false }).code !== 0) {
|
||||
throw new SError(`Error executing pip install on ${dir}`, SError.errorCodes.UNKNOWN);
|
||||
}
|
||||
|
||||
process.chdir(process.cwd());
|
||||
};
|
||||
|
||||
class ServerlessRuntimePython27 extends RuntimeBase {
|
||||
constructor(S) {
|
||||
super( S, 'python2.7' );
|
||||
}
|
||||
|
||||
populateComponentFolder( componentPath ) {
|
||||
fs.mkdirSync(path.join( componentPath, 'vendored'));
|
||||
|
||||
BbPromise.all([
|
||||
this.copyFileFromTemplate( [ '__init__.py' ], [ componentPath, 'lib', '__init__.py' ]),
|
||||
this.copyFileFromTemplate( [ 'blank__init__.py' ], [ componentPath, 'vendored', '__init__.py' ] ),
|
||||
this.copyFileFromTemplate( [ 'requirements.txt' ], [ componentPath, 'requirements.txt' ] )
|
||||
]);
|
||||
}
|
||||
|
||||
populateFunctionFolder( fnRootPath, fnFullPath ) {
|
||||
this.copyFileFromTemplate( [ 'handler.py' ], [ fnFullPath, 'handler.py' ], function(template){
|
||||
return _.template(template)({fnRootPath: fnRootPath});
|
||||
} );
|
||||
}
|
||||
|
||||
getFunctionRunActionName() {
|
||||
return 'functionRunLambdaPython2';
|
||||
}
|
||||
|
||||
installDepedencies( dir ) {
|
||||
SCli.log("Installing default python dependencies with pip...");
|
||||
SCli.log(`-----------------`);
|
||||
pipPrefixInstall(
|
||||
this.S.getProject().getFilePath( dir, 'requirements.txt'),
|
||||
this.S.getProject().getFilePath( dir, 'vendored')
|
||||
);
|
||||
SCli.log(`-----------------`);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ServerlessRuntimePython27;
|
||||
@ -20,8 +20,6 @@ class ServerlessState {
|
||||
|
||||
this._S = Serverless;
|
||||
this.meta = new this._S.classes.Meta(this._S);
|
||||
this.project = new this._S.classes.Project(this._S);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -34,7 +32,7 @@ class ServerlessState {
|
||||
|
||||
let _this = this;
|
||||
|
||||
return _this.project.load()
|
||||
return _this._S.getProject().load()
|
||||
.then(function() {
|
||||
return _this.meta.load();
|
||||
});
|
||||
@ -49,7 +47,7 @@ class ServerlessState {
|
||||
|
||||
let _this = this;
|
||||
|
||||
return _this.project.save({ deep: true })
|
||||
return _this._S.getProject().save({ deep: true })
|
||||
.then(function() {
|
||||
return _this.meta.save({ deep: true });
|
||||
});
|
||||
@ -62,25 +60,23 @@ class ServerlessState {
|
||||
|
||||
set(data) {
|
||||
this.meta = data.meta ? this.meta.set(data.meta) : this.meta;
|
||||
this.project = data.project ? this.project.set(data.project, { deep: true }) : this.project;
|
||||
this.project = data.project ? this._S.getProject().set(data.project, { deep: true }) : this._S.getProject();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Asset
|
||||
* - Add or replace an asset to the state
|
||||
* - Accepts a class instance of: Project, Component, Function, Endpoint
|
||||
* - Accepts a class instance of: Component, Function, Endpoint
|
||||
*/
|
||||
|
||||
setAsset(data) {
|
||||
if (data instanceof this._S.classes.Project) {
|
||||
this.project = data;
|
||||
} else if (data instanceof this._S.classes.Component) {
|
||||
this.project.components[data.name] = data;
|
||||
if (data instanceof this._S.classes.Component) {
|
||||
this._S.getProject().components[data.name] = data;
|
||||
} else if (data instanceof this._S.classes.Function) {
|
||||
this.project.components[data._config.sPath.split('/')[0]].functions[data._config.sPath] = data;
|
||||
this._S.getProject().components[data._config.sPath.split('/')[0]].functions[data._config.sPath] = data;
|
||||
} else if (data instanceof this._S.classes.Endpoint) {
|
||||
let func = this.project.components[data._config.sPath.split('/')[0]].functions[data._config.sPath.split('@')[0]];
|
||||
let func = this._S.getProject().components[data._config.sPath.split('/')[0]].functions[data._config.sPath.split('@')[0]];
|
||||
let added = false;
|
||||
for (let i = 0; i < func.endpoints.length; i++) {
|
||||
if (func.endpoints[i].path === data.path && func.endpoints[i].method === data.method) {
|
||||
@ -90,7 +86,7 @@ class ServerlessState {
|
||||
}
|
||||
if (!added) func.endpoints.push(data);
|
||||
} else {
|
||||
return new SError('State.setAsset() failed because you did not submit an instance of a Project, Component, Function or Endpoint class.');
|
||||
return new SError('State.setAsset() failed because you did not submit an instance of a Component, Function or Endpoint class.');
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,7 +98,7 @@ class ServerlessState {
|
||||
get() {
|
||||
return {
|
||||
meta: this.meta.get(),
|
||||
project: this.project.get()
|
||||
project: this._S.getProject().get()
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,7 +116,7 @@ class ServerlessState {
|
||||
|
||||
return {
|
||||
meta: this.meta.get(),
|
||||
project: this.project.getPopulated(options)
|
||||
project: this._S.getProject().getPopulated(options)
|
||||
}
|
||||
}
|
||||
|
||||
@ -139,7 +135,7 @@ class ServerlessState {
|
||||
*/
|
||||
|
||||
getProject() {
|
||||
return this.project;
|
||||
return this._S.getProject();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -148,7 +144,7 @@ class ServerlessState {
|
||||
*/
|
||||
|
||||
getResources(options) {
|
||||
return this.project.getResources(options);
|
||||
return this._S.getProject().getResources(options);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -183,8 +179,8 @@ class ServerlessState {
|
||||
foundComponents = [];
|
||||
|
||||
// Get all
|
||||
for (let i = 0; i < Object.keys(_this.project.components).length; i++) {
|
||||
allComponents.push(_this.project.components[Object.keys(_this.project.components)[i]]);
|
||||
for (let i = 0; i < Object.keys(_this._S.getProject().components).length; i++) {
|
||||
allComponents.push(_this._S.getProject().components[Object.keys(_this._S.getProject().components)[i]]);
|
||||
}
|
||||
|
||||
// Default options.paths
|
||||
@ -232,8 +228,8 @@ class ServerlessState {
|
||||
foundFunctions = [];
|
||||
|
||||
// Get all
|
||||
for (let i = 0; i < Object.keys(_this.project.components).length; i++) {
|
||||
let component = _this.project.components[Object.keys(_this.project.components)[i]];
|
||||
for (let i = 0; i < Object.keys(_this._S.getProject().components).length; i++) {
|
||||
let component = _this._S.getProject().components[Object.keys(_this._S.getProject().components)[i]];
|
||||
for (let j = 0; j < Object.keys(component.functions).length; j++) {
|
||||
allFunctions.push(component.functions[Object.keys(component.functions)[j]]);
|
||||
}
|
||||
@ -285,8 +281,8 @@ class ServerlessState {
|
||||
foundEndpoints = [];
|
||||
|
||||
// Get all functions
|
||||
for (let i = 0; i < Object.keys(_this.project.components).length; i++) {
|
||||
let component = _this.project.components[Object.keys(_this.project.components)[i]];
|
||||
for (let i = 0; i < Object.keys(_this._S.getProject().components).length; i++) {
|
||||
let component = _this._S.getProject().components[Object.keys(_this._S.getProject().components)[i]];
|
||||
if (!component.functions) continue;
|
||||
for (let k = 0; k < Object.keys(component.functions).length; k++) {
|
||||
let func = component.functions[Object.keys(component.functions)[k]];
|
||||
|
||||
@ -116,7 +116,7 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
|
||||
// Instantiate Classes
|
||||
_this.meta = _this.S.state.getMeta();
|
||||
_this.project = _this.S.state.getProject();
|
||||
_this.project = _this.S.getProject();
|
||||
_this.function = _this.S.state.getFunctions({ paths: [_this.evt.options.path] })[0];
|
||||
|
||||
// Set default function name
|
||||
@ -225,7 +225,7 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
FunctionName: _this.functionName, /* required */
|
||||
Handler: _this.function.handler, /* required */
|
||||
Role: _this.function.customRole ? _this.function.customRole : _this.meta.stages[_this.evt.options.stage].regions[_this.evt.options.region].variables.iamRoleArnLambda, /* required */
|
||||
Runtime: _this.function.getRuntime(), /* required */
|
||||
Runtime: _this.function.getRuntime().getName(), /* required */
|
||||
Description: 'Serverless Lambda function for project: ' + _this.project.name,
|
||||
MemorySize: _this.function.memorySize,
|
||||
Publish: true, // Required by Serverless Framework & recommended best practice by AWS
|
||||
|
||||
@ -95,7 +95,7 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
|
||||
// Instantiate classes
|
||||
_this.meta = _this.S.state.getMeta();
|
||||
_this.project = _this.S.state.getProject();
|
||||
_this.project = _this.S.getProject();
|
||||
_this.function = _this.S.state.getFunctions({ paths: [_this.evt.options.path] })[0];
|
||||
|
||||
if (!_this.function) BbPromise.reject(new SError(`Function could not be found: ${_this.evt.options.path}`));
|
||||
@ -140,7 +140,7 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
|
||||
// Set Dist Dir
|
||||
let d = new Date();
|
||||
_this.pathDist = path.join(_this.S.config.projectPath, '_meta', '_tmp', _this.function.name + '@' + d.getTime());
|
||||
_this.pathDist = _this.S.getProject().getFilePath('_meta', '_tmp', _this.function.name + '@' + d.getTime());
|
||||
|
||||
// Status
|
||||
SUtils.sDebug(`"${_this.evt.options.stage} - ${_this.evt.options.region} - ${_this.function.name}": Copying in dist dir ${_this.pathDist}`);
|
||||
|
||||
@ -27,8 +27,8 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
|
||||
class ComponentCreate extends SPlugin {
|
||||
|
||||
constructor(S, config) {
|
||||
super(S, config);
|
||||
constructor(S) {
|
||||
super(S);
|
||||
}
|
||||
|
||||
static getName() {
|
||||
@ -152,7 +152,7 @@ usage: serverless component create`,
|
||||
}
|
||||
|
||||
// If component exists in project, throw error
|
||||
if (SUtils.doesComponentExist(this.evt.options.sPath, this.S.config.projectPath)) {
|
||||
if (SUtils.doesComponentExist(this.evt.options.sPath, this.S.getProject().getRootPath())) {
|
||||
return BbPromise.reject(new SError(
|
||||
'Component ' + this.evt.options.sPath + ' already exists',
|
||||
SError.errorCodes.INVALID_PROJECT_SERVERLESS
|
||||
@ -180,23 +180,8 @@ usage: serverless component create`,
|
||||
* Install Component Dependencies
|
||||
*/
|
||||
|
||||
_installComponentDependencies() {
|
||||
let _this = this;
|
||||
if (_this.evt.options.runtime === 'nodejs') {
|
||||
SCli.log('Installing "serverless-helpers" for this component via NPM...');
|
||||
SCli.log(`-----------------`);
|
||||
SUtils.npmInstall(path.join(this.S.config.projectPath, this.evt.options.sPath));
|
||||
SCli.log(`-----------------`);
|
||||
} else if (_this.evt.options.runtime === 'python2.7') {
|
||||
SCli.log("Installing default python dependencies with pip...");
|
||||
SCli.log(`-----------------`);
|
||||
SUtils.pipPrefixInstall(
|
||||
path.join(this.S.config.projectPath, this.evt.options.sPath, 'requirements.txt'),
|
||||
path.join(this.S.config.projectPath, this.evt.options.sPath, 'vendored')
|
||||
);
|
||||
SCli.log(`-----------------`);
|
||||
}
|
||||
return BbPromise.resolve();
|
||||
_installComponentDependencies(component) {
|
||||
return( component.getRuntime().installDepedencies( this.evt.options.sPath ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -113,7 +113,7 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
_this.evt.data.deployedEndpoints = {};
|
||||
|
||||
// Instantiate Classes
|
||||
_this.project = _this.S.state.getProject();
|
||||
_this.project = _this.S.getProject();
|
||||
_this.meta = _this.S.state.getMeta();
|
||||
|
||||
// Flow
|
||||
@ -155,7 +155,7 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
}
|
||||
|
||||
// Get all functions in CWD
|
||||
let sPath = _this.getSPathFromCwd(_this.S.config.projectPath);
|
||||
let sPath = _this.getSPathFromCwd(_this.S.getProject().getRootPath());
|
||||
|
||||
_this.components = _this.S.state.getComponents({
|
||||
paths: sPath ? [sPath] : []
|
||||
|
||||
@ -124,7 +124,7 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
let _this = this;
|
||||
|
||||
// Instantiate Classes
|
||||
_this.project = _this.S.state.getProject();
|
||||
_this.project = _this.S.getProject();
|
||||
_this.meta = _this.S.state.getMeta();
|
||||
|
||||
// If no iamRoleLambda, throw error
|
||||
|
||||
@ -162,7 +162,7 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
let _this = this;
|
||||
|
||||
// Instantiate Classes
|
||||
_this.project = _this.S.state.getProject();
|
||||
_this.project = _this.S.getProject();
|
||||
_this.meta = _this.S.state.getMeta();
|
||||
|
||||
// Set defaults
|
||||
@ -175,7 +175,7 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
!_this.evt.options.all) {
|
||||
|
||||
// Get all functions in CWD
|
||||
let sPath = _this.getSPathFromCwd(_this.S.config.projectPath);
|
||||
let sPath = _this.getSPathFromCwd(_this.S.getProject().getRootPath());
|
||||
|
||||
if (!sPath) {
|
||||
throw new SError(`You must be in a component to deploy. Otherwise, use the command "serverless dash deploy"`);
|
||||
|
||||
@ -168,7 +168,7 @@ usage: serverless env set`,
|
||||
_setEnvVar(){
|
||||
let _this = this;
|
||||
|
||||
return awsMisc.getEnvFiles(this.S, _this.evt.options.region, _this.evt.options.stage)
|
||||
return awsMisc.getEnvFiles(_this.S, _this.evt.options.region, _this.evt.options.stage)
|
||||
.then(envMapsByRegion => {
|
||||
let putEnvQ = [];
|
||||
|
||||
@ -185,7 +185,7 @@ usage: serverless env set`,
|
||||
});
|
||||
|
||||
if (_this.evt.options.stage == 'local') {
|
||||
putEnvQ.push(SUtils.writeFile(path.join(this.S.config.projectPath, '.env'), contents));
|
||||
putEnvQ.push(SUtils.writeFile(_this.S.getProject().getFilePath('.env'), contents));
|
||||
} else {
|
||||
let projectName = _this.S.state.meta.get().variables.project,
|
||||
bucketName = _this.S.state.meta.get().variables.projectBucket,
|
||||
|
||||
@ -176,7 +176,7 @@ usage: serverless env unset`,
|
||||
});
|
||||
|
||||
if (_this.evt.options.stage == 'local') {
|
||||
putEnvQ.push(SUtils.writeFile(path.join(_this.S.config.projectPath, '.env'), contents));
|
||||
putEnvQ.push(SUtils.writeFile(_this.S.getProject().getFilePath('.env'), contents));
|
||||
} else {
|
||||
let projectName = _this.S.state.meta.get().variables.project,
|
||||
bucketName = _this.S.state.meta.get().variables.projectBucket,
|
||||
|
||||
@ -144,7 +144,7 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
let _this = this;
|
||||
|
||||
// Instantiate Classes
|
||||
_this.project = _this.S.state.getProject();
|
||||
_this.project = _this.S.getProject();
|
||||
_this.meta = _this.S.state.getMeta();
|
||||
|
||||
// Set defaults
|
||||
@ -157,7 +157,7 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
!_this.evt.options.all) {
|
||||
|
||||
// Get all functions in CWD
|
||||
let sPath = _this.getSPathFromCwd(_this.S.config.projectPath);
|
||||
let sPath = _this.getSPathFromCwd(_this.S.getProject().getRootPath());
|
||||
|
||||
if (!sPath) {
|
||||
throw new SError(`You must be in a component to deploy events`);
|
||||
|
||||
@ -93,7 +93,7 @@ usage: serverless function create <function>`,
|
||||
if (!_this.S.config.interactive || _this.evt.options.sPath) return BbPromise.resolve();
|
||||
|
||||
// Get sPath
|
||||
_this.evt.options.sPath = _this.getSPathFromCwd(_this.S.config.projectPath);
|
||||
_this.evt.options.sPath = _this.getSPathFromCwd(_this.S.getProject().getRootPath());
|
||||
|
||||
// Validate
|
||||
if (!_this.evt.options.sPath) {
|
||||
@ -129,7 +129,7 @@ usage: serverless function create <function>`,
|
||||
|
||||
// Validate: If interactive and no sPath, check they are in a component, and get sPath
|
||||
if (_this.S.config.interactive && !_this.evt.options.sPath) {
|
||||
_this.evt.options.sPath = _this.getSPathFromCwd(_this.S.config.projectPath);
|
||||
_this.evt.options.sPath = _this.getSPathFromCwd(_this.S.getProject().getRootPath());
|
||||
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'));
|
||||
}
|
||||
@ -163,11 +163,11 @@ usage: serverless function create <function>`,
|
||||
let dir = _this.evt.options.sPath.split('/');
|
||||
dir.pop();
|
||||
let c = dir.shift();
|
||||
if (dir[0] && !SUtils.dirExistsSync(path.join(_this.S.config.projectPath, c, dir[0]))) {
|
||||
fs.mkdirSync(path.join(_this.S.config.projectPath, c, dir[0]));
|
||||
if (dir[0] && !SUtils.dirExistsSync(_this.S.getProject().getFilePath(c, dir[0]))) {
|
||||
fs.mkdirSync(_this.S.getProject().getFilePath(c, dir[0]));
|
||||
}
|
||||
if (dir[1] && !SUtils.dirExistsSync(path.join(_this.S.config.projectPath, c, dir[0], dir[1]))) {
|
||||
fs.mkdirSync(path.join(_this.S.config.projectPath, c, dir[0], dir[1]));
|
||||
if (dir[1] && !SUtils.dirExistsSync(_this.S.getProject().getFilePath(c, dir[0], dir[1]))) {
|
||||
fs.mkdirSync(_this.S.getProject().getFilePath(c, dir[0], dir[1]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -172,7 +172,7 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
_this.evt.options.aliasFunction = _this.evt.options.aliasFunction ? _this.evt.options.aliasFunction : null;
|
||||
|
||||
// Instantiate Classes
|
||||
_this.project = _this.S.state.getProject();
|
||||
_this.project = _this.S.getProject();
|
||||
_this.meta = _this.S.state.getMeta();
|
||||
|
||||
// Set Deploy Regions
|
||||
@ -187,7 +187,7 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
!_this.evt.options.all) {
|
||||
|
||||
// Get all functions in CWD
|
||||
let sPath = _this.getSPathFromCwd(_this.S.config.projectPath);
|
||||
let sPath = _this.getSPathFromCwd(_this.S.getProject().getRootPath());
|
||||
|
||||
if (!sPath) {
|
||||
throw new SError(`You must be in a component or function folder to deploy. Otherwise, use the command "serverless dash deploy"`);
|
||||
@ -211,8 +211,8 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
}
|
||||
|
||||
// Ensure tmp folder exists in _meta
|
||||
if (!SUtils.dirExistsSync(path.join(_this.S.config.projectPath, '_meta', '_tmp'))) {
|
||||
fs.mkdirSync(path.join(_this.S.config.projectPath, '_meta', '_tmp'));
|
||||
if (!SUtils.dirExistsSync(_this.S.getProject().getFilePath('_meta', '_tmp'))) {
|
||||
fs.mkdirSync(_this.S.getProject().getFilePath('_meta', '_tmp'));
|
||||
}
|
||||
|
||||
return BbPromise.resolve();
|
||||
|
||||
@ -111,7 +111,7 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
// If CLI and path is not specified, deploy from CWD if Function
|
||||
if (this.S.cli && !this.evt.options.path) {
|
||||
// Get all functions in CWD
|
||||
let sPath = this.getSPathFromCwd(this.S.config.projectPath);
|
||||
let sPath = this.getSPathFromCwd(this.S.getProject().getRootPath());
|
||||
if (!sPath) {
|
||||
throw new SError(`You must be in a function folder to run it`);
|
||||
}
|
||||
|
||||
@ -102,12 +102,12 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
let _this = this;
|
||||
|
||||
// Instantiate Classes
|
||||
_this.project = _this.S.state.project.get();
|
||||
_this.project = _this.S.getProject().get();
|
||||
|
||||
// If CLI and path is not specified, deploy from CWD if Function
|
||||
if (_this.S.cli && !_this.evt.options.path) {
|
||||
// Get all functions in CWD
|
||||
let sPath = _this.getSPathFromCwd(_this.S.config.projectPath);
|
||||
let sPath = _this.getSPathFromCwd(_this.S.getProject().getRootPath());
|
||||
if (!sPath || sPath.split('/').length == 1) {
|
||||
return BbPromise.reject(new SError(`You must be in a function folder to run it`));
|
||||
}
|
||||
@ -136,7 +136,7 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
_runLocal() {
|
||||
|
||||
let _this = this,
|
||||
runtime = _this.function.getComponent().runtime;
|
||||
runtime = _this.function.getComponent().getRuntime();
|
||||
|
||||
let newOptions = {
|
||||
options: {
|
||||
@ -145,15 +145,7 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
};
|
||||
|
||||
return BbPromise.try(function() {
|
||||
|
||||
// Runtime: nodejs
|
||||
if (runtime === 'nodejs') {
|
||||
return _this.S.actions.functionRunLambdaNodeJs(newOptions);
|
||||
} else if (runtime === 'python2.7') {
|
||||
return _this.S.actions.functionRunLambdaPython2(newOptions);
|
||||
} else {
|
||||
return BbPromise.reject(new SError(`Only the Node.js and Python runtimes are supported.`));
|
||||
}
|
||||
return _this.S.actions[ runtime.getFunctionRunActionName() ](newOptions);
|
||||
})
|
||||
.then(function(evt) {
|
||||
_this.evt.data.result = evt.data.result;
|
||||
|
||||
@ -173,10 +173,10 @@ usage: serverless module install <github-url>`,
|
||||
}
|
||||
|
||||
_this.evt.data.module = srcModuleJson.name;
|
||||
_this.pathModule = path.join(this.S.config.projectPath, 'back', 'modules', _this.evt.data.module);
|
||||
_this.pathModule = _this.S.getProject().getFilePath('back', 'modules', _this.evt.data.module);
|
||||
|
||||
// if same module name exists, throw error
|
||||
if (SUtils.doesModuleExist(srcModuleJson.name, this.S.config.projectPath)) {
|
||||
if (SUtils.doesModuleExist(srcModuleJson.name, this.S.getProject().getRootPath())) {
|
||||
return BbPromise.reject(new SError(
|
||||
'Module ' + _this.evt.data.module + ' already exists',
|
||||
SError.errorCodes.INVALID_PROJECT_SERVERLESS
|
||||
|
||||
@ -128,7 +128,6 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
* Return EVT
|
||||
*/
|
||||
|
||||
_this.evt.data.projectPath = _this.S.config.projectPath;
|
||||
return _this.evt;
|
||||
});
|
||||
}
|
||||
@ -145,15 +144,11 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
// fixes the double generated domain id bug
|
||||
if (_this.evt.options.name) isName = true;
|
||||
|
||||
// Check if s-project.json exists
|
||||
if (_this.S.config.projectPath && SUtils.fileExistsSync(path.join(_this.S.config.projectPath, 's-project.json'))) {
|
||||
|
||||
// Check if project exists
|
||||
if (_this.S.hasProject()) {
|
||||
// Set temp name
|
||||
let projectJson = SUtils.readAndParseJsonSync(path.join(_this.S.config.projectPath, 's-project.json'));
|
||||
name = _this.evt.options.name ? _this.evt.options.name : (projectJson.name + '-' + SUtils.generateShortId(6)).toLowerCase();
|
||||
|
||||
name = _this.evt.options.name ? _this.evt.options.name : (_this.S.getProject().getName() + '-' + SUtils.generateShortId(6)).toLowerCase();
|
||||
} else {
|
||||
|
||||
// Set temp name
|
||||
name = _this.evt.options.name ? _this.evt.options.name : ('serverless-' + SUtils.generateShortId(6)).toLowerCase();
|
||||
}
|
||||
@ -351,10 +346,9 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
return BbPromise.try(function() {
|
||||
|
||||
// Update Global Serverless Instance
|
||||
if (!_this.S.config.projectPath) {
|
||||
_this.S.updateConfig({
|
||||
projectPath: path.resolve(path.join(path.dirname('.'), _this.evt.options.name))
|
||||
});
|
||||
if( !_this.S.hasProject() ) {
|
||||
let projectPath = path.resolve(path.join(path.dirname('.'), _this.evt.options.name));
|
||||
_this.S.setProject( new _this.S.classes.Project( projectPath ) );
|
||||
}
|
||||
|
||||
// Fill in meta attributes
|
||||
@ -365,18 +359,15 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
_this.meta.variables.notificationEmail = _this.evt.options.notificationEmail;
|
||||
|
||||
// Fill in project attributes
|
||||
_this.project = _this.S.state.getProject();
|
||||
_this.project = _this.S.getProject();
|
||||
_this.project.name = _this.evt.options.name;
|
||||
|
||||
// Create s-resources-cf.json
|
||||
if (!_this.project.cloudFormation && // In case initializing older project w/ cloudFormation property
|
||||
!SUtils.fileExistsSync(
|
||||
path.join(
|
||||
_this.S.config.projectPath,
|
||||
's-resources-cf.json'))) {
|
||||
!SUtils.fileExistsSync( _this.project.getFilePath( 's-resources-cf.json' ))) {
|
||||
files.push(
|
||||
SUtils.writeFile(
|
||||
path.join(_this.S.config.projectPath, 's-resources-cf.json'),
|
||||
_this.project.getFilePath( 's-resources-cf.json' ),
|
||||
JSON.stringify(
|
||||
SUtils.readAndParseJsonSync(path.join(_this.S.config.serverlessPath, 'templates', 's-resources-cf.json')),
|
||||
null, 2)
|
||||
@ -386,6 +377,7 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
// Save State
|
||||
return _this.S.state.save()
|
||||
.then(function() {
|
||||
_this.S.getProject().load();
|
||||
return _this.S.state.load();
|
||||
});
|
||||
})
|
||||
@ -394,31 +386,31 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
// Create other scaffolding
|
||||
|
||||
// If admin.env does not exist, save it
|
||||
if (!SUtils.fileExistsSync(path.join(_this.S.config.projectPath, 'admin.env'))) {
|
||||
if (!SUtils.fileExistsSync(_this.project.getFilePath( 'admin.env' ))) {
|
||||
let adminEnv = 'SERVERLESS_ADMIN_AWS_ACCESS_KEY_ID=' + _this.S.config.awsAdminKeyId + os.EOL
|
||||
+ 'SERVERLESS_ADMIN_AWS_SECRET_ACCESS_KEY=' + _this.S.config.awsAdminSecretKey + os.EOL;
|
||||
files.push(fs.writeFileAsync(path.join(_this.S.config.projectPath, 'admin.env'), adminEnv));
|
||||
files.push(fs.writeFileAsync(_this.project.getFilePath( 'admin.env' ), adminEnv));
|
||||
}
|
||||
|
||||
// If package.json does not exist, save it
|
||||
let packageJson;
|
||||
if (!SUtils.fileExistsSync(path.join(_this.S.config.projectPath, 'package.json'))) {
|
||||
if (!SUtils.fileExistsSync(_this.project.getFilePath( 'package.json' ))) {
|
||||
|
||||
// Prepare new package.json
|
||||
packageJson = SUtils.readAndParseJsonSync(path.join(_this.S.config.serverlessPath, 'templates', 'nodejs', 'package.json'));
|
||||
packageJson.name = _this.project.name;
|
||||
packageJson.name = _this.project.getName();
|
||||
packageJson.description = 'A Serverless Project and its Serverless Plugin dependencies.';
|
||||
packageJson.private = false;
|
||||
packageJson.dependencies = {};
|
||||
if (packageJson.devDependencies) delete packageJson.devDependencies;
|
||||
if (packageJson.keywords) delete packageJson.keywords;
|
||||
files.push(fs.writeFileAsync(path.join(_this.S.config.projectPath, 'package.json'), JSON.stringify(packageJson, null, 2)))
|
||||
files.push(fs.writeFileAsync(_this.project.getFilePath( 'package.json' ), JSON.stringify(packageJson, null, 2)))
|
||||
|
||||
} else {
|
||||
|
||||
// Modify existing package.json
|
||||
packageJson = SUtils.readAndParseJsonSync(path.join(_this.S.config.projectPath, 'package.json'));
|
||||
packageJson.name = _this.project.name;
|
||||
packageJson = SUtils.readAndParseJsonSync(_this.project.getFilePath( 'package.json' ));
|
||||
packageJson.name = _this.project.getName();
|
||||
|
||||
// Delete unnecessary package.json properties, if they exist
|
||||
if (packageJson.readme) delete packageJson.readme;
|
||||
@ -444,25 +436,25 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
if (packageJson._shrinkwrap || packageJson._shrinkwrap === null) delete packageJson._shrinkwrap;
|
||||
if (packageJson._spec) delete packageJson._spec;
|
||||
if (packageJson._where) delete packageJson._where;
|
||||
files.push(fs.writeFileAsync(path.join(_this.S.config.projectPath, 'package.json'), JSON.stringify(packageJson, null, 2)))
|
||||
files.push(fs.writeFileAsync(_this.project.getFilePath( 'package.json' ), JSON.stringify(packageJson, null, 2)))
|
||||
|
||||
}
|
||||
|
||||
// If README.md does not exist, save it
|
||||
if (!SUtils.fileExistsSync(path.join(_this.S.config.projectPath, 'README.md'))) {
|
||||
if (!SUtils.fileExistsSync(_this.project.getFilePath( 'README.md' ))) {
|
||||
let readme = '#' + _this.project.name;
|
||||
files.push(fs.writeFileAsync(path.join(_this.S.config.projectPath, 'README.md'), readme));
|
||||
files.push(fs.writeFileAsync(_this.project.getFilePath( 'README.md' ), readme));
|
||||
}
|
||||
|
||||
// If .gitignore does not exist, save it
|
||||
if (!SUtils.fileExistsSync(path.join(_this.S.config.projectPath, '.gitignore'))) {
|
||||
files.push(fs.writeFileAsync(path.join(_this.S.config.projectPath, '.gitignore'), fs.readFileSync(path.join(_this.S.config.serverlessPath, 'templates', 'gitignore'))));
|
||||
if (!SUtils.fileExistsSync(_this.project.getFilePath( '.gitignore' ))) {
|
||||
files.push(fs.writeFileAsync(_this.project.getFilePath( '.gitignore' ), fs.readFileSync(path.join(_this.S.config.serverlessPath, 'templates', 'gitignore'))));
|
||||
}
|
||||
|
||||
// If .env does not exist, save it
|
||||
if (!SUtils.fileExistsSync(path.join(_this.S.config.projectPath, '.env'))) {
|
||||
if (!SUtils.fileExistsSync(_this.project.getFilePath( '.env' ))) {
|
||||
files.push(SUtils.writeFile(
|
||||
path.join(_this.S.config.projectPath, '.env'),
|
||||
_this.project.getFilePath( '.env' ),
|
||||
'SERVERLESS_STAGE=' + _this.evt.options.stage
|
||||
+ '\nSERVERLESS_DATA_MODEL_STAGE=' + _this.evt.options.stage
|
||||
+ '\nSERVERLESS_PROJECT_NAME=' + _this.project.name
|
||||
@ -496,22 +488,13 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
let _this = this,
|
||||
components = _this.S.state.getComponents();
|
||||
|
||||
return BbPromise.try(function() {
|
||||
|
||||
components.forEach(function (component) {
|
||||
return BbPromise.all(
|
||||
components.map(function (component) {
|
||||
SCli.log(`Installing ${component.runtime} dependencies for component: ${component.name}...`);
|
||||
if (component.runtime === 'nodejs') {
|
||||
SUtils.npmInstall(path.join(_this.S.config.projectPath, component.name));
|
||||
} else if (component.runtime === 'python2.7') {
|
||||
SUtils.pipPrefixInstall(
|
||||
path.join(_this.S.config.projectPath, component.name, 'requirements.txt'),
|
||||
path.join(_this.S.config.projectPath, component.name, 'vendored')
|
||||
);
|
||||
}
|
||||
return BbPromise.resolve();
|
||||
|
||||
});
|
||||
})
|
||||
component.getRuntime().installDepedencies( component.name ); //TODO: shouldnt we use component sPath, in case it is a subfolder?
|
||||
}),
|
||||
{ concurrency: 1 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -261,13 +261,14 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
let _this = this;
|
||||
|
||||
// Update Global Serverless Instance
|
||||
if (!_this.S.config.projectPath) {
|
||||
_this.S.updateConfig({
|
||||
projectPath: path.resolve(path.join(path.dirname('.'), _this.evt.options.name ? _this.evt.options.name : _this.evt.options.project))
|
||||
});
|
||||
if( !_this.S.hasProject() ) {
|
||||
let projectPath = path.resolve(path.join(path.dirname('.'), _this.evt.options.name ? _this.evt.options.name : _this.evt.options.project));
|
||||
let project = new _this.S.classes.Project( projectPath );
|
||||
project.load();
|
||||
_this.S.setProject( project );
|
||||
}
|
||||
|
||||
// Load state again now that the projectPath is set
|
||||
// Load state again now that the project is set
|
||||
return _this.S.state.load()
|
||||
.then(function() {
|
||||
|
||||
|
||||
@ -63,7 +63,7 @@ usage: serverless project remove`,
|
||||
// Flow
|
||||
return this._removeAllStages()
|
||||
.then(() => {
|
||||
let projectName = this.S.state.getProject().name;
|
||||
let projectName = this.S.getProject().getName();
|
||||
|
||||
// Status
|
||||
SCli.log(`Successfully removed project "${projectName}"`);
|
||||
|
||||
@ -217,11 +217,11 @@ usage: serverless region create`,
|
||||
// Create ENV file in new region
|
||||
let envFileContents = `SERVERLESS_STAGE=${this.evt.options.stage}
|
||||
SERVERLESS_DATA_MODEL_STAGE=${this.evt.options.stage}
|
||||
SERVERLESS_PROJECT_NAME=${this.S.state.getProject().name}`;
|
||||
SERVERLESS_PROJECT_NAME=${this.S.getProject().name}`;
|
||||
|
||||
return this.S3.sPutEnvFile(
|
||||
this.S.state.getMeta().variables.projectBucket,
|
||||
this.S.state.getProject().name,
|
||||
this.S.getProject().name,
|
||||
this.evt.options.stage,
|
||||
this.evt.options.region,
|
||||
envFileContents);
|
||||
|
||||
@ -161,7 +161,7 @@ usage: serverless region remove`,
|
||||
_listS3Objects() {
|
||||
SUtils.sDebug("List related S3 objects");
|
||||
|
||||
let prefix = ['serverless', this.S.state.getProject().name, this.evt.options.stage, this.evt.options.region].join('/'),
|
||||
let prefix = ['serverless', this.S.getProject().name, this.evt.options.stage, this.evt.options.region].join('/'),
|
||||
params = {
|
||||
Bucket: this.S.state.getMeta().variables.projectBucket,
|
||||
Prefix: prefix
|
||||
@ -197,7 +197,7 @@ usage: serverless region remove`,
|
||||
|
||||
_removeVariables() {
|
||||
let fileName = `s-variables-${this.evt.options.stage}-${this.evt.options.region.replace(/-/g, '')}.json`;
|
||||
return fs.unlinkAsync(path.join(this.S.config.projectPath, '_meta', 'variables', fileName));
|
||||
return fs.unlinkAsync(this.S.getProject().getFilePath('_meta', 'variables', fileName));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -169,7 +169,7 @@ usage: serverless resources deploy`,
|
||||
|
||||
// Create CloudFormation template in _meta folder
|
||||
return SUtils.writeFile(
|
||||
path.join(_this.S.config.projectPath, '_meta', 'resources', 's-resources-cf-' + _this.evt.options.stage + '-' + replaceall('-', '', _this.evt.options.region) + '.json'),
|
||||
_this.S.getProject().getFilePath('_meta', 'resources', 's-resources-cf-' + _this.evt.options.stage + '-' + replaceall('-', '', _this.evt.options.region) + '.json'),
|
||||
JSON.stringify(_this.cfTemplate, null, 2))
|
||||
|
||||
})
|
||||
@ -212,8 +212,7 @@ usage: serverless resources deploy`,
|
||||
// Upload to S3 Bucket
|
||||
return _this.S3.sPutCfFile(
|
||||
_this.S.state.getMeta().variables.projectBucket,
|
||||
_this.S.config.projectPath,
|
||||
_this.S.state.getProject().name,
|
||||
_this.S.getProject().getName(),
|
||||
_this.evt.options.stage,
|
||||
_this.evt.options.region,
|
||||
_this.cfTemplate
|
||||
@ -222,7 +221,7 @@ usage: serverless resources deploy`,
|
||||
|
||||
// Trigger CF Stack Create/Update
|
||||
return _this.CF.sCreateOrUpdateResourcesStack(
|
||||
_this.S.state.getProject().name,
|
||||
_this.S.getProject().getName(),
|
||||
_this.evt.options.stage,
|
||||
_this.evt.options.region,
|
||||
regionVars.resourcesStackName ? regionVars.resourcesStackName : null,
|
||||
|
||||
@ -159,8 +159,7 @@ usage: serverless resources remove`,
|
||||
region = _this.evt.options.region,
|
||||
regionVars = _this.S.state.getMeta().stages[stage].regions[region].variables,
|
||||
projectBucket = _this.S.state.getMeta().variables.projectBucket,
|
||||
projectPath = _this.S.config.projectPath,
|
||||
projectName = _this.S.state.getProject().name;
|
||||
projectName = _this.S.getProject().getName();
|
||||
|
||||
// Config AWS Services
|
||||
let awsConfig = {
|
||||
@ -184,7 +183,7 @@ usage: serverless resources remove`,
|
||||
|
||||
let removeLocalResourceFile = function() {
|
||||
let fileName = `s-resources-cf-${stage}-${region.replace(/-/g, '')}.json`;
|
||||
let resourcesLocalFilePath = path.join(projectPath, '_meta', 'resources', fileName);
|
||||
let resourcesLocalFilePath = _this.S.getProject().getFilePath('_meta', 'resources', fileName);
|
||||
|
||||
if (SUtils.fileExistsSync(resourcesLocalFilePath)) {
|
||||
SUtils.sDebug(`Removing resources file "${fileName}"`);
|
||||
|
||||
@ -123,7 +123,7 @@ usage: serverless stage remove`,
|
||||
|
||||
_removeVariables() {
|
||||
let fileName = `s-variables-${this.evt.options.stage}.json`;
|
||||
return fs.unlinkAsync(path.join(this.S.config.projectPath, '_meta', 'variables', fileName));
|
||||
return fs.unlinkAsync(this.S.getProject().getFilePath('_meta', 'variables', fileName));
|
||||
}
|
||||
|
||||
_removeMeta() {
|
||||
|
||||
@ -121,7 +121,7 @@ module.exports.getEnvFileAsMap = function(Serverless, region, stage) {
|
||||
let deferred;
|
||||
|
||||
if (stage == 'local') {
|
||||
deferred = Promise.resolve(fs.readFileSync(path.join(Serverless.config.projectPath, '.env')));
|
||||
deferred = Promise.resolve(fs.readFileSync(Serverless.project.getFilePath( '.env' )));
|
||||
} else {
|
||||
let projectName = Serverless.state.meta.get().variables.project,
|
||||
bucketName = Serverless.state.meta.get().variables.projectBucket,
|
||||
|
||||
@ -159,13 +159,12 @@ module.exports = function(config) {
|
||||
* Put CF File On S3
|
||||
*/
|
||||
|
||||
S3.sPutCfFile = function(bucketName, projectPath, projectName, stage, region, cfTemplate) {
|
||||
S3.sPutCfFile = function(bucketName, projectName, stage, region, cfTemplate) {
|
||||
|
||||
// Set S3 Config To Project Bucket
|
||||
S3.sSetProjectBucketConfig(bucketName);
|
||||
|
||||
let d = new Date(),
|
||||
cfPath = path.join(projectPath, 'meta', 'private', 'resources', 's-resources-cf.json'),
|
||||
key = ['serverless', projectName, stage, region, 'resources/' + 's-resources-cf'].join('/') + '@' + d.getTime() + '.json',
|
||||
params = {
|
||||
Bucket: bucketName,
|
||||
|
||||
@ -25,14 +25,8 @@ BbPromise.promisifyAll(fs);
|
||||
*/
|
||||
|
||||
module.exports.supportedRuntimes = {
|
||||
"nodejs": {
|
||||
defaultPkgMgr: 'npm',
|
||||
validPkgMgrs: ['npm']
|
||||
},
|
||||
"python2.7": {
|
||||
defaultPkgMgr: 'pip',
|
||||
validPkgMgrs: ['pip']
|
||||
}
|
||||
"nodejs": require('../ServerlessRuntimeNode'),
|
||||
"python2.7": require('../ServerlessRuntimePython27')
|
||||
};
|
||||
|
||||
/**
|
||||
@ -92,42 +86,6 @@ exports.parseSPath = function(sPath) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get Project Path
|
||||
* - Returns path string
|
||||
*/
|
||||
|
||||
exports.getProjectPath = function(startDir) {
|
||||
|
||||
let _this = this;
|
||||
|
||||
// Check if startDir is root
|
||||
if (_this.fileExistsSync(path.join(startDir, 's-project.json'))) {
|
||||
|
||||
let serverlessJsonInDir = require(path.join(startDir, 's-project.json'));
|
||||
if (typeof serverlessJsonInDir.name !== 'undefined') return path.resolve(startDir);
|
||||
}
|
||||
|
||||
// Check up to 10 parent levels
|
||||
let previous = './',
|
||||
projRootPath = false;
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
previous = path.join(previous, '../');
|
||||
let fullPath = path.resolve(startDir, previous);
|
||||
|
||||
if (_this.fileExistsSync(path.join(fullPath, 's-project.json'))) {
|
||||
let serverlessJson = require(path.join(fullPath, 's-project.json'));
|
||||
if (typeof serverlessJson.name !== 'undefined') {
|
||||
projRootPath = fullPath;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return projRootPath;
|
||||
};
|
||||
|
||||
/**
|
||||
* Read Recursively
|
||||
*/
|
||||
@ -436,6 +394,8 @@ exports.endsWith = function(str, suffix) {
|
||||
/**
|
||||
* NPM Install
|
||||
* - Programatically install NPM dependencies
|
||||
*
|
||||
* This function is here only for purpose of running testsuite.
|
||||
*/
|
||||
|
||||
exports.npmInstall = function(dir) {
|
||||
@ -448,17 +408,6 @@ exports.npmInstall = function(dir) {
|
||||
process.chdir(process.cwd());
|
||||
};
|
||||
|
||||
/**
|
||||
* Pip install using prefix strategy (not virtualenv), requires a modern `pip` version
|
||||
*/
|
||||
exports.pipPrefixInstall = function(requirements, dir) {
|
||||
if (exec(`pip install -t "${dir}" -r "${requirements}"`, { silent: false }).code !== 0) {
|
||||
throw new SError(`Error executing pip install on ${dir}`, SError.errorCodes.UNKNOWN);
|
||||
}
|
||||
|
||||
process.chdir(process.cwd());
|
||||
};
|
||||
|
||||
/**
|
||||
* Write to console.log if process.env.DEBUG is true
|
||||
* - If we ever want to get more complicated with log levels we should use winston
|
||||
|
||||
@ -34,9 +34,8 @@ describe('Test action: Component Create', function() {
|
||||
|
||||
process.chdir(projPath);
|
||||
|
||||
serverless = new Serverless({
|
||||
interactive: false,
|
||||
projectPath: projPath
|
||||
serverless = new Serverless( projPath, {
|
||||
interactive: false
|
||||
});
|
||||
|
||||
return serverless.state.load().then(function() {
|
||||
|
||||
@ -48,11 +48,10 @@ describe('Test Action: Endpoint Deploy', function() {
|
||||
|
||||
process.chdir(projPath);
|
||||
|
||||
serverless = new Serverless({
|
||||
serverless = new Serverless( projPath, {
|
||||
interactive: false,
|
||||
awsAdminKeyId: config.awsAdminKeyId,
|
||||
awsAdminSecretKey: config.awsAdminSecretKey,
|
||||
projectPath: projPath
|
||||
awsAdminSecretKey: config.awsAdminSecretKey
|
||||
});
|
||||
|
||||
return serverless.state.load().then(function() {
|
||||
|
||||
@ -36,11 +36,10 @@ describe('Test Action: Env Get', function() {
|
||||
|
||||
process.chdir(projPath);
|
||||
|
||||
serverless = new Serverless({
|
||||
serverless = new Serverless( projPath, {
|
||||
interactive: false,
|
||||
awsAdminKeyId: config.awsAdminKeyId,
|
||||
awsAdminSecretKey: config.awsAdminSecretKey,
|
||||
projectPath: projPath
|
||||
awsAdminSecretKey: config.awsAdminSecretKey
|
||||
});
|
||||
|
||||
return serverless.state.load().then(function() {
|
||||
|
||||
@ -38,11 +38,10 @@ describe('Test Action: Env List', function() {
|
||||
|
||||
process.chdir(projPath);
|
||||
|
||||
serverless = new Serverless({
|
||||
serverless = new Serverless( projPath, {
|
||||
interactive: false,
|
||||
awsAdminKeyId: config.awsAdminKeyId,
|
||||
awsAdminSecretKey: config.awsAdminSecretKey,
|
||||
projectPath: projPath
|
||||
awsAdminSecretKey: config.awsAdminSecretKey
|
||||
});
|
||||
|
||||
return serverless.state.load().then(function() {
|
||||
|
||||
@ -40,11 +40,10 @@ describe('Test Env Set & Env Unset actions', function() {
|
||||
|
||||
process.chdir(projPath);
|
||||
|
||||
serverless = new Serverless({
|
||||
serverless = new Serverless( projPath, {
|
||||
interactive: false,
|
||||
awsAdminKeyId: config.awsAdminKeyId,
|
||||
awsAdminSecretKey: config.awsAdminSecretKey,
|
||||
projectPath: projPath
|
||||
awsAdminSecretKey: config.awsAdminSecretKey
|
||||
});
|
||||
|
||||
return serverless.state.load().then(function() {
|
||||
|
||||
@ -48,11 +48,10 @@ describe('Test Action: Event Deploy', function() {
|
||||
|
||||
process.chdir(projPath);
|
||||
|
||||
serverless = new Serverless({
|
||||
serverless = new Serverless( projPath, {
|
||||
interactive: false,
|
||||
awsAdminKeyId: config.awsAdminKeyId,
|
||||
awsAdminSecretKey: config.awsAdminSecretKey,
|
||||
projectPath: projPath
|
||||
awsAdminSecretKey: config.awsAdminSecretKey
|
||||
});
|
||||
|
||||
return serverless.state.load().then(function() {
|
||||
|
||||
@ -35,9 +35,8 @@ describe('Test action: Function Create', function() {
|
||||
|
||||
process.chdir(projPath);
|
||||
|
||||
serverless = new Serverless({
|
||||
interactive: false,
|
||||
projectPath: projPath
|
||||
serverless = new Serverless( projPath, {
|
||||
interactive: false
|
||||
});
|
||||
|
||||
return serverless.state.load().then(function() {
|
||||
@ -64,7 +63,7 @@ describe('Test action: Function Create', function() {
|
||||
serverless.actions.functionCreate(evt)
|
||||
.then(function(evt) {
|
||||
validateEvent(evt);
|
||||
let functionJson = utils.readAndParseJsonSync(path.join(serverless.config.projectPath, 'nodejscomponent', 'group1', 'function1', 's-function.json'));
|
||||
let functionJson = utils.readAndParseJsonSync(serverless.getProject().getFilePath( 'nodejscomponent', 'group1', 'function1', 's-function.json'));
|
||||
assert.equal(true, typeof functionJson.name != 'undefined');
|
||||
assert.equal(true, functionJson.endpoints.length);
|
||||
done();
|
||||
|
||||
@ -76,11 +76,10 @@ describe('Test Action: Function Deploy', function() {
|
||||
|
||||
process.chdir(projPath);
|
||||
|
||||
serverless = new Serverless({
|
||||
serverless = new Serverless( projPath, {
|
||||
interactive: false,
|
||||
awsAdminKeyId: config.awsAdminKeyId,
|
||||
awsAdminSecretKey: config.awsAdminSecretKey,
|
||||
projectPath: projPath
|
||||
awsAdminSecretKey: config.awsAdminSecretKey
|
||||
});
|
||||
|
||||
return serverless.state.load().then(function() {
|
||||
|
||||
@ -41,11 +41,10 @@ describe('Test action: Function Logs', function() {
|
||||
.then(projPath => {
|
||||
process.chdir(projPath);
|
||||
|
||||
serverless = new Serverless({
|
||||
serverless = new Serverless( projPath, {
|
||||
awsAdminKeyId: config.awsAdminKeyId,
|
||||
awsAdminSecretKey: config.awsAdminSecretKey,
|
||||
interactive: false,
|
||||
projectPath: projPath
|
||||
interactive: false
|
||||
});
|
||||
return serverless.state.load();
|
||||
})
|
||||
|
||||
@ -36,11 +36,10 @@ describe('Test Action: Function Run', function() {
|
||||
|
||||
process.chdir(projPath);
|
||||
|
||||
serverless = new Serverless({
|
||||
serverless = new Serverless( projPath, {
|
||||
interactive: true,
|
||||
awsAdminKeyId: config.awsAdminKeyId,
|
||||
awsAdminSecretKey: config.awsAdminSecretKey,
|
||||
projectPath: projPath
|
||||
awsAdminSecretKey: config.awsAdminSecretKey
|
||||
});
|
||||
|
||||
return serverless.state.load()
|
||||
|
||||
@ -36,9 +36,8 @@ describe('Test action: Module Create', function() {
|
||||
|
||||
process.chdir(projPath);
|
||||
|
||||
serverless = new Serverless({
|
||||
interactive: false,
|
||||
projectPath: projPath
|
||||
serverless = new Serverless( projPath, {
|
||||
interactive: false
|
||||
});
|
||||
|
||||
return serverless.state.load().then(function() {
|
||||
@ -67,7 +66,7 @@ describe('Test action: Module Create', function() {
|
||||
|
||||
serverless.actions.moduleCreate(evt)
|
||||
.then(function(evt) {
|
||||
let functionJson = utils.readAndParseJsonSync(path.join(serverless.config.projectPath, 'nodejscomponent', 'newmodule', 'newfunction', 's-function.json'));
|
||||
let functionJson = utils.readAndParseJsonSync(serverless.getProject().getFilePath( 'nodejscomponent', 'newmodule', 'newfunction', 's-function.json'));
|
||||
assert.equal(true, typeof functionJson.name != 'undefined');
|
||||
assert.equal(true, functionJson.endpoints.length);
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@ let Serverless = require('../../../lib/Serverless'),
|
||||
config = require('../../config');
|
||||
|
||||
// Instantiate
|
||||
let serverless = new Serverless({
|
||||
let serverless = new Serverless( undefined, {
|
||||
interactive: false,
|
||||
awsAdminKeyId: config.awsAdminKeyId,
|
||||
awsAdminSecretKey: config.awsAdminSecretKey
|
||||
|
||||
@ -18,7 +18,7 @@ let Serverless = require('../../../lib/Serverless'),
|
||||
config = require('../../config');
|
||||
|
||||
// Instantiate
|
||||
let serverless = new Serverless({
|
||||
let serverless = new Serverless( undefined, {
|
||||
interactive: false,
|
||||
awsAdminKeyId: config.awsAdminKeyId,
|
||||
awsAdminSecretKey: config.awsAdminSecretKey
|
||||
|
||||
@ -37,11 +37,10 @@ describe('Test Action: Project Remove', function() {
|
||||
this.timeout(0);
|
||||
process.chdir(projPath); // Ror some weird reason process.chdir adds /private/ before cwd path
|
||||
|
||||
serverless = new Serverless({
|
||||
serverless = new Serverless( projPath, {
|
||||
interactive: false,
|
||||
awsAdminKeyId: config.awsAdminKeyId,
|
||||
awsAdminSecretKey: config.awsAdminSecretKey,
|
||||
projectPath: projPath
|
||||
awsAdminSecretKey: config.awsAdminSecretKey
|
||||
});
|
||||
|
||||
return serverless.state.load().then(function() {
|
||||
|
||||
@ -71,11 +71,10 @@ describe('Test Action: Region Create', function() {
|
||||
this.timeout(0);
|
||||
process.chdir(projPath); // Ror some weird reason process.chdir adds /private/ before cwd path
|
||||
|
||||
serverless = new Serverless({
|
||||
serverless = new Serverless( projPath, {
|
||||
interactive: false,
|
||||
awsAdminKeyId: config.awsAdminKeyId,
|
||||
awsAdminSecretKey: config.awsAdminSecretKey,
|
||||
projectPath: projPath
|
||||
awsAdminSecretKey: config.awsAdminSecretKey
|
||||
});
|
||||
|
||||
return serverless.state.load().then(function() {
|
||||
|
||||
@ -39,11 +39,10 @@ describe('Test action: Resources Deploy', function() {
|
||||
|
||||
process.chdir(projPath);
|
||||
|
||||
serverless = new Serverless({
|
||||
serverless = new Serverless( projPath, {
|
||||
interactive: false,
|
||||
awsAdminKeyId: config.awsAdminKeyId,
|
||||
awsAdminSecretKey: config.awsAdminSecretKey,
|
||||
projectPath: projPath
|
||||
awsAdminSecretKey: config.awsAdminSecretKey
|
||||
});
|
||||
|
||||
return serverless.init()
|
||||
@ -52,7 +51,7 @@ describe('Test action: Resources Deploy', function() {
|
||||
SUtils.sDebug('Adding test bucket resource');
|
||||
|
||||
// Adding new Module resource
|
||||
serverless.state.project.cloudFormation.Resources['testBucket' + (new Date).getTime().toString()] = { "Type" : "AWS::S3::Bucket" };
|
||||
serverless.getProject().cloudFormation.Resources['testBucket' + (new Date).getTime().toString()] = { "Type" : "AWS::S3::Bucket" };
|
||||
|
||||
return serverless.state.save()
|
||||
.then(function() {
|
||||
|
||||
@ -68,11 +68,10 @@ describe('Test Action: Stage Create', function() {
|
||||
this.timeout(0);
|
||||
process.chdir(projPath);
|
||||
|
||||
serverless = new Serverless({
|
||||
serverless = new Serverless( projPath, {
|
||||
interactive: false,
|
||||
awsAdminKeyId: config.awsAdminKeyId,
|
||||
awsAdminSecretKey: config.awsAdminSecretKey,
|
||||
projectPath: projPath
|
||||
awsAdminSecretKey: config.awsAdminSecretKey
|
||||
});
|
||||
|
||||
return serverless.state.load().then(function() {
|
||||
|
||||
@ -81,9 +81,8 @@ describe('Test Default Action With Pre Hook', function() {
|
||||
.then(projPath => {
|
||||
|
||||
process.chdir(projPath);
|
||||
serverless = new Serverless({
|
||||
interactive: false,
|
||||
projectPath: projPath
|
||||
serverless = new Serverless( projPath, {
|
||||
interactive: false
|
||||
});
|
||||
|
||||
serverless.addPlugin(new CustomPlugin(serverless, {}));
|
||||
|
||||
@ -251,7 +251,7 @@ describe('Test Custom Plugin', function() {
|
||||
|
||||
before(function(done) {
|
||||
|
||||
serverless = new Serverless({
|
||||
serverless = new Serverless( undefined, {
|
||||
awsAdminKeyId: '123',
|
||||
awsAdminSecretKey: '123',
|
||||
interactive: false
|
||||
|
||||
@ -26,7 +26,7 @@ let Serverless = require('../../../lib/Serverless'),
|
||||
config = require('../../config');
|
||||
|
||||
|
||||
let serverless = new Serverless({
|
||||
let serverless = new Serverless( undefined, {
|
||||
interactive: false,
|
||||
awsAdminKeyId: config.awsAdminKeyId,
|
||||
awsAdminSecretKey: config.awsAdminSecretKey
|
||||
|
||||
@ -25,9 +25,8 @@ describe('Test Serverless Component Class', function() {
|
||||
process.chdir(projPath);
|
||||
|
||||
// Instantiate Serverless
|
||||
serverless = new Serverless({
|
||||
interactive: false,
|
||||
projectPath: projPath
|
||||
serverless = new Serverless( projPath, {
|
||||
interactive: false
|
||||
});
|
||||
|
||||
return serverless.init()
|
||||
|
||||
@ -24,9 +24,8 @@ describe('Test Serverless Endpoint Class', function() {
|
||||
process.chdir(projPath);
|
||||
|
||||
// Instantiate Serverless
|
||||
serverless = new Serverless({
|
||||
interactive: false,
|
||||
projectPath: projPath
|
||||
serverless = new Serverless( projPath, {
|
||||
interactive: false
|
||||
});
|
||||
|
||||
return serverless.init()
|
||||
|
||||
@ -24,9 +24,8 @@ describe('Test Serverless Function Class', function() {
|
||||
process.chdir(projPath);
|
||||
|
||||
// Instantiate Serverless
|
||||
serverless = new Serverless({
|
||||
interactive: false,
|
||||
projectPath: projPath
|
||||
serverless = new Serverless( projPath, {
|
||||
interactive: false
|
||||
});
|
||||
|
||||
return serverless.init()
|
||||
|
||||
@ -25,16 +25,15 @@ describe('Test Serverless Project Class', function() {
|
||||
process.chdir(projPath);
|
||||
|
||||
// Instantiate Serverless
|
||||
serverless = new Serverless({
|
||||
interactive: false,
|
||||
projectPath: projPath
|
||||
serverless = new Serverless( projPath, {
|
||||
interactive: false
|
||||
});
|
||||
|
||||
return serverless.init()
|
||||
.then(function() {
|
||||
|
||||
// Instantiate Class
|
||||
instance = new serverless.classes.Project(serverless);
|
||||
instance = serverless.getProject();
|
||||
|
||||
done();
|
||||
});
|
||||
@ -107,7 +106,13 @@ describe('Test Serverless Project Class', function() {
|
||||
});
|
||||
|
||||
it('Create new and save', function(done) {
|
||||
let project = new serverless.classes.Project(serverless);
|
||||
// TODO: Project creation is an unholy mess now. It currently is done partially outside of Project class,
|
||||
// split between ServerlessState and Meta classes, ProjectInit action, and ServerlessProject itself.
|
||||
// So, either the code should be moved fully to Project and be tested here (preferred)
|
||||
// or not really tested here. To make this happen we should first remove ServerlessState and ServerlessMeta
|
||||
// classes completely.
|
||||
let project = new serverless.classes.Project(serverless.getProject().getRootPath());
|
||||
project.setServerless( serverless );
|
||||
|
||||
project.save()
|
||||
.then(function(instance) {
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
let Serverless = require('../../../lib/Serverless.js'),
|
||||
Project = require('../../../lib/ServerlessProject'),
|
||||
path = require('path'),
|
||||
utils = require('../../../lib/utils/index'),
|
||||
assert = require('chai').assert,
|
||||
@ -24,9 +25,8 @@ describe('Test Serverless State Class', function() {
|
||||
process.chdir(projPath);
|
||||
|
||||
// Instantiate Serverless
|
||||
serverless = new Serverless({
|
||||
interactive: false,
|
||||
projectPath: projPath
|
||||
serverless = new Serverless( projPath, {
|
||||
interactive: false
|
||||
});
|
||||
|
||||
return serverless.init()
|
||||
@ -73,7 +73,7 @@ describe('Test Serverless State Class', function() {
|
||||
let clone = instance.get();
|
||||
clone.project.name = 'newProject';
|
||||
instance.set(clone);
|
||||
assert.equal(true, instance.project.name === 'newProject');
|
||||
assert.equal(true, instance._S.getProject().name === 'newProject');
|
||||
done();
|
||||
});
|
||||
|
||||
@ -248,9 +248,10 @@ describe('Test Serverless State Class', function() {
|
||||
|
||||
it('Set Assets', function(done) {
|
||||
|
||||
let project = new instance._S.classes.Project(instance._S);
|
||||
project.name = 'testProject';
|
||||
instance.setAsset(project);
|
||||
//TODO
|
||||
//let project = new instance._S.classes.Project(".");
|
||||
//project.name = 'testProject';
|
||||
//instance.setAsset(project);
|
||||
|
||||
let component = new instance._S.classes.Component(instance._S, { sPath: 'testComponent' });
|
||||
component.name = 'testComponent';
|
||||
@ -264,7 +265,8 @@ describe('Test Serverless State Class', function() {
|
||||
endpoint.path = 'test/endpoint';
|
||||
instance.setAsset(endpoint);
|
||||
|
||||
assert.equal(true, instance.project.name === 'testProject');
|
||||
// TODO
|
||||
//assert.equal(true, instance._S.getProject().name === 'testProject');
|
||||
assert.equal(true, typeof instance.project.components[component.name] !== 'undefined');
|
||||
assert.equal(true, typeof instance.project.components[component.name].functions[func._config.sPath] !== 'undefined');
|
||||
assert.equal(true, instance.project.components[component.name].functions[func._config.sPath].endpoints.length > 0);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user