Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix --index-url handling for Poetry 1.8 - second try #270

Merged
merged 1 commit into from
Mar 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 18 additions & 18 deletions src/poetry_plugin_export/exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ def _export_generic_txt(
and not is_direct_local_reference
and package.source_url
):
indexes.add(package.source_url)
indexes.add(package.source_url.rstrip("/"))

if package.files and self._with_hashes:
hashes = []
Expand Down Expand Up @@ -171,22 +171,16 @@ def _export_generic_txt(
if indexes and self._with_urls:
# If we have extra indexes, we add them to the beginning of the output
indexes_header = ""
for index in sorted(indexes):
repositories = [
r
for r in self._poetry.pool.all_repositories
if isinstance(r, HTTPRepository) and r.url == index.rstrip("/")
]
if not repositories:
continue
repository = repositories[0]
if repository is self._poetry.pool.repositories[0]:
url = (
repository.authenticated_url
if self._with_credentials
else repository.url
)
indexes_header += f"--index-url {url}\n"
has_pypi_repository = any(
r.name.lower() == "pypi" for r in self._poetry.pool.all_repositories
)
# Iterate over repositories so that we get the repository with the highest
# priority first so that --index-url comes before --extra-index-url
for repository in self._poetry.pool.all_repositories:
if (
not isinstance(repository, HTTPRepository)
or repository.url not in indexes
):
continue

url = (
Expand All @@ -197,7 +191,13 @@ def _export_generic_txt(
parsed_url = urllib.parse.urlsplit(url)
if parsed_url.scheme == "http":
indexes_header += f"--trusted-host {parsed_url.netloc}\n"
indexes_header += f"--extra-index-url {url}\n"
if (
not has_pypi_repository
and repository is self._poetry.pool.repositories[0]
):
indexes_header += f"--index-url {url}\n"
else:
indexes_header += f"--extra-index-url {url}\n"

content = indexes_header + "\n" + content

Expand Down
121 changes: 120 additions & 1 deletion tests/test_exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -1878,8 +1878,8 @@ def test_exporter_exports_requirements_txt_with_two_primary_sources(
content = f.read()

expected = f"""\
--extra-index-url https://foo:[email protected]/simple
--index-url https://baz:[email protected]/simple
--extra-index-url https://foo:[email protected]/simple

bar==4.5.6 ; {MARKER_PY} \\
--hash=sha256:67890
Expand Down Expand Up @@ -2795,3 +2795,122 @@ def test_exporter_not_confused_by_extras_in_sub_dependencies(
typer[all]==0.9.0 ; python_version >= "3.11" and python_version < "4.0"
"""
assert io.fetch_output() == expected


@pytest.mark.parametrize(
("priorities", "expected"),
[
([("custom-a", Priority.PRIMARY), ("custom-b", Priority.PRIMARY)], ("a", "b")),
([("custom-b", Priority.PRIMARY), ("custom-a", Priority.PRIMARY)], ("b", "a")),
(
[("custom-b", Priority.SUPPLEMENTAL), ("custom-a", Priority.PRIMARY)],
("a", "b"),
),
([("custom-b", Priority.EXPLICIT), ("custom-a", Priority.PRIMARY)], ("a", "b")),
(
[
("PyPI", Priority.PRIMARY),
("custom-a", Priority.PRIMARY),
("custom-b", Priority.PRIMARY),
],
("", "a", "b"),
),
(
[
("PyPI", Priority.EXPLICIT),
("custom-a", Priority.PRIMARY),
("custom-b", Priority.PRIMARY),
],
("", "a", "b"),
),
(
[
("custom-a", Priority.PRIMARY),
("custom-b", Priority.PRIMARY),
("PyPI", Priority.SUPPLEMENTAL),
],
("", "a", "b"),
),
],
)
def test_exporter_index_urls(
tmp_path: Path,
poetry: Poetry,
priorities: list[tuple[str, Priority]],
expected: tuple[str, ...],
) -> None:
pypi = poetry.pool.repository("PyPI")
poetry.pool.remove_repository("PyPI")
for name, prio in priorities:
if name.lower() == "pypi":
repo = pypi
else:
repo = LegacyRepository(name, f"https://{name[-1]}.example.com/simple")
poetry.pool.add_repository(repo, priority=prio)

poetry.locker.mock_lock_data( # type: ignore[attr-defined]
{
"package": [
{
"name": "foo",
"version": "1.2.3",
"optional": False,
"python-versions": "*",
"source": {
"type": "legacy",
"url": "https://a.example.com/simple",
"reference": "",
},
},
{
"name": "bar",
"version": "4.5.6",
"optional": False,
"python-versions": "*",
"source": {
"type": "legacy",
"url": "https://b.example.com/simple",
"reference": "",
},
},
],
"metadata": {
"python-versions": "*",
"content-hash": "123456789",
"files": {
"foo": [{"name": "foo.whl", "hash": "12345"}],
"bar": [{"name": "bar.whl", "hash": "67890"}],
},
},
}
)
set_package_requires(poetry, dev={"bar"})

exporter = Exporter(poetry, NullIO())
exporter.only_groups([MAIN_GROUP, "dev"])
exporter.export("requirements.txt", tmp_path, "requirements.txt")

with (tmp_path / "requirements.txt").open(encoding="utf-8") as f:
content = f.read()

expected_urls = [
f"--extra-index-url https://{name[-1]}.example.com/simple"
for name in expected[1:]
]
if expected[0]:
expected_urls = [
f"--index-url https://{expected[0]}.example.com/simple",
*expected_urls,
]
url_string = "\n".join(expected_urls)

expected_content = f"""\
{url_string}

bar==4.5.6 ; {MARKER_PY} \\
--hash=sha256:67890
foo==1.2.3 ; {MARKER_PY} \\
--hash=sha256:12345
"""

assert content == expected_content
Loading