diff --git a/datasette/app.py b/datasette/app.py index 7dfc63c6..f33865e4 100644 --- a/datasette/app.py +++ b/datasette/app.py @@ -76,6 +76,7 @@ from .utils import ( parse_metadata, resolve_env_secrets, resolve_routes, + fail_if_plugins_in_metadata, tilde_decode, to_css_class, urlsafe_components, @@ -334,13 +335,16 @@ class Datasette: ] if config_dir and metadata_files and not metadata: with metadata_files[0].open() as fp: - metadata = parse_metadata(fp.read()) + metadata = fail_if_plugins_in_metadata( + parse_metadata(fp.read()), metadata_files[0].name + ) if config_dir and config_files and not config: with config_files[0].open() as fp: config = parse_metadata(fp.read()) - self._metadata_local = metadata or {} + self._metadata_local = fail_if_plugins_in_metadata(metadata or {}) + self.sqlite_extensions = [] for extension in sqlite_extensions or []: # Resolve spatialite, if requested diff --git a/datasette/cli.py b/datasette/cli.py index 1a5a8af3..91f38f69 100644 --- a/datasette/cli.py +++ b/datasette/cli.py @@ -33,6 +33,7 @@ from .utils import ( initial_path_for_datasette, pairs_to_nested_config, temporary_docker_directory, + fail_if_plugins_in_metadata, value_as_boolean, SpatialiteNotFound, StaticMount, @@ -542,7 +543,7 @@ def serve( metadata_data = None if metadata: - metadata_data = parse_metadata(metadata.read()) + metadata_data = fail_if_plugins_in_metadata(parse_metadata(metadata.read())) config_data = None if config: diff --git a/datasette/utils/__init__.py b/datasette/utils/__init__.py index 18d18641..0f449b89 100644 --- a/datasette/utils/__init__.py +++ b/datasette/utils/__init__.py @@ -1268,3 +1268,18 @@ def pairs_to_nested_config(pairs: typing.List[typing.Tuple[str, typing.Any]]) -> parsed_pair = _handle_pair(key, value) result = _combine(result, parsed_pair) return result + + +def fail_if_plugins_in_metadata(metadata: dict, filename=None): + """If plugin config is inside metadata, raise an Exception""" + if metadata is not None and metadata.get("plugins") is not None: + suggested_extension = ( + ".yaml" + if filename is not None + and (filename.endswith(".yaml") or filename.endswith(".yml")) + else ".json" + ) + raise Exception( + f'Datasette no longer accepts plugin configuration in --metadata. Move your "plugins" configuration blocks to a separate file - we suggest calling that datasette.{suggested_extension} - and start Datasette with datasette -c datasette.{suggested_extension}. See https://docs.datasette.io/en/latest/configuration.html for more details.' + ) + return metadata diff --git a/tests/test_plugins.py b/tests/test_plugins.py index 66060bca..82e2f7f1 100644 --- a/tests/test_plugins.py +++ b/tests/test_plugins.py @@ -879,6 +879,14 @@ def test_hook_forbidden(restore_working_directory): ) +def test_plugin_config_in_metadata(): + with pytest.raises( + Exception, + match="Datasette no longer accepts plugin configuration in --metadata", + ): + Datasette(memory=True, metadata={"plugins": {}}) + + @pytest.mark.asyncio async def test_hook_handle_exception(ds_client): await ds_client.get("/trigger-error?x=123")