New --setting to replace --config, closes #992

pull/1112/head
Simon Willison 2020-11-24 12:01:47 -08:00
rodzic 4bac9f18f9
commit 3159263f05
3 zmienionych plików z 93 dodań i 4 usunięć

Wyświetl plik

@ -2,6 +2,7 @@ import asyncio
import uvicorn
import click
from click import formatting
from click.types import CompositeParamType
from click_default_group import DefaultGroup
import json
import os
@ -29,6 +30,7 @@ from .version import __version__
class Config(click.ParamType):
# This will be removed in Datasette 1.0 in favour of class Setting
name = "config"
def convert(self, config, param, ctx):
@ -63,6 +65,39 @@ class Config(click.ParamType):
self.fail("Invalid option")
class Setting(CompositeParamType):
name = "setting"
arity = 2
def convert(self, config, param, ctx):
name, value = config
if name not in DEFAULT_CONFIG:
self.fail(
f"{name} is not a valid option (--help-config to see all)",
param,
ctx,
)
return
# Type checking
default = DEFAULT_CONFIG[name]
if isinstance(default, bool):
try:
return name, value_as_boolean(value)
except ValueAsBooleanError:
self.fail(f'"{name}" should be on/off/true/false/1/0', param, ctx)
return
elif isinstance(default, int):
if not value.isdigit():
self.fail(f'"{name}" should be an integer', param, ctx)
return
return name, int(value)
elif isinstance(default, str):
return name, value
else:
# Should never happen:
self.fail("Invalid option")
@click.group(cls=DefaultGroup, default="serve", default_if_no_args=True)
@click.version_option(version=__version__)
def cli():
@ -330,7 +365,14 @@ def uninstall(packages, yes):
@click.option(
"--config",
type=Config(),
help="Set config option using configname:value docs.datasette.io/en/stable/config.html",
help="Deprecated: set config option using configname:value. Use --setting instead.",
multiple=True,
)
@click.option(
"--setting",
"settings",
type=Setting(),
help="Setting, see docs.datasette.io/en/stable/config.html",
multiple=True,
)
@click.option(
@ -372,6 +414,7 @@ def serve(
static,
memory,
config,
settings,
secret,
root,
get,
@ -410,6 +453,15 @@ def serve(
if metadata:
metadata_data = parse_metadata(metadata.read())
combined_config = {}
if config:
click.echo(
"--config name:value will be deprecated in Datasette 1.0, use --setting name value instead",
err=True,
)
combined_config.update(config)
combined_config.update(settings)
kwargs = dict(
immutables=immutable,
cache_headers=not reload,
@ -420,7 +472,7 @@ def serve(
template_dir=template_dir,
plugins_dir=plugins_dir,
static_mounts=static,
config=dict(config),
config=combined_config,
memory=memory,
secret=secret,
version_note=version_note,

Wyświetl plik

@ -25,9 +25,10 @@ Options:
--plugins-dir DIRECTORY Path to directory containing custom plugins
--static MOUNT:DIRECTORY Serve static files from this directory at /MOUNT/...
--memory Make :memory: database available
--config CONFIG Set config option using configname:value
docs.datasette.io/en/stable/config.html
--config CONFIG Deprecated: set config option using configname:value. Use
--setting instead.
--setting SETTING... Setting, see docs.datasette.io/en/stable/config.html
--secret TEXT Secret used for signing secure values, such as signed
cookies

Wyświetl plik

@ -4,6 +4,7 @@ from .fixtures import (
TestClient as _TestClient,
EXPECTED_PLUGINS,
)
import asyncio
from datasette.plugins import DEFAULT_PLUGINS
from datasette.cli import cli, serve
from datasette.version import __version__
@ -17,6 +18,13 @@ import textwrap
from unittest import mock
@pytest.fixture
def ensure_eventloop():
# Workaround for "Event loop is closed" error
if asyncio.get_event_loop().is_closed():
asyncio.set_event_loop(asyncio.new_event_loop())
def test_inspect_cli(app_client):
runner = CliRunner()
result = runner.invoke(cli, ["inspect", "fixtures.db"])
@ -115,6 +123,7 @@ def test_metadata_yaml():
static=[],
memory=False,
config=[],
settings=[],
secret=None,
root=False,
version_note=None,
@ -163,3 +172,30 @@ def test_version():
runner = CliRunner()
result = runner.invoke(cli, ["--version"])
assert result.output == f"cli, version {__version__}\n"
def test_setting(ensure_eventloop):
runner = CliRunner()
result = runner.invoke(
cli, ["--setting", "default_page_size", "5", "--get", "/-/config.json"]
)
assert result.exit_code == 0, result.output
assert json.loads(result.output)["default_page_size"] == 5
def test_setting_type_validation(ensure_eventloop):
runner = CliRunner(mix_stderr=False)
result = runner.invoke(cli, ["--setting", "default_page_size", "dog"])
assert result.exit_code == 2
assert '"default_page_size" should be an integer' in result.stderr
def test_config_deprecated(ensure_eventloop):
# The --config option should show a deprecation message
runner = CliRunner(mix_stderr=False)
result = runner.invoke(
cli, ["--config", "allow_download:off", "--get", "/-/config.json"]
)
assert result.exit_code == 0
assert not json.loads(result.output)["allow_download"]
assert "will be deprecated in" in result.stderr