diff --git a/README.md b/README.md index 2e15a25..90b19db 100644 --- a/README.md +++ b/README.md @@ -61,3 +61,4 @@ poetry export -f requirements.txt --output requirements.txt * `--all-groups`: Include all dependency groups. * `--without-hashes`: Exclude hashes from the exported file. * `--with-credentials`: Include credentials for extra indices. +* `--without-markers`: Exclude markers in the exported file. diff --git a/src/poetry_plugin_export/command.py b/src/poetry_plugin_export/command.py index 51db1e7..f0c342f 100644 --- a/src/poetry_plugin_export/command.py +++ b/src/poetry_plugin_export/command.py @@ -75,6 +75,12 @@ class ExportCommand(GroupCommand): ), option("all-extras", None, "Include all sets of extra dependencies."), option("with-credentials", None, "Include credentials for extra indices."), + option( + "without-markers", + None, + "Exclude markers in the exported file.", + flag=True, + ), ] @property @@ -146,6 +152,10 @@ def handle(self) -> int: ) return 1 + without_markers = False + if self.option("without-markers"): + without_markers = self.option("without-markers") + groups = ( self.poetry.package.dependency_group_names(include_optional=True) if self.option("all-groups") @@ -158,6 +168,7 @@ def handle(self) -> int: exporter.with_hashes(not self.option("without-hashes")) exporter.with_credentials(self.option("with-credentials")) exporter.with_urls(not self.option("without-urls")) + exporter.with_markers(not without_markers) exporter.export(fmt, Path.cwd(), output or self.io) return 0 diff --git a/src/poetry_plugin_export/exporter.py b/src/poetry_plugin_export/exporter.py index 35922a5..1a028a7 100644 --- a/src/poetry_plugin_export/exporter.py +++ b/src/poetry_plugin_export/exporter.py @@ -45,6 +45,7 @@ def __init__(self, poetry: Poetry, io: IO) -> None: self._with_hashes = True self._with_credentials = False self._with_urls = True + self._with_markers = True self._extras: Collection[NormalizedName] = () self._groups: Iterable[str] = [MAIN_GROUP] @@ -77,6 +78,11 @@ def with_credentials(self, with_credentials: bool = True) -> Exporter: return self + def with_markers(self, with_markers: bool = True) -> Exporter: + self._with_markers = with_markers + + return self + def export(self, fmt: str, cwd: Path, output: IO | str) -> None: if not self.is_format_supported(fmt): raise ValueError(f"Invalid export format: {fmt}") @@ -153,7 +159,7 @@ def _export_generic_txt( if not is_direct_remote_reference and ";" in requirement: markers = requirement.split(";", 1)[1].strip() - if markers: + if markers and self._with_markers: line += f" ; {markers}" if ( diff --git a/tests/test_exporter.py b/tests/test_exporter.py index d2fbb74..945ec45 100644 --- a/tests/test_exporter.py +++ b/tests/test_exporter.py @@ -520,6 +520,64 @@ def test_exporter_can_export_requirements_txt_with_nested_packages_and_markers( assert expected == {} +@pytest.mark.parametrize("lock_version", ["2.1"]) +def test_exporter_with_no_markers_flag( + tmp_path: Path, poetry: Poetry, lock_version: str +) -> None: + lock_data = { + "package": [ + { + "name": "greenlet", + "version": "3.2.1", + "optional": False, + "python-versions": ">=3.9", + "markers": 'python_version < "3.14" and (platform_machine == "aarch64" or platform_machine == "ppc64le" or platform_machine == "x86_64" or platform_machine == "amd64" or platform_machine == "AMD64" or platform_machine == "win32" or platform_machine == "WIN32")', + }, + { + "name": "typing-extensions", + "version": "4.13.2", + "optional": False, + "python-versions": ">=3.8", + }, + { + "name": "sqlalchemy", + "version": "2.0.40", + "optional": False, + "python-versions": ">=3.7", + "dependencies": { + "greenlet": { + "version": ">=1", + "markers": 'python_version < "3.14" and (platform_machine == "aarch64" or platform_machine == "ppc64le" or platform_machine == "x86_64" or platform_machine == "amd64" or platform_machine == "AMD64" or platform_machine == "win32" or platform_machine == "WIN32")', + }, + "typing-extensions": ">=4.6.0", + }, + }, + ], + "metadata": { + "lock-version": lock_version, + "files": {"greenlet": [], "typing-extensions": [], "sqlalchemy": []}, + }, + } + + fix_lock_data(lock_data) + poetry.locker.mock_lock_data(lock_data) # type: ignore[attr-defined] + + exporter = Exporter(poetry, NullIO()) + exporter.with_markers(False) + exporter.export("requirements.txt", tmp_path, "requirements.txt") + + with open(tmp_path / "requirements.txt") as f: + lines = set(f.read().strip().splitlines()) + + expected = { + "greenlet==3.2.1", + "sqlalchemy==2.0.40", + "typing-extensions==4.13.2", + } + + assert lines == expected + + @pytest.mark.parametrize( ["dev", "lines"], [