Skip to content

Commit

Permalink
Merge pull request #6 from LinusU/listr
Browse files Browse the repository at this point in the history
🎉 Add support for non-tty (e.g. CI) output
  • Loading branch information
LinusU authored Feb 9, 2018
2 parents bf01ddd + 1acf158 commit ed1d976
Show file tree
Hide file tree
Showing 4 changed files with 418 additions and 111 deletions.
99 changes: 26 additions & 73 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,11 @@
/* Make sure that AWS uses local config files, since this is a CLI util */
process.env.AWS_SDK_LOAD_CONFIG = 'true'

const ora = require('ora')
const neodoc = require('neodoc')
const parseArn = require('aws-arn-parser')
const prettyBytes = require('pretty-bytes')
const awsHasRegion = require('aws-has-region')
const Listr = require('listr')

const amazon = require('./lib/amazon')
const builder = require('./lib/builder')
const swagger = require('./lib/swagger')
const tasks = require('./lib/tasks')

class UserError extends Error {}

Expand All @@ -30,81 +26,38 @@ Options:
--deploy-to Deploy the API to the specified stage, and make it callable from the Internet.
`

const createList = new Listr([
tasks.packageApp,
tasks.createLambdaRole,
tasks.createLambdaFunction,
tasks.loadSwaggerDefinition,
tasks.generateSwaggerDefinition,
tasks.createApiGateway,
tasks.deployApi
])

const updateList = new Listr([
tasks.packageApp,
tasks.updateLambdaFunction,
tasks.loadSwaggerDefinition,
tasks.generateSwaggerDefinition,
tasks.updateApiGateway,
tasks.deployApi
])

async function main () {
const args = neodoc.run(usage)
const spinner = ora()

if (!awsHasRegion()) {
throw new UserError(awsHasRegion.errorText)
}

try {
if (args.create) {
spinner.start('Packaging app for Lambda')
const zipFile = await builder.createZipFile(process.cwd())
spinner.succeed(`App packaged successfully! Final size: ${prettyBytes(zipFile.byteLength)}`)

let roleArn = args['--role']
if (!roleArn) {
spinner.start('Creating Lambda role')
roleArn = await amazon.createLambdaRole(args['<name>'])
spinner.succeed(`Created new Lambda role with ARN: ${roleArn}`)
}

spinner.start('Creating Lambda function')
const lambdaArn = await amazon.createFunction({ zipFile, functionName: args['<name>'], role: roleArn })
spinner.succeed(`Created new Lambda function with ARN: ${lambdaArn}`)

const definition = args['--swagger']
? await swagger.loadSwaggerFile(args['--swagger'], lambdaArn)
: await swagger.forwardAllDefinition(lambdaArn)

spinner.start('Creating new API Gateway')
const { id } = await amazon.createApiGateway({ definition, lambdaArn })
spinner.succeed(`Created new API Gateway with id: ${id}`)

if (args['--deploy-to']) {
const stage = args['--deploy-to']
const { region } = parseArn(lambdaArn)

spinner.start('Deploying the API to a live address')
await amazon.deployApiGateway({ id, stage })
spinner.succeed(`Now serving live requests at: https://${id}.execute-api.${region}.amazonaws.com/${stage}`)
}
}

if (args.update) {
spinner.start('Packaging app for Lambda')
const zipFile = await builder.createZipFile(process.cwd())
spinner.succeed(`App packaged successfully! Final size: ${prettyBytes(zipFile.byteLength)}`)

spinner.start('Creating Lambda function')
const lambdaArn = await amazon.updateFunction({ zipFile, functionName: args['<name>'] })
spinner.succeed(`Updated existing Lambda function with ARN: ${lambdaArn}`)

const definition = args['--swagger']
? await swagger.loadSwaggerFile(args['--swagger'], lambdaArn)
: await swagger.forwardAllDefinition(lambdaArn)

const id = args['--rest-api-id']

spinner.start('Updating existing API Gateway')
await amazon.updateApiGateway({ id, definition, lambdaArn })
spinner.succeed(`Updated existing API Gateway with id: ${id}`)

if (args['--deploy-to']) {
const stage = args['--deploy-to']
const { region } = parseArn(lambdaArn)

spinner.start('Deploying the API to a live address')
await amazon.deployApiGateway({ id, stage })
spinner.succeed(`Now serving live requests at: https://${id}.execute-api.${region}.amazonaws.com/${stage}`)
}
}
} catch (err) {
spinner.fail(err.toString())
if (args.create) {
await createList.run({ args })
}

throw err
if (args.update) {
await updateList.run({ args })
}
}

Expand Down
90 changes: 90 additions & 0 deletions lib/tasks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
const parseArn = require('aws-arn-parser')
const prettyBytes = require('pretty-bytes')

const amazon = require('./amazon')
const builder = require('./builder')
const swagger = require('./swagger')

exports.packageApp = {
title: 'Packaging app for Lambda',
task: async (ctx, task) => {
ctx.zipFile = await builder.createZipFile(process.cwd())
task.title = `App packaged successfully! Final size: ${prettyBytes(ctx.zipFile.byteLength)}`
}
}

exports.createLambdaRole = {
title: 'Creating Lambda role',
task: async (ctx, task) => {
if (ctx.args['--role']) {
ctx.roleArn = ctx.args['--role']
task.skip('Using provided role')
} else {
ctx.roleArn = await amazon.createLambdaRole(ctx.args['<name>'])
task.title = `Created new Lambda role with ARN: ${ctx.roleArn}`
}
}
}

exports.createLambdaFunction = {
title: 'Creating Lambda function',
task: async (ctx, task) => {
ctx.lambdaArn = await amazon.createFunction({ zipFile: ctx.zipFile, functionName: ctx.args['<name>'], role: ctx.roleArn })
task.title = `Created new Lambda function with ARN: ${ctx.lambdaArn}`
}
}

exports.updateLambdaFunction = {
title: 'Updating Lambda function',
task: async (ctx, task) => {
ctx.lambdaArn = await amazon.updateFunction({ zipFile: ctx.zipFile, functionName: ctx.args['<name>'] })
task.title = `Updated existing Lambda function with ARN: ${ctx.lambdaArn}`
}
}

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.lambdaArn)
task.title = 'Loaded Swagger definition from file'
}
}

exports.generateSwaggerDefinition = {
title: 'Generate Swagger definition',
enabled: (ctx) => !ctx.args['--swagger'],
task: async (ctx, task) => {
ctx.definition = await swagger.forwardAllDefinition(ctx.lambdaArn)
task.title = 'Generated "forward all" Swagger definition'
}
}

exports.createApiGateway = {
title: 'Creating new API Gateway',
task: async (ctx, task) => {
ctx.id = (await amazon.createApiGateway({ definition: ctx.definition, lambdaArn: ctx.lambdaArn })).id
task.title = `Created new API Gateway with id: ${ctx.id}`
}
}

exports.updateApiGateway = {
title: 'Updating existing API Gateway',
task: async (ctx, task) => {
ctx.id = ctx.args['--rest-api-id']
await amazon.updateApiGateway({ id: ctx.id, definition: ctx.definition, lambdaArn: ctx.lambdaArn })
task.title = `Updated existing API Gateway with id: ${ctx.id}`
}
}

exports.deployApi = {
title: 'Deploying the API to a live address',
enabled: (ctx) => Boolean(ctx.args['--deploy-to']),
task: async (ctx, task) => {
const stage = ctx.args['--deploy-to']
const { region } = parseArn(ctx.lambdaArn)

await amazon.deployApiGateway({ id: ctx.id, stage })
task.title = `Now serving live requests at: https://${ctx.id}.execute-api.${region}.amazonaws.com/${stage}`
}
}
Loading

0 comments on commit ed1d976

Please sign in to comment.