mirror of
https://github.com/simonw/datasette.git
synced 2025-12-10 16:51:24 +01:00
New --setting to replace --config, closes #992
This commit is contained in:
parent
4bac9f18f9
commit
3159263f05
3 changed files with 93 additions and 4 deletions
|
|
@ -2,6 +2,7 @@ import asyncio
|
||||||
import uvicorn
|
import uvicorn
|
||||||
import click
|
import click
|
||||||
from click import formatting
|
from click import formatting
|
||||||
|
from click.types import CompositeParamType
|
||||||
from click_default_group import DefaultGroup
|
from click_default_group import DefaultGroup
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
|
@ -29,6 +30,7 @@ from .version import __version__
|
||||||
|
|
||||||
|
|
||||||
class Config(click.ParamType):
|
class Config(click.ParamType):
|
||||||
|
# This will be removed in Datasette 1.0 in favour of class Setting
|
||||||
name = "config"
|
name = "config"
|
||||||
|
|
||||||
def convert(self, config, param, ctx):
|
def convert(self, config, param, ctx):
|
||||||
|
|
@ -63,6 +65,39 @@ class Config(click.ParamType):
|
||||||
self.fail("Invalid option")
|
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.group(cls=DefaultGroup, default="serve", default_if_no_args=True)
|
||||||
@click.version_option(version=__version__)
|
@click.version_option(version=__version__)
|
||||||
def cli():
|
def cli():
|
||||||
|
|
@ -330,7 +365,14 @@ def uninstall(packages, yes):
|
||||||
@click.option(
|
@click.option(
|
||||||
"--config",
|
"--config",
|
||||||
type=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,
|
multiple=True,
|
||||||
)
|
)
|
||||||
@click.option(
|
@click.option(
|
||||||
|
|
@ -372,6 +414,7 @@ def serve(
|
||||||
static,
|
static,
|
||||||
memory,
|
memory,
|
||||||
config,
|
config,
|
||||||
|
settings,
|
||||||
secret,
|
secret,
|
||||||
root,
|
root,
|
||||||
get,
|
get,
|
||||||
|
|
@ -410,6 +453,15 @@ def serve(
|
||||||
if metadata:
|
if metadata:
|
||||||
metadata_data = parse_metadata(metadata.read())
|
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(
|
kwargs = dict(
|
||||||
immutables=immutable,
|
immutables=immutable,
|
||||||
cache_headers=not reload,
|
cache_headers=not reload,
|
||||||
|
|
@ -420,7 +472,7 @@ def serve(
|
||||||
template_dir=template_dir,
|
template_dir=template_dir,
|
||||||
plugins_dir=plugins_dir,
|
plugins_dir=plugins_dir,
|
||||||
static_mounts=static,
|
static_mounts=static,
|
||||||
config=dict(config),
|
config=combined_config,
|
||||||
memory=memory,
|
memory=memory,
|
||||||
secret=secret,
|
secret=secret,
|
||||||
version_note=version_note,
|
version_note=version_note,
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,10 @@ Options:
|
||||||
--plugins-dir DIRECTORY Path to directory containing custom plugins
|
--plugins-dir DIRECTORY Path to directory containing custom plugins
|
||||||
--static MOUNT:DIRECTORY Serve static files from this directory at /MOUNT/...
|
--static MOUNT:DIRECTORY Serve static files from this directory at /MOUNT/...
|
||||||
--memory Make :memory: database available
|
--memory Make :memory: database available
|
||||||
--config CONFIG Set config option using configname:value
|
--config CONFIG Deprecated: set config option using configname:value. Use
|
||||||
docs.datasette.io/en/stable/config.html
|
--setting instead.
|
||||||
|
|
||||||
|
--setting SETTING... Setting, see docs.datasette.io/en/stable/config.html
|
||||||
--secret TEXT Secret used for signing secure values, such as signed
|
--secret TEXT Secret used for signing secure values, such as signed
|
||||||
cookies
|
cookies
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ from .fixtures import (
|
||||||
TestClient as _TestClient,
|
TestClient as _TestClient,
|
||||||
EXPECTED_PLUGINS,
|
EXPECTED_PLUGINS,
|
||||||
)
|
)
|
||||||
|
import asyncio
|
||||||
from datasette.plugins import DEFAULT_PLUGINS
|
from datasette.plugins import DEFAULT_PLUGINS
|
||||||
from datasette.cli import cli, serve
|
from datasette.cli import cli, serve
|
||||||
from datasette.version import __version__
|
from datasette.version import __version__
|
||||||
|
|
@ -17,6 +18,13 @@ import textwrap
|
||||||
from unittest import mock
|
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):
|
def test_inspect_cli(app_client):
|
||||||
runner = CliRunner()
|
runner = CliRunner()
|
||||||
result = runner.invoke(cli, ["inspect", "fixtures.db"])
|
result = runner.invoke(cli, ["inspect", "fixtures.db"])
|
||||||
|
|
@ -115,6 +123,7 @@ def test_metadata_yaml():
|
||||||
static=[],
|
static=[],
|
||||||
memory=False,
|
memory=False,
|
||||||
config=[],
|
config=[],
|
||||||
|
settings=[],
|
||||||
secret=None,
|
secret=None,
|
||||||
root=False,
|
root=False,
|
||||||
version_note=None,
|
version_note=None,
|
||||||
|
|
@ -163,3 +172,30 @@ def test_version():
|
||||||
runner = CliRunner()
|
runner = CliRunner()
|
||||||
result = runner.invoke(cli, ["--version"])
|
result = runner.invoke(cli, ["--version"])
|
||||||
assert result.output == f"cli, version {__version__}\n"
|
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
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue