Skip to content

Commit 9dcae01

Browse files
committed
add initial support for single page repositories
This change allows users to make use of find-links style single page sources that do not present a PEP 503 simple API repository.
1 parent b6d4b0a commit 9dcae01

File tree

4 files changed

+112
-1
lines changed

4 files changed

+112
-1
lines changed

src/poetry/factory.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from __future__ import annotations
22

3+
import re
4+
35
from pathlib import Path
46
from typing import TYPE_CHECKING
57

@@ -157,6 +159,7 @@ def create_legacy_repository(
157159
cls, source: dict[str, str], auth_config: Config
158160
) -> LegacyRepository:
159161
from poetry.repositories.legacy_repository import LegacyRepository
162+
from poetry.repositories.single_page_repository import SinglePageRepository
160163
from poetry.utils.helpers import get_cert
161164
from poetry.utils.helpers import get_client_cert
162165

@@ -169,7 +172,12 @@ def create_legacy_repository(
169172
name = source["name"]
170173
url = source["url"]
171174

172-
return LegacyRepository(
175+
repository_class = LegacyRepository
176+
177+
if re.match(r".*\.(htm|html)$", url):
178+
repository_class = SinglePageRepository
179+
180+
return repository_class(
173181
name,
174182
url,
175183
config=auth_config,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from __future__ import annotations
2+
3+
from poetry.repositories.legacy_repository import LegacyRepository
4+
from poetry.repositories.link_sources.html import SimpleRepositoryPage
5+
6+
7+
class SinglePageRepository(LegacyRepository):
8+
def _get_page(self, endpoint: str = None) -> SimpleRepositoryPage | None:
9+
"""
10+
Single page repositories only have one page irrespective of endpoint.
11+
"""
12+
response = self._get_response("")
13+
if not response:
14+
return None
15+
return SimpleRepositoryPage(response.url, response.text)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head>
4+
<body>
5+
<a href="https://storage.googleapis.com/jax-releases/nocuda/jaxlib-0.3.0-cp310-none-manylinux2010_x86_64.whl">nocuda/jaxlib-0.3.0-cp310-none-manylinux2010_x86_64.whl</a><br>
6+
<a href="https://storage.googleapis.com/jax-releases/nocuda/jaxlib-0.3.0-cp37-none-manylinux2010_x86_64.whl">nocuda/jaxlib-0.3.0-cp37-none-manylinux2010_x86_64.whl</a><br>
7+
<a href="https://storage.googleapis.com/jax-releases/nocuda/jaxlib-0.3.0-cp38-none-manylinux2010_x86_64.whl">nocuda/jaxlib-0.3.0-cp38-none-manylinux2010_x86_64.whl</a><br>
8+
<a href="https://storage.googleapis.com/jax-releases/nocuda/jaxlib-0.3.0-cp39-none-manylinux2010_x86_64.whl">nocuda/jaxlib-0.3.0-cp39-none-manylinux2010_x86_64.whl</a><br>
9+
<a href="https://storage.googleapis.com/jax-releases/nocuda/jaxlib-0.3.2-cp310-none-manylinux2010_x86_64.whl">nocuda/jaxlib-0.3.2-cp310-none-manylinux2010_x86_64.whl</a><br>
10+
<a href="https://storage.googleapis.com/jax-releases/nocuda/jaxlib-0.3.2-cp37-none-manylinux2010_x86_64.whl">nocuda/jaxlib-0.3.2-cp37-none-manylinux2010_x86_64.whl</a><br>
11+
<a href="https://storage.googleapis.com/jax-releases/nocuda/jaxlib-0.3.2-cp38-none-manylinux2010_x86_64.whl">nocuda/jaxlib-0.3.2-cp38-none-manylinux2010_x86_64.whl</a><br>
12+
<a href="https://storage.googleapis.com/jax-releases/nocuda/jaxlib-0.3.2-cp39-none-manylinux2010_x86_64.whl">nocuda/jaxlib-0.3.2-cp39-none-manylinux2010_x86_64.whl</a><br>
13+
<a href="https://storage.googleapis.com/jax-releases/nocuda/jaxlib-0.3.5-cp310-none-manylinux2010_x86_64.whl">nocuda/jaxlib-0.3.5-cp310-none-manylinux2010_x86_64.whl</a><br>
14+
<a href="https://storage.googleapis.com/jax-releases/nocuda/jaxlib-0.3.5-cp37-none-manylinux2010_x86_64.whl">nocuda/jaxlib-0.3.5-cp37-none-manylinux2010_x86_64.whl</a><br>
15+
<a href="https://storage.googleapis.com/jax-releases/nocuda/jaxlib-0.3.5-cp38-none-manylinux2010_x86_64.whl">nocuda/jaxlib-0.3.5-cp38-none-manylinux2010_x86_64.whl</a><br>
16+
<a href="https://storage.googleapis.com/jax-releases/nocuda/jaxlib-0.3.5-cp39-none-manylinux2010_x86_64.whl">nocuda/jaxlib-0.3.5-cp39-none-manylinux2010_x86_64.whl</a><br>
17+
<a href="https://storage.googleapis.com/jax-releases/nocuda/jaxlib-0.3.7-cp310-none-manylinux2014_x86_64.whl">nocuda/jaxlib-0.3.7-cp310-none-manylinux2014_x86_64.whl</a><br>
18+
<a href="https://storage.googleapis.com/jax-releases/nocuda/jaxlib-0.3.7-cp37-none-manylinux2014_x86_64.whl">nocuda/jaxlib-0.3.7-cp37-none-manylinux2014_x86_64.whl</a><br>
19+
<a href="https://storage.googleapis.com/jax-releases/nocuda/jaxlib-0.3.7-cp38-none-manylinux2014_x86_64.whl">nocuda/jaxlib-0.3.7-cp38-none-manylinux2014_x86_64.whl</a><br>
20+
<a href="https://storage.googleapis.com/jax-releases/nocuda/jaxlib-0.3.7-cp39-none-manylinux2014_x86_64.whl">nocuda/jaxlib-0.3.7-cp39-none-manylinux2014_x86_64.whl</a><br>
21+
<a href="https://storage.googleapis.com/jax-releases/jax/jax-0.3.0.tar.gz">jax/jax-0.3.0.tar.gz</a><br>
22+
<a href="https://storage.googleapis.com/jax-releases/jax/jax-0.3.2.tar.gz">jax/jax-0.3.2.tar.gz</a><br>
23+
<a href="https://storage.googleapis.com/jax-releases/jax/jax-0.3.5.tar.gz">jax/jax-0.3.5.tar.gz</a><br>
24+
<a href="https://storage.googleapis.com/jax-releases/jax/jax-0.3.6.tar.gz">jax/jax-0.3.6.tar.gz</a><br>
25+
<a href="https://storage.googleapis.com/jax-releases/jax/jax-0.3.7.tar.gz">jax/jax-0.3.7.tar.gz</a><br>
26+
</body>
27+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
from __future__ import annotations
2+
3+
import re
4+
5+
from pathlib import Path
6+
7+
from poetry.core.packages.dependency import Dependency
8+
9+
from poetry.repositories.link_sources.html import SimpleRepositoryPage
10+
from poetry.repositories.single_page_repository import SinglePageRepository
11+
12+
13+
class MockSinglePageRepository(SinglePageRepository):
14+
15+
FIXTURES = Path(__file__).parent / "fixtures" / "single-page"
16+
17+
def __init__(self, page: str) -> None:
18+
super().__init__(
19+
"single-page",
20+
url=f"http://single-page.foo.bar/{page}.html",
21+
disable_cache=True,
22+
)
23+
24+
def _get_page(self, endpoint: str = None) -> SimpleRepositoryPage | None:
25+
fixture = self.FIXTURES / self.url.rsplit("/", 1)[-1]
26+
if not fixture.exists():
27+
return
28+
29+
with fixture.open(encoding="utf-8") as f:
30+
return SimpleRepositoryPage(self._url, f.read())
31+
32+
def _download(self, url: str, dest: Path) -> None:
33+
raise RuntimeError("Tests are not configured for downloads")
34+
35+
36+
def test_single_page_repository_get_page():
37+
repo = MockSinglePageRepository("jax_releases")
38+
39+
page = repo._get_page("/ignored")
40+
links = list(page.links)
41+
42+
assert len(links) == 21
43+
44+
for link in links:
45+
assert re.match(r"^(jax|jaxlib)-0\.3\.\d.*\.(whl|tar\.gz)$", link.filename)
46+
assert link.netloc == "storage.googleapis.com"
47+
assert link.path.startswith("/jax-releases/")
48+
49+
50+
def test_single_page_repository_find_packages():
51+
repo = MockSinglePageRepository("jax_releases")
52+
53+
dep = Dependency("jaxlib", "0.3.7")
54+
55+
packages = repo.find_packages(dep)
56+
57+
assert len(packages) == 1
58+
59+
package = packages[0]
60+
assert package.name == dep.name
61+
assert package.to_dependency().to_pep_508() == dep.to_pep_508()

0 commit comments

Comments
 (0)