From 1f79be7e4e203c7d494df21224f77e6a83d63879 Mon Sep 17 00:00:00 2001 From: Jacob Kaplan-Moss Date: Tue, 21 Nov 2017 10:10:48 -0800 Subject: [PATCH] More error checking and docs --- datasette/cli.py | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/datasette/cli.py b/datasette/cli.py index 42697c56..23fd0f15 100644 --- a/datasette/cli.py +++ b/datasette/cli.py @@ -30,7 +30,7 @@ def build(files, inspect_file): @click.argument('files', type=click.Path(exists=True), nargs=-1) @click.option( '-n', '--name', default='datasette', - help='Application name to use when deploying to Now' + help='Application name to use when deploying to Now (ignored for Heroku)' ) @click.option( '-m', '--metadata', type=click.File(mode='r'), @@ -47,23 +47,27 @@ def publish(publisher, files, name, metadata, extra_options, force, **extra_meta """ Publish specified SQLite database files to the internet along with a datasette API. - Only current option for PUBLISHER is 'now'. You must have Zeit Now installed: - https://zeit.co/now + Options for PUBLISHER: + * 'now' - You must have Zeit Now installed: https://zeit.co/now + * 'heroku' - You must have Heroku installed: https://cli.heroku.com/ Example usage: datasette publish now my-database.db """ - if publisher == 'now': - if not shutil.which('now'): + def _fail_if_publish_binary_not_installed(binary, publish_target, install_link): + """Exit (with error message) if ``binary` isn't installed""" + if not shutil.which(binary): click.secho( - ' The publish command requires "now" to be installed and configured ', + f" Publishing to {publish_target} requires {binary} to be installed and configured ", bg='red', fg='white', bold=True, - err=True, + err=True ) - click.echo('Follow the instructions at https://zeit.co/now#whats-now', err=True) + click.echo(f"Follow the instructions at {install_link}", err=True) sys.exit(1) + if publisher == 'now': + _fail_if_publish_binary_not_installed('now', 'Zeit Now', 'https://zeit.co/now') with temporary_docker_directory(files, name, metadata, extra_options, extra_metadata): if force: call(['now', '--force']) @@ -71,13 +75,20 @@ def publish(publisher, files, name, metadata, extra_options, force, **extra_meta call('now') elif publisher == 'heroku': - # FIXME: need to verify we have heroku, heroku-builds, and are logged in (ugh) + _fail_if_publish_binary_not_installed('heroku', 'Heroku', 'https://cli.heroku.com') + + # Check for heroku-builds plugin + plugins = [line.split()[0] for line in check_output(['heroku', 'plugins']).splitlines()] + if 'heroku-builds' not in plugins: + click.echo('Publishing to Heroku requires the heroku-builds plugin to be installed.') + click.confirm('Install it? (this will run `heroku plugins:install heroku-builds`)', abort=True) + call(["heroku", "plugins:install", "heroku-builds"]) + with temporary_heroku_directory(files, name, metadata, extra_options, extra_metadata): create_output = check_output(['heroku', 'apps:create', '--json']) app_name = json.loads(create_output)["name"] call(["heroku", "builds:create", "-a", app_name]) - @cli.command() @click.argument('files', type=click.Path(exists=True), nargs=-1, required=True) @click.option(