From 07fee41598159d0c25a7216ad8a89cdefdd0f98f Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Wed, 29 Jan 2020 11:47:04 -0800 Subject: [PATCH] -p argument for datasette package, plus tests - refs #661 --- datasette/cli.py | 5 ++++ datasette/utils/__init__.py | 8 ++++-- tests/test_package.py | 53 +++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 tests/test_package.py diff --git a/datasette/cli.py b/datasette/cli.py index b71275d5..67d00fbb 100644 --- a/datasette/cli.py +++ b/datasette/cli.py @@ -167,6 +167,9 @@ def plugins(all, plugins_dir): ) @click.option("--spatialite", is_flag=True, help="Enable SpatialLite extension") @click.option("--version-note", help="Additional note to show on /-/versions") +@click.option( + "-p", "--port", default=8001, help="Port to run the server on, defaults to 8001", +) @click.option("--title", help="Title for metadata") @click.option("--license", help="License label for metadata") @click.option("--license_url", help="License URL for metadata") @@ -186,6 +189,7 @@ def package( install, spatialite, version_note, + port, **extra_metadata ): "Package specified SQLite files into a new datasette Docker container" @@ -211,6 +215,7 @@ def package( spatialite, version_note, extra_metadata, + port=port, ): args = ["docker", "build"] if tag: diff --git a/datasette/utils/__init__.py b/datasette/utils/__init__.py index ab5f995b..a8db83a7 100644 --- a/datasette/utils/__init__.py +++ b/datasette/utils/__init__.py @@ -275,6 +275,7 @@ def make_dockerfile( spatialite, version_note, environment_variables=None, + port=8001, ): cmd = ["datasette", "serve", "--host", "0.0.0.0"] for filename in files: @@ -313,8 +314,8 @@ WORKDIR /app {environment_variables} RUN pip install -U {install_from} RUN datasette inspect {files} --inspect-file inspect-data.json -ENV PORT 8001 -EXPOSE 8001 +ENV PORT {port} +EXPOSE {port} CMD {cmd}""".format( environment_variables="\n".join( [ @@ -326,6 +327,7 @@ CMD {cmd}""".format( cmd=cmd, install_from=" ".join(install), spatialite_extras=SPATIALITE_DOCKERFILE_EXTRAS if spatialite else "", + port=port, ).strip() @@ -344,6 +346,7 @@ def temporary_docker_directory( version_note, extra_metadata=None, environment_variables=None, + port=8001, ): extra_metadata = extra_metadata or {} tmp = tempfile.TemporaryDirectory() @@ -373,6 +376,7 @@ def temporary_docker_directory( spatialite, version_note, environment_variables, + port=port, ) os.chdir(datasette_dir) if metadata_content: diff --git a/tests/test_package.py b/tests/test_package.py new file mode 100644 index 00000000..f0cbe88f --- /dev/null +++ b/tests/test_package.py @@ -0,0 +1,53 @@ +from click.testing import CliRunner +from datasette import cli +from unittest import mock +import pathlib +import json + + +class CaptureDockerfile: + def __call__(self, _): + self.captured = (pathlib.Path() / "Dockerfile").read_text() + + +EXPECTED_DOCKERFILE = """ +FROM python:3.8 +COPY . /app +WORKDIR /app + + +RUN pip install -U datasette +RUN datasette inspect test.db --inspect-file inspect-data.json +ENV PORT {port} +EXPOSE {port} +CMD datasette serve --host 0.0.0.0 -i test.db --cors --inspect-file inspect-data.json --port $PORT +""".strip() + + +@mock.patch("shutil.which") +@mock.patch("datasette.cli.call") +def test_package(mock_call, mock_which): + mock_which.return_value = True + runner = CliRunner() + capture = CaptureDockerfile() + mock_call.side_effect = capture + with runner.isolated_filesystem(): + open("test.db", "w").write("data") + result = runner.invoke(cli.cli, ["package", "test.db"]) + assert 0 == result.exit_code + mock_call.assert_has_calls([mock.call(["docker", "build", "."])]) + assert EXPECTED_DOCKERFILE.format(port=8001) == capture.captured + + +@mock.patch("shutil.which") +@mock.patch("datasette.cli.call") +def test_package_with_port(mock_call, mock_which): + mock_which.return_value = True + capture = CaptureDockerfile() + mock_call.side_effect = capture + runner = CliRunner() + with runner.isolated_filesystem(): + open("test.db", "w").write("data") + result = runner.invoke(cli.cli, ["package", "test.db", "-p", "8080"]) + assert 0 == result.exit_code + assert EXPECTED_DOCKERFILE.format(port=8080) == capture.captured