diff --git a/README.md b/README.md index 9cff2732..579fe843 100644 --- a/README.md +++ b/README.md @@ -141,6 +141,7 @@ This will create a docker image containing both the datasette application and th -m, --metadata FILENAME Path to JSON file containing metadata to publish --extra-options TEXT Extra options to pass to datasette serve --force Pass --force option to now + --branch TEXT Install datasette from a GitHub branch e.g. master --title TEXT Title for metadata --license TEXT License label for metadata --license_url TEXT License URL for metadata @@ -162,6 +163,7 @@ If you have docker installed you can use `datasette package` to create a new Doc optionally use name:tag format -m, --metadata FILENAME Path to JSON file containing metadata to publish --extra-options TEXT Extra options to pass to datasette serve + --branch TEXT Install datasette from a GitHub branch e.g. master --title TEXT Title for metadata --license TEXT License label for metadata --license_url TEXT License URL for metadata diff --git a/datasette/cli.py b/datasette/cli.py index 646f90bb..d292d388 100644 --- a/datasette/cli.py +++ b/datasette/cli.py @@ -39,12 +39,13 @@ def build(files, inspect_file): ) @click.option('--extra-options', help='Extra options to pass to datasette serve') @click.option('--force', is_flag=True, help='Pass --force option to now') +@click.option('--branch', help='Install datasette from a GitHub branch e.g. master') @click.option('--title', help='Title for metadata') @click.option('--license', help='License label for metadata') @click.option('--license_url', help='License URL for metadata') @click.option('--source', help='Source label for metadata') @click.option('--source_url', help='Source URL for metadata') -def publish(publisher, files, name, metadata, extra_options, force, **extra_metadata): +def publish(publisher, files, name, metadata, extra_options, force, branch, **extra_metadata): """ Publish specified SQLite database files to the internet along with a datasette API. @@ -64,7 +65,7 @@ def publish(publisher, files, name, metadata, extra_options, force, **extra_meta click.echo('Follow the instructions at https://zeit.co/now#whats-now', err=True) sys.exit(1) - with temporary_docker_directory(files, name, metadata, extra_options, extra_metadata): + with temporary_docker_directory(files, name, metadata, extra_options, branch, extra_metadata): if force: call(['now', '--force']) else: @@ -82,12 +83,13 @@ def publish(publisher, files, name, metadata, extra_options, force, **extra_meta help='Path to JSON file containing metadata to publish' ) @click.option('--extra-options', help='Extra options to pass to datasette serve') +@click.option('--branch', help='Install datasette from a GitHub branch e.g. master') @click.option('--title', help='Title for metadata') @click.option('--license', help='License label for metadata') @click.option('--license_url', help='License URL for metadata') @click.option('--source', help='Source label for metadata') @click.option('--source_url', help='Source URL for metadata') -def package(files, tag, metadata, extra_options, **extra_metadata): +def package(files, tag, metadata, extra_options, branch, **extra_metadata): "Package specified SQLite files into a new datasette Docker container" if not shutil.which('docker'): click.secho( @@ -98,7 +100,7 @@ def package(files, tag, metadata, extra_options, **extra_metadata): err=True, ) sys.exit(1) - with temporary_docker_directory(files, 'datasette', metadata, extra_options, extra_metadata): + with temporary_docker_directory(files, 'datasette', metadata, extra_options, branch, extra_metadata): args = ['docker', 'build'] if tag: args.append('-t') diff --git a/datasette/utils.py b/datasette/utils.py index b30a8b97..1b0d3531 100644 --- a/datasette/utils.py +++ b/datasette/utils.py @@ -148,7 +148,7 @@ def escape_sqlite_table_name(s): return '[{}]'.format(s) -def make_dockerfile(files, metadata_file, extra_options=''): +def make_dockerfile(files, metadata_file, extra_options='', branch=None): cmd = ['"datasette"', '"serve"', '"--host"', '"0.0.0.0"'] cmd.append('"' + '", "'.join(files) + '"') cmd.extend(['"--cors"', '"--port"', '"8001"', '"--inspect-file"', '"inspect-data.json"']) @@ -157,21 +157,27 @@ def make_dockerfile(files, metadata_file, extra_options=''): 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( + branch + ) return ''' FROM python:3 COPY . /app WORKDIR /app -RUN pip install datasette -RUN datasette build {} --inspect-file inspect-data.json +RUN pip install {install_from} +RUN datasette build {files} --inspect-file inspect-data.json EXPOSE 8001 -CMD [{}]'''.format( - ' '.join(files), - ', '.join(cmd) +CMD [{cmd}]'''.format( + files=' '.join(files), + cmd=', '.join(cmd), + install_from=install_from, ).strip() @contextmanager -def temporary_docker_directory(files, name, metadata, extra_options, extra_metadata=None): +def temporary_docker_directory(files, name, metadata, extra_options, branch=None, 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 @@ -191,7 +197,7 @@ def temporary_docker_directory(files, name, metadata, extra_options, extra_metad if value: metadata_content[key] = value try: - dockerfile = make_dockerfile(file_names, metadata_content and 'metadata.json', extra_options) + dockerfile = make_dockerfile(file_names, metadata_content and 'metadata.json', extra_options, branch) os.chdir(datasette_dir) if metadata_content: open('metadata.json', 'w').write(json.dumps(metadata_content, indent=2))