diff --git a/docs/cli.md b/docs/cli.md index 7e4eaf4a142..7de5b8af291 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -720,9 +720,17 @@ This command exports the lock file to other formats. poetry export -f requirements.txt --output requirements.txt ``` +{{% warning %}} +This command is provided by the [Export Poetry Plugin](https://github.com/python-poetry/poetry-plugin-export). +In a future version of Poetry this plugin will not be installed by default anymore. +In order to avoid a breaking change and make your automation forward-compatible, +please install poetry-plugin-export explicitly. +See {{< relref "plugins#using-plugins" >}} for details on how to install a plugin. +{{% /warning %}} + {{% note %}} -This command is provided by the [Export Poetry Plugin](https://github.com/python-poetry/poetry-plugin-export) -and is also available as a pre-commit hook. See [pre-commit hooks]({{< relref "pre-commit-hooks#poetry-export" >}}) for more information. +This command is also available as a pre-commit hook. +See [pre-commit hooks]({{< relref "pre-commit-hooks#poetry-export" >}}) for more information. {{% /note %}} {{% note %}} diff --git a/docs/pre-commit-hooks.md b/docs/pre-commit-hooks.md index de9c229b48b..556f4893adc 100644 --- a/docs/pre-commit-hooks.md +++ b/docs/pre-commit-hooks.md @@ -53,6 +53,10 @@ For more information see the [lock command]({{< relref "cli#lock" >}}). The `poetry-export` hook calls the `poetry export` command to sync your `requirements.txt` file with your current dependencies. +{{% warning %}} +This hook is provided by the [Export Poetry Plugin](https://github.com/python-poetry/poetry-plugin-export). +{{% /warning %}} + {{% note %}} It is recommended to run the [`poetry-lock`](#poetry-lock) hook prior to this one. {{% /note %}} diff --git a/src/poetry/config/config.py b/src/poetry/config/config.py index 6d7658645ae..3100fab7dee 100644 --- a/src/poetry/config/config.py +++ b/src/poetry/config/config.py @@ -133,6 +133,9 @@ class Config: "max-workers": None, "no-binary": None, }, + "warnings": { + "export": True, + }, } def __init__( @@ -279,6 +282,7 @@ def _get_normalizer(name: str) -> Callable[[str], Any]: "experimental.system-git-client", "installer.modern-installation", "installer.parallel", + "warnings.export", }: return boolean_normalizer diff --git a/src/poetry/console/application.py b/src/poetry/console/application.py index 8d325efde1f..b6973085947 100644 --- a/src/poetry/console/application.py +++ b/src/poetry/console/application.py @@ -354,6 +354,12 @@ def _load_plugins(self, io: IO | None = None) -> None: manager.load_plugins() manager.activate(self) + # We have to override the command from poetry-plugin-export + # with the wrapper. + if self.command_loader.has("export"): + del self.command_loader._factories["export"] + self.command_loader._factories["export"] = load_command("export") + self._plugins_loaded = True @property diff --git a/src/poetry/console/commands/config.py b/src/poetry/console/commands/config.py index 008817918d5..3b460fb7aa2 100644 --- a/src/poetry/console/commands/config.py +++ b/src/poetry/console/commands/config.py @@ -77,6 +77,7 @@ def unique_config_values(self) -> dict[str, tuple[Any, Any]]: PackageFilterPolicy.validator, PackageFilterPolicy.normalize, ), + "warnings.export": (boolean_validator, boolean_normalizer), } return unique_config_values diff --git a/src/poetry/console/commands/export.py b/src/poetry/console/commands/export.py new file mode 100644 index 00000000000..36723d40be7 --- /dev/null +++ b/src/poetry/console/commands/export.py @@ -0,0 +1,19 @@ +from __future__ import annotations + +from poetry_plugin_export.command import ExportCommand as BaseExportCommand + + +class ExportCommand(BaseExportCommand): + def handle(self) -> int: + if self.poetry.config.get("warnings.export"): + self.line_error( + "Warning: poetry-plugin-export will not be installed by default in a" + " future version of Poetry.\n" + "In order to avoid a breaking change and make your automation" + " forward-compatible, please install poetry-plugin-export explicitly." + " See https://python-poetry.org/docs/plugins/#using-plugins for details" + " on how to install a plugin.\n" + "To disable this warning run 'poetry config warnings.export false'.", + style="warning", + ) + return super().handle() diff --git a/tests/console/commands/test_config.py b/tests/console/commands/test_config.py index 1f22b958e0a..24b89a63d9b 100644 --- a/tests/console/commands/test_config.py +++ b/tests/console/commands/test_config.py @@ -67,6 +67,7 @@ def test_list_displays_default_value_if_not_set( virtualenvs.path = {venv_path} # {config_cache_dir / 'virtualenvs'} virtualenvs.prefer-active-python = false virtualenvs.prompt = "{{project_name}}-py{{python_version}}" +warnings.export = true """ assert tester.io.fetch_output() == expected @@ -96,6 +97,7 @@ def test_list_displays_set_get_setting( virtualenvs.path = {venv_path} # {config_cache_dir / 'virtualenvs'} virtualenvs.prefer-active-python = false virtualenvs.prompt = "{{project_name}}-py{{python_version}}" +warnings.export = true """ assert config.set_config_source.call_count == 0 # type: ignore[attr-defined] @@ -146,6 +148,7 @@ def test_unset_setting( virtualenvs.path = {venv_path} # {config_cache_dir / 'virtualenvs'} virtualenvs.prefer-active-python = false virtualenvs.prompt = "{{project_name}}-py{{python_version}}" +warnings.export = true """ assert config.set_config_source.call_count == 0 # type: ignore[attr-defined] assert tester.io.fetch_output() == expected @@ -174,6 +177,7 @@ def test_unset_repo_setting( virtualenvs.path = {venv_path} # {config_cache_dir / 'virtualenvs'} virtualenvs.prefer-active-python = false virtualenvs.prompt = "{{project_name}}-py{{python_version}}" +warnings.export = true """ assert config.set_config_source.call_count == 0 # type: ignore[attr-defined] assert tester.io.fetch_output() == expected @@ -301,6 +305,7 @@ def test_list_displays_set_get_local_setting( virtualenvs.path = {venv_path} # {config_cache_dir / 'virtualenvs'} virtualenvs.prefer-active-python = false virtualenvs.prompt = "{{project_name}}-py{{python_version}}" +warnings.export = true """ assert config.set_config_source.call_count == 1 # type: ignore[attr-defined] @@ -338,6 +343,7 @@ def test_list_must_not_display_sources_from_pyproject_toml( virtualenvs.path = {venv_path} # {config_cache_dir / 'virtualenvs'} virtualenvs.prefer-active-python = false virtualenvs.prompt = "{{project_name}}-py{{python_version}}" +warnings.export = true """ assert tester.io.fetch_output() == expected diff --git a/tests/console/commands/test_export.py b/tests/console/commands/test_export.py new file mode 100644 index 00000000000..962c2c8c151 --- /dev/null +++ b/tests/console/commands/test_export.py @@ -0,0 +1,31 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +import pytest + + +if TYPE_CHECKING: + from cleo.testers.command_tester import CommandTester + + from tests.conftest import Config + from tests.types import CommandTesterFactory + + +@pytest.fixture +def tester(command_tester_factory: CommandTesterFactory) -> CommandTester: + return command_tester_factory("export") + + +def test_export_prints_warning(tester: CommandTester) -> None: + tester.execute("") + assert ( + "Warning: poetry-plugin-export will not be installed by default" + in tester.io.fetch_error() + ) + + +def test_disable_export_warning(tester: CommandTester, config: Config) -> None: + config.config["warnings"]["export"] = False + tester.execute("") + assert "poetry-plugin-export" not in tester.io.fetch_error()