diff --git a/README.md b/README.md index 0b4fce3..c452f1f 100644 --- a/README.md +++ b/README.md @@ -142,6 +142,18 @@ plugins: include: replace ``` + + +#### `include_from_url` + +Allow including content from URLs. + +```yaml +plugins: + - include-markdown: + include_from_url: true +``` + ### Reference This plugin provides two directives, one to include Markdown files and another diff --git a/locale/es/README.md b/locale/es/README.md index fccbe0f..6f5f853 100644 --- a/locale/es/README.md +++ b/locale/es/README.md @@ -125,6 +125,16 @@ plugins: include: replace ``` +#### `include_from_url` + +Permite incluir contenido desde URLs. + +```yaml +plugins: + - include-markdown: + include_from_url: true +``` + ### Referencia Este plugin provee dos directivas, una para incluir archivos Markdown y otra para diff --git a/locale/es/README.md.po b/locale/es/README.md.po index c1a3b1f..528a36c 100644 --- a/locale/es/README.md.po +++ b/locale/es/README.md.po @@ -480,3 +480,6 @@ msgstr "" msgid "Common arguments" msgstr "Argumentos comunes" + +msgid "Allow including content from URLs." +msgstr "Permite incluir contenido desde URLs." diff --git a/locale/fr/README.md b/locale/fr/README.md index a63c464..aa6935d 100644 --- a/locale/fr/README.md +++ b/locale/fr/README.md @@ -126,6 +126,16 @@ plugins: include: replace ``` +#### `include_from_url` + +Autoriser l'inclusion de contenu provenant d'URL. + +```yaml +plugins: + - include-markdown: + include_from_url: true +``` + ### Référence Ce plugin fournit deux directives, une pour inclure des fichiers Markdown et une diff --git a/locale/fr/README.md.po b/locale/fr/README.md.po index 25cabcf..c498a4f 100644 --- a/locale/fr/README.md.po +++ b/locale/fr/README.md.po @@ -478,3 +478,6 @@ msgstr "" msgid "Common arguments" msgstr "Arguments communs" + +msgid "Allow including content from URLs." +msgstr "Autoriser l'inclusion de contenu provenant d'URL." diff --git a/pyproject.toml b/pyproject.toml index 19cf415..a56c75f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "mkdocs-include-markdown-plugin" -version = "7.2.2" +version = "7.3.0" description = "Mkdocs Markdown includer plugin." readme = "README.md" license = "Apache-2.0" diff --git a/src/mkdocs_include_markdown_plugin/config.py b/src/mkdocs_include_markdown_plugin/config.py index ae1a8d6..7d95376 100644 --- a/src/mkdocs_include_markdown_plugin/config.py +++ b/src/mkdocs_include_markdown_plugin/config.py @@ -35,3 +35,4 @@ class PluginConfig(Config): # noqa: D101 'include-markdown': 'include-markdown', }, ) + include_from_url = MkType(bool, default=True) diff --git a/src/mkdocs_include_markdown_plugin/event.py b/src/mkdocs_include_markdown_plugin/event.py index f6d6114..8cba017 100644 --- a/src/mkdocs_include_markdown_plugin/event.py +++ b/src/mkdocs_include_markdown_plugin/event.py @@ -55,6 +55,7 @@ @dataclass class Settings: # noqa: D101 exclude: list[str] | None + include_from_url: bool = False def get_file_content( # noqa: PLR0913, PLR0915 @@ -169,14 +170,25 @@ def found_include_tag( # noqa: PLR0912, PLR0915 order, ) - if is_url and 'order' in used_arguments: # pragma: no cover - location = process.file_lineno_message( - page_src_path, docs_dir, directive_lineno(), - ) - logger.warning( - f"Ignoring 'order' argument of 'include' directive" - f" at {location} because the included path is a URL", - ) + if is_url: + if 'order' in used_arguments: # pragma: no cover + location = process.file_lineno_message( + page_src_path, docs_dir, directive_lineno(), + ) + logger.warning( + f"Ignoring 'order' argument of 'include' directive" + f" at {location} because the included path is a URL", + ) + + if not settings.include_from_url: + location = process.file_lineno_message( + page_src_path, docs_dir, directive_lineno(), + ) + raise PluginError( + f'Including from URL at {location} is not allowed because' + ' include-markdown is configured with include_from_url set' + ' to false', + ) if not file_paths_to_include: location = process.file_lineno_message( @@ -414,14 +426,25 @@ def found_include_markdown_tag( # noqa: PLR0912, PLR0915 order, ) - if is_url and 'order' in used_arguments: # pragma: no cover - location = process.file_lineno_message( - page_src_path, docs_dir, directive_lineno(), - ) - logger.warning( - f"Ignoring 'order' argument of 'include-markdown' directive" - f" at {location} because the included path is a URL", - ) + if is_url: + if 'order' in used_arguments: # pragma: no cover + location = process.file_lineno_message( + page_src_path, docs_dir, directive_lineno(), + ) + logger.warning( + f"Ignoring 'order' argument of 'include-markdown' directive" + f" at {location} because the included path is a URL", + ) + + if not settings.include_from_url: + location = process.file_lineno_message( + page_src_path, docs_dir, directive_lineno(), + ) + raise PluginError( + f'Including from URL at {location} is not allowed because' + ' include-markdown is configured with include_from_url set' + ' to false', + ) if not file_paths_to_include: location = process.file_lineno_message( @@ -713,6 +736,7 @@ def on_page_markdown( }, Settings( exclude=config.exclude, + include_from_url=config.include_from_url, ), files_watcher=plugin._files_watcher, http_cache=plugin._cache or http_cache, diff --git a/tests/test_integration/test_cache_integration.py b/tests/test_integration/test_cache_integration.py index 1ac8122..170d1da 100644 --- a/tests/test_integration/test_cache_integration.py +++ b/tests/test_integration/test_cache_integration.py @@ -4,7 +4,6 @@ from mkdocs.exceptions import PluginError import mkdocs_include_markdown_plugin.cache -from mkdocs_include_markdown_plugin import IncludeMarkdownPlugin from mkdocs_include_markdown_plugin.cache import ( Cache, get_cache_directory, @@ -12,7 +11,7 @@ is_platformdirs_installed, ) from mkdocs_include_markdown_plugin.event import on_page_markdown -from testing_helpers import FakeConfig, parametrize_directives +from testing_helpers import parametrize_directives @pytest.mark.parametrize( @@ -80,14 +79,14 @@ def run(): os.remove(file_path) -def test_cache_setting_when_not_available_raises_error(monkeypatch): +def test_cache_setting_when_not_available_raises_error(plugin, monkeypatch): monkeypatch.setattr( mkdocs_include_markdown_plugin.cache, 'is_platformdirs_installed', lambda: False, ) - plugin = IncludeMarkdownPlugin() - plugin.config = FakeConfig(cache=600, cache_dir='') + monkeypatch.setattr(plugin.config, 'cache', 600) + monkeypatch.setattr(plugin.config, 'cache_dir', '') with pytest.raises(PluginError) as exc: plugin.on_config({}) assert ( @@ -96,12 +95,12 @@ def test_cache_setting_when_not_available_raises_error(monkeypatch): ) in str(exc.value) -def test_cache_setting_available_with_cache_dir(monkeypatch): +def test_cache_setting_available_with_cache_dir(plugin, monkeypatch): monkeypatch.setattr( mkdocs_include_markdown_plugin.cache, 'is_platformdirs_installed', lambda: False, ) - plugin = IncludeMarkdownPlugin() - plugin.config = FakeConfig(cache=600, cache_dir='foo') + monkeypatch.setattr(plugin.config, 'cache', 600) + monkeypatch.setattr(plugin.config, 'cache_dir', 'foo') plugin.on_config({}) diff --git a/tests/test_integration/test_include_from_url_setting.py b/tests/test_integration/test_include_from_url_setting.py new file mode 100644 index 0000000..4266617 --- /dev/null +++ b/tests/test_integration/test_include_from_url_setting.py @@ -0,0 +1,49 @@ +"""Tests for the ``include_from_url`` global setting.""" + +import pytest +from mkdocs.exceptions import PluginError + +from mkdocs_include_markdown_plugin.event import on_page_markdown +from testing_helpers import mock_read_url, parametrize_directives + + +URL = ( + 'https://raw.githubusercontent.com/mondeja/' + 'mkdocs-include-markdown-plugin/master/examples/basic/docs/included.md' +) +URL_CONTENT = '''Some ignored content. + +<--start--> + +Some included content. +''' + + +@parametrize_directives +def test_include_from_url_disabled_by_default_raises( + directive, page, tmp_path, plugin, monkeypatch, +): + monkeypatch.setattr(plugin.config, 'include_from_url', False) + mock_read_url(monkeypatch, URL_CONTENT) + includer = tmp_path / 'includer.md' + content = f'{{% {directive} "{URL}" %}}' + includer.write_text(content, encoding='utf-8') + + with pytest.raises(PluginError) as exc: + on_page_markdown(content, page(includer), tmp_path, plugin) + assert 'include_from_url set to false' in str(exc.value) + + +@parametrize_directives +def test_include_from_url_enabled_allows_url( + directive, page, tmp_path, plugin, monkeypatch, +): + monkeypatch.setattr(plugin.config, 'include_from_url', True) + mock_read_url(monkeypatch, URL_CONTENT) + + includer = tmp_path / 'includer.md' + content = f'{{% {directive} "{URL}" %}}' + includer.write_text(content, encoding='utf-8') + + result = on_page_markdown(content, page(includer), tmp_path, plugin) + assert 'Some included content.' in result diff --git a/tests/test_integration/test_order_setting.py b/tests/test_integration/test_order_setting.py index 7564768..c3fcab6 100644 --- a/tests/test_integration/test_order_setting.py +++ b/tests/test_integration/test_order_setting.py @@ -2,13 +2,10 @@ from mkdocs.exceptions import PluginError from mkdocs_include_markdown_plugin.directive import get_order_option_regex -from mkdocs_include_markdown_plugin.plugin import IncludeMarkdownPlugin -from testing_helpers import FakeConfig -def test_invalid_order_setting(): - plugin = IncludeMarkdownPlugin() - plugin.config = FakeConfig(order='invalid-order') +def test_invalid_order_setting(plugin, monkeypatch): + monkeypatch.setattr(plugin.config, 'order', 'invalid-order') with pytest.raises(PluginError) as exc: plugin.on_config({}) regex = get_order_option_regex() @@ -18,7 +15,6 @@ def test_invalid_order_setting(): ) in str(exc.value) -def test_valid_order_setting(): - plugin = IncludeMarkdownPlugin() - plugin.config = FakeConfig(order='alpha-name') +def test_valid_order_setting(plugin, monkeypatch): + monkeypatch.setattr(plugin.config, 'order', 'alpha-name') assert plugin.on_config({}) is not None diff --git a/tests/testing_helpers.py b/tests/testing_helpers.py index bc8ab04..ec16797 100644 --- a/tests/testing_helpers.py +++ b/tests/testing_helpers.py @@ -1,11 +1,8 @@ import os import sys -from dataclasses import dataclass, field import pytest -from mkdocs_include_markdown_plugin.config import PluginConfig - parametrize_directives = pytest.mark.parametrize( 'directive', @@ -26,11 +23,8 @@ rootdir = os.path.join(os.path.dirname(__file__), '..') -@dataclass -class FakeConfig: - cache: int = PluginConfig.cache.default - cache_dir: str = PluginConfig.cache_dir.default - directives: dict[str, str] = field( - default_factory=lambda: PluginConfig.directives.default, +def mock_read_url(monkeypatch, content): + monkeypatch.setattr( + 'mkdocs_include_markdown_plugin.process.read_url', + lambda _url, _http_cache, _encoding: content, # noqa: ARG005 ) - order: str = PluginConfig.order.default