diff --git a/app.js b/app.js index fcce9eb..8efe4c7 100755 --- a/app.js +++ b/app.js @@ -17,15 +17,15 @@ const usage = ` Scandium usage: - scandium create [options] - scandium update [options] - scandium environment show [options] + scandium create [options] + scandium update [options] + scandium environment show [options] options: - Name of the Lambda function. - --env-from-file= Read and set environmental variables from the specified file. --deploy-to= Deploy the API to the specified stage, and make it callable from the Internet. + --env-from-file= Read and set environmental variables from the specified file. --help Show this help, then exit. + --name= Name of the Lambda function. Default to the name property in your package.json. --rest-api-id= ID of the AWS API Gateway rest api to point to the Lambda function. --role= ARN of the IAM role that Lambda assumes when it executes your function. --swagger= Path to Swagger API definition used to configure AWS API Gateway. @@ -38,6 +38,7 @@ async function main () { const listrOpts = (isCI || args['--verbose']) ? { renderer: listrVerboseRenderer } : {} const createList = new Listr([ + tasks.parseOptions, tasks.packageApp, tasks.readEnvironmentFile, tasks.createLambdaRole, @@ -49,6 +50,7 @@ async function main () { ], listrOpts) const updateList = new Listr([ + tasks.parseOptions, tasks.packageApp, tasks.readEnvironmentFile, tasks.updateLambdaEnvironment, @@ -59,6 +61,11 @@ async function main () { tasks.deployApi ], listrOpts) + const environmentList = new Listr([ + tasks.parseOptions, + tasks.getCurrentEnvironment + ], listrOpts) + if (!awsHasRegion()) { throw new UserError(awsHasRegion.errorText) } @@ -72,10 +79,10 @@ async function main () { } if (args.environment && args.show) { - const environment = await amazon.getFunctionEnvironment({ functionName: args[''] }) + const { currentEnvironment } = await environmentList.run({ args }) - for (const key of Object.keys(environment)) { - console.log(`${key}=${environment[key]}`) + for (const key of Object.keys(currentEnvironment)) { + console.log(`${key}=${currentEnvironment[key]}`) } } } diff --git a/lib/tasks.js b/lib/tasks.js index fe29cf5..7e025d2 100644 --- a/lib/tasks.js +++ b/lib/tasks.js @@ -2,6 +2,7 @@ const fs = require('fs') const util = require('util') const dotenv = require('dotenv') +const loadJsonFile = require('load-json-file') const parseArn = require('aws-arn-parser') const prettyBytes = require('pretty-bytes') @@ -12,6 +13,25 @@ const UserError = require('./user-error') const readFile = util.promisify(fs.readFile) +exports.parseOptions = { + title: 'Parse options', + task: async (ctx, task) => { + if (ctx.args['--name']) { + ctx.name = ctx.args['--name'] + } else { + try { + ctx.name = (await loadJsonFile('package.json')).name + } catch (err) { + if (err.code !== 'ENOENT') throw err + } + + if (!ctx.name) { + throw new UserError('Please specify a name using the --name flag') + } + } + } +} + exports.packageApp = { title: 'Packaging app for Lambda', task: async (ctx, task) => { @@ -35,7 +55,7 @@ exports.createLambdaRole = { ctx.roleArn = ctx.args['--role'] task.skip('Using provided role') } else { - ctx.roleArn = await amazon.createLambdaRole(ctx.args['']) + ctx.roleArn = await amazon.createLambdaRole(ctx.name) task.title = `Created new Lambda role with ARN: ${ctx.roleArn}` } } @@ -44,7 +64,7 @@ exports.createLambdaRole = { exports.createLambdaFunction = { title: 'Creating Lambda function', task: async (ctx, task) => { - ctx.lambdaArn = await amazon.createFunction({ zipFile: ctx.zipFile, functionName: ctx.args[''], role: ctx.roleArn, environment: ctx.environment }) + ctx.lambdaArn = await amazon.createFunction({ zipFile: ctx.zipFile, functionName: ctx.name, role: ctx.roleArn, environment: ctx.environment }) task.title = `Created new Lambda function with ARN: ${ctx.lambdaArn}` } } @@ -53,11 +73,11 @@ exports.updateLambdaFunction = { title: 'Updating Lambda function', task: async (ctx, task) => { try { - ctx.lambdaArn = await amazon.updateFunction({ zipFile: ctx.zipFile, functionName: ctx.args[''] }) + ctx.lambdaArn = await amazon.updateFunction({ zipFile: ctx.zipFile, functionName: ctx.name }) task.title = `Updated existing Lambda function with ARN: ${ctx.lambdaArn}` } catch (err) { if (err.code === 'ResourceNotFoundException') { - throw new UserError(`Unable to find a Lambda function named "${ctx.args['']}", did you mean to run the create command?`) + throw new UserError(`Unable to find a Lambda function named "${ctx.name}", did you mean to run the create command?`) } throw err @@ -69,7 +89,7 @@ exports.updateLambdaEnvironment = { title: 'Update Lambda environment', enabled: (ctx) => Boolean(ctx.args['--env-from-file']), task: async (ctx, task) => { - await amazon.updateFunctionEnvironment({ functionName: ctx.args[''], environment: ctx.environment }) + await amazon.updateFunctionEnvironment({ functionName: ctx.name, environment: ctx.environment }) task.title = `Updated existing Lambda environment` } } @@ -78,7 +98,7 @@ exports.loadSwaggerDefinition = { title: 'Load Swagger definition', enabled: (ctx) => Boolean(ctx.args['--swagger']), task: async (ctx, task) => { - ctx.definition = await swagger.loadSwaggerFile(ctx.args['--swagger'], ctx.args[''], ctx.lambdaArn) + ctx.definition = await swagger.loadSwaggerFile(ctx.args['--swagger'], ctx.name, ctx.lambdaArn) task.title = 'Loaded Swagger definition from file' } } @@ -87,7 +107,7 @@ exports.generateSwaggerDefinition = { title: 'Generate Swagger definition', enabled: (ctx) => !ctx.args['--swagger'], task: async (ctx, task) => { - ctx.definition = await swagger.forwardAllDefinition(ctx.args[''], ctx.lambdaArn) + ctx.definition = await swagger.forwardAllDefinition(ctx.name, ctx.lambdaArn) task.title = 'Generated "forward all" Swagger definition' } } @@ -111,7 +131,7 @@ exports.updateApiGateway = { if (ctx.args['--rest-api-id']) { ctx.id = ctx.args['--rest-api-id'] } else { - ctx.id = await amazon.findApiGateway(ctx.args['']) + ctx.id = await amazon.findApiGateway(ctx.name) } await amazon.updateApiGateway({ id: ctx.id, definition: ctx.definition, lambdaArn: ctx.lambdaArn }) @@ -130,3 +150,10 @@ exports.deployApi = { task.title = `Now serving live requests at: https://${ctx.id}.execute-api.${region}.amazonaws.com/${stage}` } } + +exports.getCurrentEnvironment = { + title: 'Fetching current environment', + task: async (ctx, task) => { + ctx.currentEnvironment = await amazon.getFunctionEnvironment({ functionName: ctx.name }) + } +}