diff --git a/README.md b/README.md index 12eb0eb..78f00c9 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ $ heroku plugins:install heroku-container-registry In a directory with a Dockerfile: ``` +$ heroku container:run web $ heroku container:login $ heroku create $ heroku container:push diff --git a/commands/run.js b/commands/run.js new file mode 100644 index 0000000..7478042 --- /dev/null +++ b/commands/run.js @@ -0,0 +1,79 @@ +const cli = require('heroku-cli-util') +const Sanbashi = require('../lib/sanbashi') + +let usage = ` + ${ cli.color.bold.underline.magenta('Usage:')} + ${ cli.color.cmd('heroku container:run web bash')} # Runs bash on the local web docker container + ${ cli.color.cmd('heroku container:run worker')} # Runs the container CMD on the local worker container` + +module.exports = function (topic) { + return { + topic: topic, + command: 'run', + description: 'builds, then runs the docker image locally', + variableArgs: true, + help: usage, + flags: [ + { + name: 'verbose', + char: 'v', + hasValue: false + }, + { + name: 'arg', + hasValue: true, + description: 'set build-time variables' + } + ], + run: cli.command(run) + } +} + +let run = async function (context, heroku) { + if (context.args.length === 0) { + cli.error(`Error: Requires one process type\n ${usage} `) + process.exit(1) + } + + let processType = context.args.shift() + let command = context.args + let tag = `heroku-local-${processType}` + let dockerfiles = Sanbashi.getDockerfiles(process.cwd(), false) + let possibleJobs = Sanbashi.getJobs(tag, dockerfiles) + + let jobs = [] + if (possibleJobs.standard) { + possibleJobs.standard.forEach((pj) => { pj.resource = pj.resource.replace(/standard$/, processType)}) + jobs = possibleJobs.standard || [] + } + if (!jobs.length) { + cli.warn('No images to push') + process.exit(1) + } + + let job = jobs[0] + let flagsArg = context.flags.arg + let buildArg = (flagsArg !== undefined) ? flagsArg.split(',') : [] + + try { + cli.styledHeader(`Building ${processType} (${job.dockerfile })`) + await Sanbashi.buildImage(job.dockerfile, job.resource, context.flags.verbose, buildArg) + } catch (err) { + cli.error(`Error: docker build exited with ${ err }`) + cli.hush(err.stack || err) + process.exit(1) + } + + if (command == '') { + cli.styledHeader(`Running web`) + } else { + cli.styledHeader(`Running '${command}' on ${tag}`) + } + try { + await Sanbashi.runImage(job.resource, command, context.flags.verbose) + } catch(err) { + cli.error(`Error: docker run exited with ${ err }`) + cli.hush(err.stack || err) + process.exit(1) + } +} diff --git a/index.js b/index.js index d5711e8..dd42102 100644 --- a/index.js +++ b/index.js @@ -12,6 +12,7 @@ module.exports = { require('./commands/index')(pkg), require('./commands/login')(pkg.topic), require('./commands/logout')(pkg.topic), - require('./commands/push')(pkg.topic) + require('./commands/push')(pkg.topic), + require('./commands/run')(pkg.topic) ] } diff --git a/lib/sanbashi.js b/lib/sanbashi.js index d421eb1..958d5ea 100644 --- a/lib/sanbashi.js +++ b/lib/sanbashi.js @@ -101,6 +101,17 @@ Sanbashi.pushImage = function (resource, verbose) { return Sanbashi.cmd('docker', args) } +Sanbashi.runImage = function (resource, command, verbose) { + let args = ['run'] + if (command == '') { + args.push(resource) + } else { + args.push('-it', resource, command) + } + log(verbose, args) + return Sanbashi.cmd('docker', args) +} + Sanbashi.cmd = function (cmd, args) { return new Promise((resolve, reject) => { Child.spawn(cmd, args, {stdio: 'inherit'})