From 404fa2252b070952ff1d1fc8bafc153789f36ada Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Wed, 18 Apr 2018 07:48:34 -0700 Subject: [PATCH] datasette publish/package --install option, closes #223 Allows you to specify one or more additional packages to be installed, useful for deploying plugins. --- datasette/cli.py | 15 +++++++++++++++ datasette/utils.py | 47 +++++++++++++++++++++++++++++++++++---------- tests/test_utils.py | 2 ++ 3 files changed, 54 insertions(+), 10 deletions(-) diff --git a/datasette/cli.py b/datasette/cli.py index 7314d2a4..2f9e1d43 100644 --- a/datasette/cli.py +++ b/datasette/cli.py @@ -81,6 +81,11 @@ def inspect(files, inspect_file, sqlite_extensions): help="mountpoint:path-to-directory for serving static files", multiple=True, ) +@click.option( + "--install", + help="Additional packages (e.g. plugins) to install", + multiple=True, +) @click.option("--title", help="Title for metadata") @click.option("--license", help="License label for metadata") @click.option("--license_url", help="License URL for metadata") @@ -97,6 +102,7 @@ def publish( template_dir, plugins_dir, static, + install, **extra_metadata ): """ @@ -140,6 +146,7 @@ def publish( template_dir, plugins_dir, static, + install, extra_metadata, ): if force: @@ -175,6 +182,7 @@ def publish( template_dir, plugins_dir, static, + install, extra_metadata, ): create_output = check_output(["heroku", "apps:create", "--json"]).decode( @@ -286,6 +294,11 @@ def skeleton(files, metadata, sqlite_extensions): help="mountpoint:path-to-directory for serving static files", multiple=True, ) +@click.option( + "--install", + help="Additional packages (e.g. plugins) to install", + multiple=True, +) @click.option("--title", help="Title for metadata") @click.option("--license", help="License label for metadata") @click.option("--license_url", help="License URL for metadata") @@ -300,6 +313,7 @@ def package( template_dir, plugins_dir, static, + install, **extra_metadata ): "Package specified SQLite files into a new datasette Docker container" @@ -321,6 +335,7 @@ def package( template_dir, plugins_dir, static, + install, extra_metadata, ): args = ["docker", "build"] diff --git a/datasette/utils.py b/datasette/utils.py index 7ba663f0..09795f43 100644 --- a/datasette/utils.py +++ b/datasette/utils.py @@ -188,7 +188,7 @@ def escape_sqlite(s): return '[{}]'.format(s) -def make_dockerfile(files, metadata_file, extra_options, branch, template_dir, plugins_dir, static): +def make_dockerfile(files, metadata_file, extra_options, branch, template_dir, plugins_dir, static, install): cmd = ['"datasette"', '"serve"', '"--host"', '"0.0.0.0"'] cmd.append('"' + '", "'.join(files) + '"') cmd.extend(['"--cors"', '"--port"', '"8001"', '"--inspect-file"', '"inspect-data.json"']) @@ -204,11 +204,15 @@ def make_dockerfile(files, metadata_file, extra_options, branch, template_dir, p if extra_options: for opt in extra_options.split(): cmd.append('"{}"'.format(opt)) + install_from = 'datasette' if branch: - install_from = 'https://github.com/simonw/datasette/archive/{}.zip'.format( + install = ['https://github.com/simonw/datasette/archive/{}.zip'.format( branch - ) + )] + list(install) + else: + install = ['datasette'] + list(install) + return ''' FROM python:3 COPY . /app @@ -219,12 +223,23 @@ EXPOSE 8001 CMD [{cmd}]'''.format( files=' '.join(files), cmd=', '.join(cmd), - install_from=install_from, + install_from=' '.join(install), ).strip() @contextmanager -def temporary_docker_directory(files, name, metadata, extra_options, branch, template_dir, plugins_dir, static, extra_metadata=None): +def temporary_docker_directory( + files, + name, + metadata, + extra_options, + branch, + template_dir, + plugins_dir, + static, + install, + extra_metadata=None +): extra_metadata = extra_metadata or {} tmp = tempfile.TemporaryDirectory() # We create a datasette folder in there to get a nicer now deploy name @@ -252,6 +267,7 @@ def temporary_docker_directory(files, name, metadata, extra_options, branch, tem template_dir, plugins_dir, static, + install, ) os.chdir(datasette_dir) if metadata_content: @@ -281,7 +297,18 @@ def temporary_docker_directory(files, name, metadata, extra_options, branch, tem @contextmanager -def temporary_heroku_directory(files, name, metadata, extra_options, branch, template_dir, plugins_dir, static, extra_metadata=None): +def temporary_heroku_directory( + files, + name, + metadata, + extra_options, + branch, + template_dir, + plugins_dir, + static, + install, + extra_metadata=None +): # FIXME: lots of duplicated code from above extra_metadata = extra_metadata or {} @@ -311,13 +338,13 @@ def temporary_heroku_directory(files, name, metadata, extra_options, branch, tem open('runtime.txt', 'w').write('python-3.6.3') if branch: - install_from = 'https://github.com/simonw/datasette/archive/{branch}.zip'.format( + install = ['https://github.com/simonw/datasette/archive/{branch}.zip'.format( branch=branch - ) + )] + list(install) else: - install_from = 'datasette' + install = ['datasette'] + list(install) - open('requirements.txt', 'w').write(install_from) + open('requirements.txt', 'w').write('\n'.join(install)) os.mkdir('bin') open('bin/post_compile', 'w').write('datasette inspect --inspect-file inspect-data.json') diff --git a/tests/test_utils.py b/tests/test_utils.py index 3b3b8946..8323d2bd 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -197,6 +197,7 @@ def test_temporary_docker_directory_uses_hard_link(): template_dir=None, plugins_dir=None, static=[], + install=[], ) as temp_docker: hello = os.path.join(temp_docker, 'hello') assert 'world' == open(hello).read() @@ -221,6 +222,7 @@ def test_temporary_docker_directory_uses_copy_if_hard_link_fails(mock_link): template_dir=None, plugins_dir=None, static=[], + install=[], ) as temp_docker: hello = os.path.join(temp_docker, 'hello') assert 'world' == open(hello).read()