basic new variable system

This commit is contained in:
Eslam A. Hefnawy 2016-08-12 20:12:28 +09:00
parent 2bc3ac38bb
commit 5dafeee388
16 changed files with 367 additions and 1522 deletions

View File

@ -54,7 +54,7 @@ class Serverless {
.then(() => {
// set the provider of the service (so that the PluginManager takes care to
// execute the correct provider specific plugins)
this.pluginManager.setProvider(this.service.provider.name || this.service.provider);
this.pluginManager.setProvider(this.service.provider.name);
// load all plugins
this.pluginManager.loadAllPlugins(this.service.plugins);
@ -62,6 +62,9 @@ class Serverless {
// give the CLI the plugins so that it can print out plugin information
// such as options when the user enters --help
this.cli.setLoadedPlugins(this.pluginManager.getPlugins());
// populate variables after processing options
return this.service.populate(this.pluginManager.cliOptions);
});
}

View File

@ -18,7 +18,7 @@ class Service {
this.defaults = {
stage: 'dev',
region: 'us-east-1',
variableSyntax: null,
variableSyntax: '\\${([a-zA-Z0-9._\\-\\/\\(\\)]+?)}',
};
this.custom = {};
this.plugins = [];
@ -30,9 +30,9 @@ class Service {
if (data) this.update(data);
}
load(opts) {
load(rawOptions) {
const that = this;
const options = opts || {};
const options = rawOptions || {};
options.stage = options.stage || options.s;
options.region = options.region || options.r;
const servicePath = that.serverless.config.servicePath;
@ -50,279 +50,321 @@ class Service {
.join(this.serverless.config.servicePath, 'serverless.yaml');
}
let serverlessEnvYmlPath = path.join(servicePath, 'serverless.env.yml');
// change to serverless.env.yaml if the file could not be found
if (!this.serverless.utils.fileExistsSync(serverlessEnvYmlPath)) {
serverlessEnvYmlPath = path
.join(this.serverless.config.servicePath, 'serverless.env.yaml');
}
return that.serverless.yamlParser
.parse(serverlessYmlPath)
.then((serverlessYmlParam) => {
const serverlessYml = serverlessYmlParam;
.then((serverlessFileParam) => {
const serverlessFile = serverlessFileParam;
// basic service level validation
if (!serverlessYml.service) {
if (!serverlessFile.service) {
throw new SError('"service" property is missing in serverless.yml');
}
if (!serverlessYml.provider) {
if (!serverlessFile.provider) {
throw new SError('"provider" property is missing in serverless.yml');
}
if (!serverlessYml.functions) {
if (!serverlessFile.functions) {
throw new SError('"functions" property is missing in serverless.yml');
}
if (typeof serverlessYml.provider !== 'object') {
const providerName = serverlessYml.provider;
serverlessYml.provider = {
if (typeof serverlessFile.provider !== 'object') {
const providerName = serverlessFile.provider;
serverlessFile.provider = {
name: providerName,
};
}
if (['aws', 'azure', 'google', 'ibm'].indexOf(serverlessYml.provider.name)) {
if (['aws', 'azure', 'google', 'ibm'].indexOf(serverlessFile.provider.name)) {
const errorMessage = [
`Provider "${serverlessYml.provider.name}" is not supported.`,
`Provider "${serverlessFile.provider.name}" is not supported.`,
' Valid values for provider are: aws, azure, google, ibm.',
' Please provide one of those values to the "provider" property in serverless.yml.',
].join('');
throw new SError(errorMessage);
}
that.service = serverlessYml.service;
that.provider = serverlessYml.provider;
that.custom = serverlessYml.custom;
that.plugins = serverlessYml.plugins;
that.resources = serverlessYml.resources;
that.functions = serverlessYml.functions;
_.forEach(that.functions, (functionObj, index) => {
if (!functionObj.events) {
that.functions[index].events = [];
}
});
if (serverlessYml.package && serverlessYml.package.artifact) {
that.package.artifact = serverlessYml.package.artifact;
}
if (serverlessYml.package && serverlessYml.package.exclude) {
that.package.exclude = serverlessYml.package.exclude;
}
if (serverlessYml.package && serverlessYml.package.include) {
that.package.include = serverlessYml.package.include;
}
if (serverlessYml.defaults && serverlessYml.defaults.stage) {
this.defaults.stage = serverlessYml.defaults.stage;
}
if (serverlessYml.defaults && serverlessYml.defaults.region) {
this.defaults.region = serverlessYml.defaults.region;
}
if (serverlessYml.defaults && serverlessYml.defaults.variableSyntax) {
this.defaults.variableSyntax = serverlessYml.defaults.variableSyntax;
}
})
.then(() => that.serverless.yamlParser
.parse(serverlessEnvYmlPath))
.then((serverlessEnvYmlParam) => {
const serverlessEnvYml = serverlessEnvYmlParam;
// safely load serverless.env.yml while avoiding
// reference errors
serverlessEnvYml.vars = serverlessEnvYml.vars || {};
serverlessEnvYml.stages = serverlessEnvYml.stages || {};
Object.keys(serverlessEnvYml.stages).forEach(stage => {
serverlessEnvYml.stages[stage] = serverlessEnvYml.stages[stage] || {};
serverlessEnvYml.stages[stage].vars = serverlessEnvYml.stages[stage].vars || {};
serverlessEnvYml.stages[stage].regions = serverlessEnvYml.stages[stage].regions || {};
Object.keys(serverlessEnvYml.stages[stage].regions).forEach(region => {
serverlessEnvYml.stages[stage].regions[region] =
serverlessEnvYml.stages[stage].regions[region] || {};
serverlessEnvYml.stages[stage].regions[region].vars =
serverlessEnvYml.stages[stage].regions[region].vars || {};
});
});
that.environment = serverlessEnvYml;
return BbPromise.resolve(that);
})
.then(() => {
if (!options.stage) {
options.stage = this.defaults.stage;
}
if (!options.region) {
options.region = this.defaults.region;
}
// Validate: Check stage exists
this.getStage(options.stage);
// Validate: Check region exists in stage
this.getRegionInStage(options.stage, options.region);
that.service = serverlessFile.service;
that.provider = serverlessFile.provider;
that.custom = serverlessFile.custom;
that.plugins = serverlessFile.plugins;
that.resources = serverlessFile.resources;
that.functions = serverlessFile.functions;
// setup function.name property
_.forEach(that.functions, (functionObj, functionName) => {
if (!functionObj.events) {
that.functions[functionName].events = [];
}
if (!functionObj.name) {
that.functions[functionName].name = `${that.service}-${options.stage}-${functionName}`;
}
});
let varTemplateSyntax = /\${([\s\S]+?)}/g;
if (this.defaults && this.defaults.variableSyntax) {
varTemplateSyntax = RegExp(this.defaults.variableSyntax, 'g');
// temporally remove variable syntax from service otherwise it'll match
this.defaults.variableSyntax = true;
if (serverlessFile.package && serverlessFile.package.artifact) {
that.package.artifact = serverlessFile.package.artifact;
}
if (serverlessFile.package && serverlessFile.package.exclude) {
that.package.exclude = serverlessFile.package.exclude;
}
if (serverlessFile.package && serverlessFile.package.include) {
that.package.include = serverlessFile.package.include;
}
const commonVars = this.getVariables();
const stageVars = this.getVariables(options.stage);
const regionVars = this.getVariables(options.stage, options.region);
if (serverlessFile.defaults && serverlessFile.defaults.stage) {
this.defaults.stage = serverlessFile.defaults.stage;
}
if (serverlessFile.defaults && serverlessFile.defaults.region) {
this.defaults.region = serverlessFile.defaults.region;
}
if (serverlessFile.defaults && serverlessFile.defaults.variableSyntax) {
this.defaults.variableSyntax = serverlessFile.defaults.variableSyntax;
}
// temporally remove environment obj. Doesn't make sense to
// populate environment (stages, regions, vars)
const environment = _.cloneDeep(this.environment);
this.environment = null;
if (serverlessFile.defaults) {
const warningMessage = [
'Deprecation Notice: the "defaults" property in serverless.yml',
' is deprecated. The "stage", "region" & "variableSyntax" properties',
' has been moved to the "provider" property instead. Please update',
' your serverless.yml file asap. For more info, you can check our docs.',
].join('');
this.serverless.cli.log(warningMessage);
/*
* we can't use an arrow function in this case cause that would
* change the lexical scoping required by the traverse module
*/
traverse(this).forEach(function (valParam) {
const t = this;
let val = valParam;
// check if the current string is a variable
if (typeof (val) === 'string' && val.match(varTemplateSyntax)) {
// get all ${variable} in the string
val.match(varTemplateSyntax).forEach((variableSyntax) => {
const variableString = variableSyntax
.replace(varTemplateSyntax, (match, varName) => varName.trim());
const variableName = (variableString
.split('.').length > 1) ? variableString
.split('.')[0] : variableString;
let value;
/*
* we will manipulate the value later
* so we gotta clone otherwise we will
* corrupt the passed-by-reference variables object
*/
if (variableName in commonVars) {
value = _.cloneDeep(commonVars[variableName]);
}
if (variableName in stageVars) {
value = _.cloneDeep(stageVars[variableName]);
}
if (variableName in regionVars) {
value = _.cloneDeep(regionVars[variableName]);
}
// Populate
if (typeof value === 'undefined') {
const errorMessage = [
`Variable "${variableName}" doesn't exist in serverless.env.yml.`,
' Please add it to serverless.env.yml.',
].join('');
throw new that.serverless.classes
.Error(errorMessage);
} else if (typeof value === 'string') {
if (variableString.split('.').length > 1) {
const errorMessage = [
`Trying to access sub properties of a string variable "${variableName}".`,
' Please make sure the variable in serverless.env.yml',
' is an object, otherwise you cannot use the',
' dot notation for that variable in serverless.yml',
].join('');
throw new that.serverless.classes
.Error(errorMessage);
}
// for string variables, we use replaceall in case the user
// includes the variable as a substring (ie. "hello ${name}")
val = replaceall(variableSyntax, value, val);
} else {
// populate objects recursively
/* eslint no-lonely-if: "off" */
if (typeof value === 'object') {
const subProperties = variableString.split('.');
// remove first element. It's the variableName
subProperties.splice(0, 1);
subProperties.forEach(subProperty => {
if (!value[subProperty]) {
const errorMessage = [
`Variable "${variableName}" doesn't have sub property "${subProperty}".`,
' Please make sure the variable is',
' the intended object in serverless.env.yml,',
' or reference the correct sub property in serverless.yml',
].join('');
throw new that.serverless.classes
.Error(errorMessage);
}
value = value[subProperty];
});
if (typeof value === 'string') {
val = replaceall(variableSyntax, value, val);
} else {
if (val !== variableSyntax) {
const errorMessage = [
'Trying to populate non string variables into',
` a string for variable "${variableName}".`,
' Please make sure the variable value in',
' serverless.env.yml is a string',
].join('');
throw new that.serverless.classes
.Error(errorMessage);
}
val = value;
}
} else if (variableString.split('.').length > 1) {
const errorMessage = [
`Trying to access sub properties of a non-object variable "${variableName}"`,
' Please make sure the variable is an object in serverless.env.yml,',
' otherwise, you cannot use the dot notation',
' for that variable in serverless.yml',
].join('');
throw new that.serverless.classes
.Error(errorMessage);
} else {
if (val !== variableSyntax) {
const errorMessage = [
'Trying to populate non string variables',
` into a string for variable "${variableName}".`,
' Please make sure the variable value in serverless.env.yml is a string',
].join('');
throw new that.serverless.classes
.Error(errorMessage);
}
val = value; // not string nor object
}
}
});
// Replace
t.update(val);
if (serverlessFile.defaults.stage) {
this.defaults.stage = serverlessFile.defaults.stage;
}
});
if (serverlessFile.defaults.region) {
this.defaults.region = serverlessFile.defaults.region;
}
if (serverlessFile.defaults.variableSyntax) {
this.defaults.variableSyntax = serverlessFile.defaults.variableSyntax;
}
}
// put back environment that we temporally removed earlier
this.environment = environment;
// put back variable syntax if we removed it for processing
if (this.defaults && this.defaults.variableSyntax) {
this.defaults.variableSyntax = varTemplateSyntax;
// Moving defaults into provider obj
if (serverlessFile.provider.stage) {
this.defaults.stage = serverlessFile.provider.stage;
}
if (serverlessFile.provider.region) {
this.defaults.region = serverlessFile.provider.region;
}
if (serverlessFile.provider.variableSyntax) {
this.defaults.variableSyntax = serverlessFile.provider.variableSyntax;
}
return this;
});
}
populate(processedOptions) {
const that = this;
const options = processedOptions || {};
const variableSyntaxProperty = this.defaults.variableSyntax;
const variableSyntax = RegExp(variableSyntaxProperty, 'g');
const fileRefSyntax = RegExp(/^file\(([a-zA-Z0-9._\-\/]+?)\)/g);
// const fileRefSyntax = RegExp('^file\\(([a-zA-Z0-9._\\-\\/]+?)\\)', 'g');
// temporally remove variable syntax from service otherwise it'll match
this.defaults.variableSyntax = true;
this.serverless.service.defaults.variableSyntax = true;
/*
* we can't use an arrow function in this case cause that would
* change the lexical scoping required by the traverse module
*/
traverse(this).forEach(function (property) {
const t = this;
if (typeof property === 'string') {
const nestedPopulate = (updatedPropertyParam) => {
let updatedProperty = updatedPropertyParam;
if (typeof updatedProperty === 'string' && updatedProperty.match(variableSyntax)) {
updatedProperty.match(variableSyntax).forEach((matchedString) => {
const variableString = matchedString
.replace(variableSyntax, (match, varName) => varName.trim());
/*
* File Reference
*/
if (variableString.match(fileRefSyntax)) {
const matchedFileRefString = variableString.match(fileRefSyntax)[0];
const referencedFileRelativePath = matchedFileRefString
.replace(fileRefSyntax, (match, varName) => varName.trim());
const referencedFileFullPath = path.join(that.serverless.config.servicePath,
referencedFileRelativePath);
let value = that.serverless.utils.readFileSync(referencedFileFullPath);
if (matchedFileRefString !== variableString) {
let deepProperties = variableString
.replace(matchedFileRefString, '');
if (deepProperties.substring(0, 1) !== '.') {
const errorMessage = [
'Invalid variable syntax when referencing',
` file "${referencedFileRelativePath}"`,
' Please use valid dot notation when referencing sub properties.',
].join('');
throw new that.serverless.classes
.Error(errorMessage);
}
deepProperties = deepProperties.slice(1);
const selfSubProperties = deepProperties.split('.');
selfSubProperties.forEach(selfSubProperty => {
if (!value[selfSubProperty]) {
const errorMessage = [
`file "${referencedFileRelativePath}" doesn't`,
` have sub property "${selfSubProperty}".`,
' Please make sure you are referencing the correct sub property',
].join('');
throw new that.serverless.classes
.Error(errorMessage);
}
value = value[selfSubProperty];
});
}
if (typeof value === 'string') {
updatedProperty = replaceall(matchedString, value, updatedProperty);
} else {
if (updatedProperty !== matchedString) {
const errorMessage = [
'Trying to populate non string value into',
` a string when referencing file "${referencedFileRelativePath}".`,
' Please make sure the value of the property',
' is a string',
].join('');
throw new that.serverless.classes
.Error(errorMessage);
}
updatedProperty = value;
}
/*
* Env Var Reference
*/
} else if (variableString.split('.')[0] === 'env') {
if (variableString.split('.').length !== 2) {
const errorMessage = [
'Trying to access sub properties of environment',
' variable strings, or trying to reference all environment variable.',
].join('');
throw new SError(errorMessage);
}
const requestedEnvVar = variableString.split('.')[1];
const propertyValue = process.env[requestedEnvVar];
if (typeof propertyValue === 'undefined') {
const errorMessage = [
`Environment variable ${requestedEnvVar} is not set on your machine.`,
' Please set this env var before referencing it as a variable.',
].join('');
throw new SError(errorMessage);
}
updatedProperty = replaceall(matchedString, propertyValue, updatedProperty);
/*
* Options Reference
*/
} else if (variableString.split('.')[0] === 'opt') {
if (variableString.split('.').length === 1) {
// load all options object
if (updatedProperty === matchedString) {
updatedProperty = options;
} else {
const errorMessage = [
'Trying to reference all options object as a substring.',
' Please make sure the string referencing the variable',
' Does not contain any other sub-strings,',
' or reference a specific option string.',
].join('');
throw new SError(errorMessage);
}
} else if (variableString.split('.').length === 2) {
// load specific option
const requestedOption = variableString.split('.')[1];
const propertyValue = options[requestedOption];
if (typeof propertyValue === 'undefined') {
const errorMessage = [
`Option ${requestedOption} was not passed in the CLI.`,
' Please pass this variable in the CLI to use in serverless.yml.',
].join('');
throw new SError(errorMessage);
}
updatedProperty = replaceall(matchedString, propertyValue, updatedProperty);
} else {
const errorMessage = [
'Trying to reference a specific option sub properties.',
' Each passed option can only be a string, not objects.',
' Please make sure you only reference the option string',
' without any other dot notation.',
].join('');
throw new SError(errorMessage);
}
/*
* Self Reference
*/
} else if (variableString.split('.')[0] === 'self') {
if (variableString.split('.').length === 1) {
const errorMessage = [
'You can\'t reference the entire "self" serverless.yml file.',
' Please reference a sub property with ${self.subProp}',
].join('');
throw new that.serverless.classes
.Error(errorMessage);
}
let value = _.cloneDeep(that);
const selfSubProperties = variableString.split('.');
// remove first element. It's the "self" keyword
selfSubProperties.splice(0, 1);
selfSubProperties.forEach(selfSubProperty => {
if (!value[selfSubProperty]) {
const errorMessage = [
`serverless.yml doesn't have sub property "${selfSubProperty}".`,
' Please make sure you are referencing the correct sub property',
].join('');
throw new that.serverless.classes
.Error(errorMessage);
}
value = value[selfSubProperty];
});
if (typeof value === 'string') {
updatedProperty = replaceall(matchedString, value, updatedProperty);
} else {
if (updatedProperty !== matchedString) {
const errorMessage = [
'Trying to populate non string value into',
' a string when referencing "self".',
' Please make sure the value of the property',
' is a string',
].join('');
throw new that.serverless.classes
.Error(errorMessage);
}
updatedProperty = value;
}
} else {
const errorMessage = [
`Invalid variable reference syntax for variable ${matchedString}.`,
' You can only reference env vars, options, & files.',
' You can check our docs for more info.',
].join('');
throw new SError(errorMessage);
}
});
return nestedPopulate(updatedProperty);
}
return updatedProperty;
};
const updatedProperty = nestedPopulate(property);
t.update(updatedProperty);
}
});
// put back variable syntax that we removed earlier
this.defaults.variableSyntax = variableSyntaxProperty;
this.serverless.service.defaults.variableSyntax = variableSyntaxProperty;
return this;
}
update(data) {
return _.merge(this, data);
}
@ -348,37 +390,6 @@ class Service {
getAllEventsInFunction(functionName) {
return Object.keys(this.getFunction(functionName).events);
}
getStage(stageName) {
if (stageName in this.environment.stages) {
return this.environment.stages[stageName];
}
throw new SError(`Stage "${stageName}" doesn't exist in this service.`);
}
getAllStages() {
return Object.keys(this.environment.stages);
}
getRegionInStage(stageName, regionName) {
if (regionName in this.getStage(stageName).regions) {
return this.getStage(stageName).regions[regionName];
}
throw new SError(`Region "${regionName}" doesn't exist in stage "${stageName}"`);
}
getAllRegionsInStage(stageName) {
return Object.keys(this.getStage(stageName).regions);
}
getVariables(stageName, regionName) {
if (stageName && regionName) {
return this.getRegionInStage(stageName, regionName).vars || {};
} else if (stageName) {
return this.getStage(stageName).vars || {};
}
return this.environment.vars || {};
}
}
module.exports = Service;

View File

@ -89,8 +89,7 @@ class SDK {
prefix = 'AWS';
}
const profile = process.env[`${prefix}_PROFILE`]
|| this.serverless.service.getVariables(stage).profile;
const profile = process.env[`${prefix}_PROFILE`];
credentials.profile = profile;

View File

@ -9,6 +9,8 @@ module.exports = {
.Error('This command can only be run inside a service directory');
}
console.log(this.serverless.service.custom)
this.options.stage = this.options.stage
|| (this.serverless.service.defaults && this.serverless.service.defaults.stage)
|| 'dev';
@ -16,10 +18,6 @@ module.exports = {
|| (this.serverless.service.defaults && this.serverless.service.defaults.region)
|| 'us-east-1';
// validate stage / region exists in service
this.serverless.service.getStage(this.options.stage);
this.serverless.service.getRegionInStage(this.options.stage, this.options.region);
return BbPromise.resolve();
},
};

View File

@ -87,46 +87,20 @@ describe('AWS SDK', () => {
describe('#getCredentials()', () => {
it('should get credentials', () => {
const serverless = new Serverless();
serverless.service.environment = {
vars: {
profile: 'default',
},
stages: {
dev: {
vars: {},
regions: {},
},
},
};
serverless.service.environment.stages.dev.regions['us-east-1'] = {
vars: {},
};
process.env.AWS_PROFILE = 'default';
const awsSdk = new AwsSdk(serverless);
const credentials = awsSdk.getCredentials();
expect(credentials.profile).to.equal('default');
delete process.env.AWS_PROFILE;
});
it('should get stage credentials', () => {
const serverless = new Serverless();
serverless.service.environment = {
vars: {},
stages: {
dev: {
vars: {
profile: 'default',
},
regions: {},
},
},
};
serverless.service.environment.stages.dev.regions['us-east-1'] = {
vars: {},
};
process.env.AWS_DEV_PROFILE = 'default';
const awsSdk = new AwsSdk(serverless);
const credentials = awsSdk.getCredentials('dev');
expect(credentials.profile).to.deep.equal('default');
delete process.env.AWS_DEV_PROFILE;
});
});

View File

@ -15,43 +15,11 @@ describe('#validate()', () => {
region: 'us-east-1',
};
awsPlugin.serverless.service.environment = {
vars: {},
stages: {
dev: {
vars: {},
regions: {
'us-east-1': {
vars: {},
},
},
},
},
};
awsPlugin.serverless.config.servicePath = true;
Object.assign(awsPlugin, validate);
});
it('should succeed if region exists in service', () => {
expect(() => awsPlugin.validate()).to.not.throw(Error);
});
it('should throw error if region does not exist in service', () => {
awsPlugin.options.region = 'us-west-2';
expect(() => awsPlugin.validate()).to.throw(Error);
});
it('should succeed if stage exists in service', () => {
expect(() => awsPlugin.validate()).to.not.throw(Error);
});
it('should throw error if stage does not exist in service', () => {
awsPlugin.options.stage = 'prod';
expect(() => awsPlugin.validate()).to.throw(Error);
});
it('should succeed if inside service (servicePath defined)', () => {
expect(() => awsPlugin.validate()).to.not.throw(Error);
});
@ -76,20 +44,6 @@ describe('#validate()', () => {
stage: 'some-stage',
};
awsPlugin.serverless.service.environment = {
vars: {},
stages: {
'some-stage': {
vars: {},
regions: {
'us-east-1': {
vars: {},
},
},
},
},
};
return awsPlugin.validate().then(() => {
expect(awsPlugin.options.stage).to.equal('some-stage');
});
@ -108,20 +62,6 @@ describe('#validate()', () => {
region: 'some-region',
};
awsPlugin.serverless.service.environment = {
vars: {},
stages: {
dev: {
vars: {},
regions: {
'some-region': {
vars: {},
},
},
},
},
};
return awsPlugin.validate().then(() => {
expect(awsPlugin.options.region).to.equal('some-region');
});

View File

@ -1,15 +0,0 @@
# This is the Serverless Environment File
#
# It contains listing of your stages, and their regions
# It also manages serverless variables at 3 levels:
# - common variables: variables that apply to all stages/regions
# - stage variables: variables that apply to a specific stage
# - region variables: variables that apply to a specific region
vars:
stages:
dev:
vars:
regions:
us-east-1:
vars:

View File

@ -1,15 +0,0 @@
# This is the Serverless Environment File
#
# It contains listing of your stages, and their regions
# It also manages serverless variables at 3 levels:
# - common variables: variables that apply to all stages/regions
# - stage variables: variables that apply to a specific stage
# - region variables: variables that apply to a specific region
vars:
stages:
dev:
vars:
regions:
us-east-1:
vars:

View File

@ -49,13 +49,13 @@ functions:
handler: hello.Handler
# you can add any of the following events
# events:
# - http:
# path: users/create
# method: get
# - s3: ${bucket}
# - schedule: rate(10 minutes)
# - sns: greeter-topic
# events:
# - http:
# path: users/create
# method: get
# - s3: ${env.BUCKET}
# - schedule: rate(10 minutes)
# - sns: greeter-topic
# you can add CloudFormation resource templates here
#resources:

View File

@ -1,15 +0,0 @@
# This is the Serverless Environment File
#
# It contains listing of your stages and their regions
# It also manages serverless variables at 3 levels:
# - common variables: variables that apply to all stages/regions
# - stage variables: variables that apply to a specific stage
# - region variables: variables that apply to a specific region
vars:
stages:
dev:
vars:
regions:
us-east-1:
vars:

View File

@ -48,14 +48,14 @@ functions:
hello:
handler: handler.hello
# you can add any of the following events
# events:
# - http:
# path: users/create
# method: get
# - s3: ${bucket}
# - schedule: rate(10 minutes)
# - sns: greeter-topic
# you can add any of the following events
# events:
# - http:
# path: users/create
# method: get
# - s3: ${env.BUCKET}
# - schedule: rate(10 minutes)
# - sns: greeter-topic
# you can add CloudFormation resource templates here
#resources:

View File

@ -1,15 +0,0 @@
# This is the Serverless Environment File
#
# It contains listing of your stages, and their regions
# It also manages serverless variables at 3 levels:
# - common variables: variables that apply to all stages/regions
# - stage variables: variables that apply to a specific stage
# - region variables: variables that apply to a specific region
vars:
stages:
dev:
vars:
regions:
us-east-1:
vars:

View File

@ -49,13 +49,13 @@ functions:
handler: handler.hello
# you can add any of the following events
# events:
# - http:
# path: users/create
# method: get
# - s3: ${bucket}
# - schedule: rate(10 minutes)
# - sns: greeter-topic
# events:
# - http:
# path: users/create
# method: get
# - s3: ${env.BUCKET}
# - schedule: rate(10 minutes)
# - sns: greeter-topic
# you can add CloudFormation resource templates here
#resources:

View File

@ -74,8 +74,6 @@ describe('Create', () => {
return create.create().then(() => {
expect(create.serverless.utils.fileExistsSync(path.join(tmpDir, 'serverless.yml')))
.to.be.equal(true);
expect(create.serverless.utils.fileExistsSync(path.join(tmpDir, 'serverless.env.yml')))
.to.be.equal(true);
expect(create.serverless.utils.fileExistsSync(path.join(tmpDir, 'handler.js')))
.to.be.equal(true);
@ -92,8 +90,6 @@ describe('Create', () => {
return create.create().then(() => {
expect(create.serverless.utils.fileExistsSync(path.join(tmpDir, 'serverless.yml')))
.to.be.equal(true);
expect(create.serverless.utils.fileExistsSync(path.join(tmpDir, 'serverless.env.yml')))
.to.be.equal(true);
expect(create.serverless.utils.fileExistsSync(path.join(tmpDir, 'handler.py')))
.to.be.equal(true);
@ -110,8 +106,6 @@ describe('Create', () => {
return create.create().then(() => {
expect(create.serverless.utils.fileExistsSync(path.join(tmpDir, 'serverless.yml')))
.to.be.equal(true);
expect(create.serverless.utils.fileExistsSync(path.join(tmpDir, 'serverless.env.yml')))
.to.be.equal(true);
expect(create.serverless.utils.fileExistsSync(path.join(tmpDir, 'event.json')))
.to.be.equal(true);
expect(create.serverless.utils.fileExistsSync(path.join(tmpDir, 'pom.xml')))
@ -142,8 +136,6 @@ describe('Create', () => {
return create.create().then(() => {
expect(create.serverless.utils.fileExistsSync(path.join(tmpDir, 'serverless.yml')))
.to.be.equal(true);
expect(create.serverless.utils.fileExistsSync(path.join(tmpDir, 'serverless.env.yml')))
.to.be.equal(true);
expect(create.serverless.utils.fileExistsSync(path.join(tmpDir, 'event.json')))
.to.be.equal(true);
expect(create.serverless.utils.fileExistsSync(path.join(tmpDir, 'build.gradle')))

View File

@ -688,8 +688,6 @@ describe('PluginManager', () => {
expect(serverlessInstance.utils
.fileExistsSync(path.join(tmpDir, 'serverless.yml'))).to.equal(true);
expect(serverlessInstance.utils
.fileExistsSync(path.join(tmpDir, 'serverless.env.yml'))).to.equal(true);
expect(serverlessInstance.utils
.fileExistsSync(path.join(tmpDir, 'handler.js'))).to.equal(true);

File diff suppressed because it is too large Load Diff