kopia lustrzana https://github.com/simonw/datasette
Treat plugins in metadata as if they were in config, closes #2248
rodzic
d4bc2b2dfc
commit
be4f02335f
|
@ -74,6 +74,7 @@ from .utils import (
|
|||
find_spatialite,
|
||||
format_bytes,
|
||||
module_from_path,
|
||||
move_plugins,
|
||||
parse_metadata,
|
||||
resolve_env_secrets,
|
||||
resolve_routes,
|
||||
|
@ -341,6 +342,11 @@ class Datasette:
|
|||
with config_files[0].open() as fp:
|
||||
config = parse_metadata(fp.read())
|
||||
|
||||
# Move any "plugins" settings from metadata to config - updates them in place
|
||||
metadata = metadata or {}
|
||||
config = config or {}
|
||||
move_plugins(metadata, config)
|
||||
|
||||
self._metadata_local = metadata or {}
|
||||
self.sqlite_extensions = []
|
||||
for extension in sqlite_extensions or []:
|
||||
|
|
|
@ -1287,3 +1287,43 @@ def make_slot_function(name, datasette, request, **kwargs):
|
|||
return markupsafe.Markup("".join(html_bits))
|
||||
|
||||
return inner
|
||||
|
||||
|
||||
def move_plugins(source, destination):
|
||||
"""
|
||||
Move 'plugins' keys from source to destination dictionary. Creates hierarchy in destination if needed.
|
||||
After moving, recursively remove any keys in the source that are left empty.
|
||||
"""
|
||||
|
||||
def recursive_move(src, dest, path=None):
|
||||
if path is None:
|
||||
path = []
|
||||
for key, value in list(src.items()):
|
||||
new_path = path + [key]
|
||||
if key == "plugins":
|
||||
# Navigate and create the hierarchy in destination if needed
|
||||
d = dest
|
||||
for step in path:
|
||||
d = d.setdefault(step, {})
|
||||
# Move the plugins
|
||||
d[key] = value
|
||||
# Remove the plugins from source
|
||||
src.pop(key, None)
|
||||
elif isinstance(value, dict):
|
||||
recursive_move(value, dest, new_path)
|
||||
# After moving, check if the current dictionary is empty and remove it if so
|
||||
if not value:
|
||||
src.pop(key, None)
|
||||
|
||||
def prune_empty_dicts(d):
|
||||
"""
|
||||
Recursively prune all empty dictionaries from a given dictionary.
|
||||
"""
|
||||
for key, value in list(d.items()):
|
||||
if isinstance(value, dict):
|
||||
prune_empty_dicts(value)
|
||||
if value == {}:
|
||||
d.pop(key, None)
|
||||
|
||||
recursive_move(source, destination)
|
||||
prune_empty_dicts(source)
|
||||
|
|
|
@ -1458,3 +1458,54 @@ async def test_hook_register_events():
|
|||
datasette = Datasette(memory=True)
|
||||
await datasette.invoke_startup()
|
||||
assert any(k.__name__ == "OneEvent" for k in datasette.event_classes)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"metadata,config,expected_metadata,expected_config",
|
||||
(
|
||||
(
|
||||
# Instance level
|
||||
{"plugins": {"datasette-foo": "bar"}},
|
||||
{},
|
||||
{},
|
||||
{"plugins": {"datasette-foo": "bar"}},
|
||||
),
|
||||
(
|
||||
# Database level
|
||||
{"databases": {"foo": {"plugins": {"datasette-foo": "bar"}}}},
|
||||
{},
|
||||
{},
|
||||
{"databases": {"foo": {"plugins": {"datasette-foo": "bar"}}}},
|
||||
),
|
||||
(
|
||||
# Table level
|
||||
{
|
||||
"databases": {
|
||||
"foo": {"tables": {"bar": {"plugins": {"datasette-foo": "bar"}}}}
|
||||
}
|
||||
},
|
||||
{},
|
||||
{},
|
||||
{
|
||||
"databases": {
|
||||
"foo": {"tables": {"bar": {"plugins": {"datasette-foo": "bar"}}}}
|
||||
}
|
||||
},
|
||||
),
|
||||
(
|
||||
# Keep other keys
|
||||
{"plugins": {"datasette-foo": "bar"}, "other": "key"},
|
||||
{"original_config": "original"},
|
||||
{"other": "key"},
|
||||
{"original_config": "original", "plugins": {"datasette-foo": "bar"}},
|
||||
),
|
||||
),
|
||||
)
|
||||
def test_metadata_plugin_config_treated_as_config(
|
||||
metadata, config, expected_metadata, expected_config
|
||||
):
|
||||
ds = Datasette(metadata=metadata, config=config)
|
||||
actual_metadata = ds.metadata()
|
||||
assert "plugins" not in actual_metadata
|
||||
assert actual_metadata == expected_metadata
|
||||
assert ds.config == expected_config
|
||||
|
|
Ładowanie…
Reference in New Issue