Commit a694aadb by DustinMoriarty Committed by GitHub

feat: export without urls (#4763)

Export requirements.txt without index URLs

Co-authored-by: DBM012 <dustin.moriarty@amfam.com>
parent d3bc0eba
...@@ -602,6 +602,7 @@ Only the `requirements.txt` format is currently supported. ...@@ -602,6 +602,7 @@ Only the `requirements.txt` format is currently supported.
* `--dev`: Include development dependencies. * `--dev`: Include development dependencies.
* `--extras (-E)`: Extra sets of dependencies to include. * `--extras (-E)`: Extra sets of dependencies to include.
* `--without-hashes`: Exclude hashes from the exported file. * `--without-hashes`: Exclude hashes from the exported file.
* `--without-urls`: Exclude source repository urls from the exported file.
* `--with-credentials`: Include credentials for extra indices. * `--with-credentials`: Include credentials for extra indices.
## env ## env
......
...@@ -20,6 +20,11 @@ class ExportCommand(Command): ...@@ -20,6 +20,11 @@ class ExportCommand(Command):
), ),
option("output", "o", "The name of the output file.", flag=False), option("output", "o", "The name of the output file.", flag=False),
option("without-hashes", None, "Exclude hashes from the exported file."), option("without-hashes", None, "Exclude hashes from the exported file."),
option(
"without-urls",
None,
"Exclude source repository urls from the exported file.",
),
option("dev", None, "Include development dependencies."), option("dev", None, "Include development dependencies."),
option( option(
"extras", "extras",
...@@ -71,4 +76,5 @@ class ExportCommand(Command): ...@@ -71,4 +76,5 @@ class ExportCommand(Command):
dev=self.option("dev"), dev=self.option("dev"),
extras=self.option("extras"), extras=self.option("extras"),
with_credentials=self.option("with-credentials"), with_credentials=self.option("with-credentials"),
with_urls=not self.option("without-urls"),
) )
...@@ -34,6 +34,7 @@ class Exporter: ...@@ -34,6 +34,7 @@ class Exporter:
dev: bool = False, dev: bool = False,
extras: Optional[Union[bool, Sequence[str]]] = None, extras: Optional[Union[bool, Sequence[str]]] = None,
with_credentials: bool = False, with_credentials: bool = False,
with_urls: bool = True,
) -> None: ) -> None:
if fmt not in self.ACCEPTED_FORMATS: if fmt not in self.ACCEPTED_FORMATS:
raise ValueError(f"Invalid export format: {fmt}") raise ValueError(f"Invalid export format: {fmt}")
...@@ -45,6 +46,7 @@ class Exporter: ...@@ -45,6 +46,7 @@ class Exporter:
dev=dev, dev=dev,
extras=extras, extras=extras,
with_credentials=with_credentials, with_credentials=with_credentials,
with_urls=with_urls,
) )
def _export_requirements_txt( def _export_requirements_txt(
...@@ -55,6 +57,7 @@ class Exporter: ...@@ -55,6 +57,7 @@ class Exporter:
dev: bool = False, dev: bool = False,
extras: Optional[Union[bool, Sequence[str]]] = None, extras: Optional[Union[bool, Sequence[str]]] = None,
with_credentials: bool = False, with_credentials: bool = False,
with_urls: bool = True,
) -> None: ) -> None:
indexes = set() indexes = set()
content = "" content = ""
...@@ -122,7 +125,7 @@ class Exporter: ...@@ -122,7 +125,7 @@ class Exporter:
content += "\n".join(sorted(dependency_lines)) content += "\n".join(sorted(dependency_lines))
content += "\n" content += "\n"
if indexes: if indexes and with_urls:
# If we have extra indexes, we add them to the beginning of the output # If we have extra indexes, we add them to the beginning of the output
indexes_header = "" indexes_header = ""
for index in sorted(indexes): for index in sorted(indexes):
......
from unittest.mock import ANY
from unittest.mock import Mock
import pytest import pytest
from poetry.console.commands.export import Exporter
from tests.helpers import get_package from tests.helpers import get_package
...@@ -110,3 +114,23 @@ bar==1.1.0 ...@@ -110,3 +114,23 @@ bar==1.1.0
foo==1.0.0 foo==1.0.0
""" """
assert expected == tester.io.fetch_output() assert expected == tester.io.fetch_output()
def test_export_with_urls(monkeypatch, tester, poetry):
"""
We are just validating that the option gets passed. The option itself is tested in
the Exporter test.
"""
mock_export = Mock()
monkeypatch.setattr(Exporter, "export", mock_export)
tester.execute("--without-urls")
mock_export.assert_called_once_with(
ANY,
ANY,
ANY,
dev=False,
extras=[],
with_credentials=False,
with_hashes=True,
with_urls=False,
)
...@@ -1367,6 +1367,64 @@ foo==1.2.3 \\ ...@@ -1367,6 +1367,64 @@ foo==1.2.3 \\
assert expected == content assert expected == content
def test_exporter_exports_requirements_txt_with_url_false(tmp_dir, poetry):
poetry.pool.add_repository(
LegacyRepository(
"custom",
"https://example.com/simple",
)
)
poetry.locker.mock_lock_data(
{
"package": [
{
"name": "foo",
"version": "1.2.3",
"category": "main",
"optional": False,
"python-versions": "*",
},
{
"name": "bar",
"version": "4.5.6",
"category": "dev",
"optional": False,
"python-versions": "*",
"source": {
"type": "legacy",
"url": "https://example.com/simple",
"reference": "",
},
},
],
"metadata": {
"python-versions": "*",
"content-hash": "123456789",
"hashes": {"foo": ["12345"], "bar": ["67890"]},
},
}
)
set_package_requires(poetry)
exporter = Exporter(poetry)
exporter.export(
"requirements.txt", Path(tmp_dir), "requirements.txt", dev=True, with_urls=False
)
with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
content = f.read()
expected = """\
bar==4.5.6 \\
--hash=sha256:67890
foo==1.2.3 \\
--hash=sha256:12345
"""
assert expected == content
def test_exporter_exports_requirements_txt_with_legacy_packages_trusted_host( def test_exporter_exports_requirements_txt_with_legacy_packages_trusted_host(
tmp_dir, poetry tmp_dir, poetry
): ):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment