2020-06-11 16:02:03 +00:00
|
|
|
import os
|
publish_subcommand hook + default plugins mechanism, used for publish heroku/now (#349)
This change introduces a new plugin hook, publish_subcommand, which can be
used to implement new subcommands for the "datasette publish" command family.
I've used this new hook to refactor out the "publish now" and "publish heroku"
implementations into separate modules. I've also added unit tests for these
two publishers, mocking the subprocess.call and subprocess.check_output
functions.
As part of this, I introduced a mechanism for loading default plugins. These
are defined in the new "default_plugins" list inside datasette/app.py
Closes #217 (Plugin support for datasette publish)
Closes #348 (Unit tests for "datasette publish")
Refs #14, #59, #102, #103, #146, #236, #347
2018-07-26 05:15:59 +00:00
|
|
|
import shutil
|
|
|
|
import sys
|
|
|
|
|
2023-08-23 02:07:10 +00:00
|
|
|
import click
|
|
|
|
|
|
|
|
from ..utils import StaticMount
|
|
|
|
|
publish_subcommand hook + default plugins mechanism, used for publish heroku/now (#349)
This change introduces a new plugin hook, publish_subcommand, which can be
used to implement new subcommands for the "datasette publish" command family.
I've used this new hook to refactor out the "publish now" and "publish heroku"
implementations into separate modules. I've also added unit tests for these
two publishers, mocking the subprocess.call and subprocess.check_output
functions.
As part of this, I introduced a mechanism for loading default plugins. These
are defined in the new "default_plugins" list inside datasette/app.py
Closes #217 (Plugin support for datasette publish)
Closes #348 (Unit tests for "datasette publish")
Refs #14, #59, #102, #103, #146, #236, #347
2018-07-26 05:15:59 +00:00
|
|
|
|
|
|
|
def add_common_publish_arguments_and_options(subcommand):
|
2019-05-04 02:15:14 +00:00
|
|
|
for decorator in reversed(
|
|
|
|
(
|
|
|
|
click.argument("files", type=click.Path(exists=True), nargs=-1),
|
|
|
|
click.option(
|
|
|
|
"-m",
|
|
|
|
"--metadata",
|
|
|
|
type=click.File(mode="r"),
|
2020-04-02 19:30:53 +00:00
|
|
|
help="Path to JSON/YAML file containing metadata to publish",
|
2019-05-04 02:15:14 +00:00
|
|
|
),
|
|
|
|
click.option(
|
|
|
|
"--extra-options", help="Extra options to pass to datasette serve"
|
|
|
|
),
|
|
|
|
click.option(
|
2021-03-23 16:19:41 +00:00
|
|
|
"--branch", help="Install datasette from a GitHub branch e.g. main"
|
2019-05-04 02:15:14 +00:00
|
|
|
),
|
|
|
|
click.option(
|
|
|
|
"--template-dir",
|
|
|
|
type=click.Path(exists=True, file_okay=False, dir_okay=True),
|
|
|
|
help="Path to directory containing custom templates",
|
|
|
|
),
|
|
|
|
click.option(
|
|
|
|
"--plugins-dir",
|
|
|
|
type=click.Path(exists=True, file_okay=False, dir_okay=True),
|
|
|
|
help="Path to directory containing custom plugins",
|
|
|
|
),
|
|
|
|
click.option(
|
|
|
|
"--static",
|
|
|
|
type=StaticMount(),
|
2019-11-26 02:31:42 +00:00
|
|
|
help="Serve static files from this directory at /MOUNT/...",
|
2019-05-04 02:15:14 +00:00
|
|
|
multiple=True,
|
|
|
|
),
|
|
|
|
click.option(
|
|
|
|
"--install",
|
|
|
|
help="Additional packages (e.g. plugins) to install",
|
|
|
|
multiple=True,
|
|
|
|
),
|
2019-07-08 02:06:31 +00:00
|
|
|
click.option(
|
|
|
|
"--plugin-secret",
|
|
|
|
nargs=3,
|
|
|
|
type=(str, str, str),
|
|
|
|
callback=validate_plugin_secret,
|
|
|
|
multiple=True,
|
|
|
|
help="Secrets to pass to plugins, e.g. --plugin-secret datasette-auth-github client_id xxx",
|
|
|
|
),
|
2019-05-04 02:15:14 +00:00
|
|
|
click.option(
|
|
|
|
"--version-note", help="Additional note to show on /-/versions"
|
|
|
|
),
|
2020-06-11 16:02:03 +00:00
|
|
|
click.option(
|
|
|
|
"--secret",
|
|
|
|
help="Secret used for signing secure values, such as signed cookies",
|
|
|
|
envvar="DATASETTE_PUBLISH_SECRET",
|
|
|
|
default=lambda: os.urandom(32).hex(),
|
|
|
|
),
|
2019-05-04 02:15:14 +00:00
|
|
|
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"),
|
|
|
|
click.option("--about", help="About label for metadata"),
|
|
|
|
click.option("--about_url", help="About URL for metadata"),
|
|
|
|
)
|
|
|
|
):
|
publish_subcommand hook + default plugins mechanism, used for publish heroku/now (#349)
This change introduces a new plugin hook, publish_subcommand, which can be
used to implement new subcommands for the "datasette publish" command family.
I've used this new hook to refactor out the "publish now" and "publish heroku"
implementations into separate modules. I've also added unit tests for these
two publishers, mocking the subprocess.call and subprocess.check_output
functions.
As part of this, I introduced a mechanism for loading default plugins. These
are defined in the new "default_plugins" list inside datasette/app.py
Closes #217 (Plugin support for datasette publish)
Closes #348 (Unit tests for "datasette publish")
Refs #14, #59, #102, #103, #146, #236, #347
2018-07-26 05:15:59 +00:00
|
|
|
subcommand = decorator(subcommand)
|
|
|
|
return subcommand
|
|
|
|
|
|
|
|
|
|
|
|
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(
|
|
|
|
"Publishing to {publish_target} requires {binary} to be installed and configured".format(
|
|
|
|
publish_target=publish_target, binary=binary
|
|
|
|
),
|
|
|
|
bg="red",
|
|
|
|
fg="white",
|
|
|
|
bold=True,
|
|
|
|
err=True,
|
|
|
|
)
|
|
|
|
click.echo(
|
2020-11-15 23:24:22 +00:00
|
|
|
f"Follow the instructions at {install_link}",
|
publish_subcommand hook + default plugins mechanism, used for publish heroku/now (#349)
This change introduces a new plugin hook, publish_subcommand, which can be
used to implement new subcommands for the "datasette publish" command family.
I've used this new hook to refactor out the "publish now" and "publish heroku"
implementations into separate modules. I've also added unit tests for these
two publishers, mocking the subprocess.call and subprocess.check_output
functions.
As part of this, I introduced a mechanism for loading default plugins. These
are defined in the new "default_plugins" list inside datasette/app.py
Closes #217 (Plugin support for datasette publish)
Closes #348 (Unit tests for "datasette publish")
Refs #14, #59, #102, #103, #146, #236, #347
2018-07-26 05:15:59 +00:00
|
|
|
err=True,
|
|
|
|
)
|
|
|
|
sys.exit(1)
|
2019-07-08 02:06:31 +00:00
|
|
|
|
|
|
|
|
|
|
|
def validate_plugin_secret(ctx, param, value):
|
|
|
|
for plugin_name, plugin_setting, setting_value in value:
|
|
|
|
if "'" in setting_value:
|
|
|
|
raise click.BadParameter("--plugin-secret cannot contain single quotes")
|
|
|
|
return value
|