Skip to content

Commit 6b7a2b3

Browse files
committed
Treat rebuilds as PEP 440 local versions (+test.N) instead of Maven-style .letters-dash suffixes.
Python versions group on the public version (everything before +); release is the local identifier. Catalog still keeps the newest pulp_created unit per public version. Assisted-By: Cursor
1 parent 9338213 commit 6b7a2b3

7 files changed

Lines changed: 48 additions & 46 deletions

File tree

‎docs/user/guides/catalog.md‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ http GET "${BASE_ADDR}/pulp/api/v3/repositories/python/python/${REPO_PK}/package
3434

3535
- `versions` is the list of version numbers, newest first (PEP 440, so `1.10` before `1.9`).
3636
- `latest_releases` is the same versions with extra metadata. `release` is filled when
37-
that version has a rebuild (for example `5.3.17.rhlw-00001` is shown as version
38-
`5.3.17` with `release` `rhlw-00001`); otherwise it is empty.
37+
that version has a rebuild (for example `5.3.17+test.1` is shown as version
38+
`5.3.17` with `release` `test.1`); otherwise it is empty.
3939
- `created_at` is when that version was added to the repository.
4040
- `last_updated` is when **any** file for the package last changed in this repository
4141
version, including a rebuild of an older version.
@@ -99,8 +99,8 @@ http GET "${BASE_ADDR}/pulp/api/v3/content/python/packages/" \
9999
repository_version=="${LATEST_VERSION_HREF}"
100100
```
101101

102-
Each content row includes `base_version`: the version without a rebuild suffix
103-
(equal to `version` when there is none).
102+
Each content row includes `base_version`: the version without a PEP 440 local
103+
version (equal to `version` when there is none).
104104

105105
To fetch a single version, omit `collapse_builds` and filter by `name`, `version`,
106106
and `packagetype`:

‎pulp_python/app/catalog.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616

1717
def base_version_annotation(field_name="version"):
18-
"""SQL expression that strips a trailing rebuild suffix from ``version``.
18+
"""SQL expression that strips a PEP 440 local version from ``version``.
1919
2020
Uses ``versions.BUILD_SUFFIX_PATTERN`` (POSIX) so Python ``strip_build_suffix``
2121
and this ``REGEXP_REPLACE`` stay aligned. Implemented with ``REGEXP_REPLACE``
@@ -34,7 +34,7 @@ def base_version_annotation(field_name="version"):
3434
def collapse_python_builds(queryset):
3535
"""Keep one content unit per ``(name_normalized, base_version)``.
3636
37-
``base_version`` is ``version`` with a trailing rebuild suffix stripped.
37+
``base_version`` is ``version`` with a PEP 440 local version stripped.
3838
The unit with the latest ``pulp_created`` is kept. Callers that want one
3939
row per logical version (not per wheel/sdist) should also filter
4040
``packagetype``.

‎pulp_python/app/serializers.py‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -234,8 +234,8 @@ class PythonPackageContentSerializer(core_serializers.SingleArtifactContentUploa
234234
)
235235
base_version = serializers.SerializerMethodField(
236236
help_text=_(
237-
"The package version with a trailing rebuild suffix stripped "
238-
"(matching %s). Equal to version when no suffix is present."
237+
"The package version with a PEP 440 local version stripped "
238+
"(matching %s). Equal to version when no local version is present."
239239
)
240240
% BUILD_SUFFIX_PATTERN,
241241
)
@@ -659,13 +659,13 @@ class PythonPackageReleaseSerializer(serializers.Serializer):
659659
"""One logical version on the repository package index."""
660660

661661
version = serializers.CharField(
662-
help_text=_("Logical version key (rebuild suffix stripped)."),
662+
help_text=_("Logical version key (PEP 440 local version stripped)."),
663663
)
664664
release = serializers.CharField(
665665
help_text=_(
666-
"Rebuild/release qualifier within the version line "
667-
"(e.g. rhlw-00001 or rhlw-00001-n0001). "
668-
"Empty when the selected unit has no rebuild suffix."
666+
"PEP 440 local identifier within the version line "
667+
"(e.g. test.1 or test.1.n1). "
668+
"Empty when the selected unit has no local version."
669669
),
670670
allow_blank=True,
671671
)

‎pulp_python/app/versions.py‎

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88

99
from packaging.version import InvalidVersion, Version
1010

11-
# Last dot-segment is a rebuild if it is letters, dash, rest of that segment.
12-
BUILD_SUFFIX_PATTERN = r"\.[a-zA-Z]+-[^.]+$"
11+
# PEP 440 local version: ``+`` through the end of the string (POSIX, shared with SQL).
12+
BUILD_SUFFIX_PATTERN = r"\+.*$"
1313
BUILD_SUFFIX_RE = re.compile(BUILD_SUFFIX_PATTERN)
1414

1515
PACKAGE_INDEX_ORDERING_FIELDS = frozenset({"name", "name_normalized", "last_updated"})
@@ -18,25 +18,24 @@
1818

1919

2020
def strip_build_suffix(version):
21-
"""Return ``version`` with a trailing rebuild suffix removed, else unchanged.
21+
"""Return ``version`` with a PEP 440 local version removed, else unchanged.
2222
23-
A rebuild is the last dot-segment matching ``BUILD_SUFFIX_PATTERN``.
23+
A rebuild is the local version (``+`` through the end of the string).
2424
"""
2525
if not version:
2626
return version
2727
return BUILD_SUFFIX_RE.sub("", version)
2828

2929

3030
def rebuild_release(version):
31-
"""Return the rebuild qualifier without the leading dot, or an empty string."""
31+
"""Return the PEP 440 local identifier without the leading ``+``, or empty."""
3232
if not version:
3333
return ""
3434
base = strip_build_suffix(version)
3535
if version == base:
3636
return ""
37-
if version.startswith(base + "."):
38-
return version[len(base) + 1 :]
39-
return ""
37+
# strip_build_suffix removes ``+local``; skip the ``+``.
38+
return version[len(base) + 1 :]
4039

4140

4241
def version_sort_key(version):

‎pulp_python/app/viewsets.py‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -720,9 +720,9 @@ class PythonPackageContentFilter(core_viewsets.ContentFilter):
720720
collapse_builds = drf_filters.BooleanFilter(
721721
method="filter_collapse_builds",
722722
help_text=(
723-
"When true, collapse rebuilds of the same logical version: strip a trailing "
724-
f"suffix matching {BUILD_SUFFIX_PATTERN} from version, then keep one content unit "
725-
"per (name_normalized, base_version) with the latest pulp_created. "
723+
"When true, collapse rebuilds of the same logical version: strip a PEP 440 "
724+
f"local version matching {BUILD_SUFFIX_PATTERN} from version, then keep one "
725+
"content unit per (name_normalized, base_version) with the latest pulp_created. "
726726
"Pass packagetype=sdist so wheel and sdist files are not collapsed together. "
727727
"Default false."
728728
),

‎pulp_python/tests/functional/api/test_catalog.py‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ def test_package_list_ordering_last_updated(
361361
tmp_path,
362362
repo,
363363
later_name,
364-
"1.0.0.rhlw-00003",
364+
"1.0.0+test.3",
365365
)
366366
after_rebuild = _api_get(
367367
bindings_cfg, f"{repo.pulp_href}packages/", ordering="-last_updated", limit=100
@@ -372,7 +372,7 @@ def test_package_list_ordering_last_updated(
372372
assert set(zzz["versions"]) == {"2.0.0", "1.0.0"}
373373
assert zzz["versions"][0] == "2.0.0"
374374
rebuild_rel = next(rel for rel in zzz["latest_releases"] if rel["version"] == "1.0.0")
375-
assert rebuild_rel["release"] == "rhlw-00003"
375+
assert rebuild_rel["release"] == "test.3"
376376
assert zzz["last_updated"] == rebuild_rel["created_at"]
377377
public_rel = next(rel for rel in zzz["latest_releases"] if rel["version"] == "2.0.0")
378378
assert public_rel["release"] == ""
@@ -392,7 +392,7 @@ def test_public_and_predisclosure_collapse_to_logical_version(
392392
tmp_path,
393393
repo,
394394
name,
395-
"5.3.17.rhlw-00001-n0001",
395+
"5.3.17+test.1.n1",
396396
)
397397

398398
pkgs = _api_get(bindings_cfg, f"{repo.pulp_href}packages/")
@@ -402,7 +402,7 @@ def test_public_and_predisclosure_collapse_to_logical_version(
402402
assert pkg["versions"] == ["5.3.17"]
403403
assert len(pkg["latest_releases"]) == 1
404404
assert pkg["latest_releases"][0]["version"] == "5.3.17"
405-
assert pkg["latest_releases"][0]["release"] == "rhlw-00001-n0001"
405+
assert pkg["latest_releases"][0]["release"] == "test.1.n1"
406406

407407
metrics = _api_get(bindings_cfg, f"{repo.pulp_href}metrics/")
408408
assert metrics == {"package_count": 1, "version_count": 1, "build_count": 2}
@@ -432,7 +432,7 @@ def test_public_and_predisclosure_collapse_to_logical_version(
432432
assert collapsed["count"] == 1
433433
kept = collapsed["results"][0]
434434
assert kept["base_version"] == "5.3.17"
435-
assert kept["version"] == "5.3.17.rhlw-00001-n0001"
435+
assert kept["version"] == "5.3.17+test.1.n1"
436436

437437

438438
@pytest.mark.parallel

‎pulp_python/tests/unit/test_catalog.py‎

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,26 +16,29 @@
1616
)
1717

1818

19+
# A rebuild is a PEP 440 local version: from ``+`` through the end of the
20+
# string. The public version is everything before ``+``. ``release`` is the
21+
# local identifier without the leading ``+``.
1922
@pytest.mark.parametrize(
2023
"version,expected",
2124
[
2225
("0.1", "0.1"),
2326
("5.3.17", "5.3.17"),
2427
("5.3.18", "5.3.18"),
2528
("5.3.180", "5.3.180"),
26-
("5.3.17.rhlw-00001", "5.3.17"),
27-
("5.3.18.rhlw-00003", "5.3.18"),
28-
("5.3.17.rhlw-00001-n0001", "5.3.17"),
29-
("5.3.18.lw-1", "5.3.18"),
30-
("1.0.0.abc-1", "1.0.0"),
31-
("1.0.0.ABC-99", "1.0.0"),
32-
("1.0.foo-bar", "1.0"),
33-
("1.0.rhlw-١", "1.0"),
29+
("5.3.17+test.1", "5.3.17"),
30+
("5.3.18+test.2", "5.3.18"),
31+
("5.3.17+test.1.n1", "5.3.17"),
32+
("5.3.17+test.1.n1.hf2", "5.3.17"),
33+
("1.0.0+foo.bar", "1.0.0"),
34+
("1.2.3a1+test.1", "1.2.3a1"),
35+
("1!1.2.3+test.1", "1!1.2.3"),
36+
("1.0+", "1.0"),
3437
("4.3.0-redhat-1", "4.3.0-redhat-1"),
3538
("5.3.18-anything", "5.3.18-anything"),
3639
("5.3.18.anything", "5.3.18.anything"),
37-
("1.0.rhlw-00003.extra", "1.0.rhlw-00003.extra"),
38-
("1.0.rhlw-", "1.0.rhlw-"),
40+
("5.3.17.test-00001", "5.3.17.test-00001"),
41+
("1.0.test-1.extra", "1.0.test-1.extra"),
3942
("", ""),
4043
(None, None),
4144
],
@@ -48,17 +51,17 @@ def test_strip_build_suffix(version, expected):
4851
"version,expected",
4952
[
5053
("5.3.18", ""),
51-
("5.3.17.rhlw-00001", "rhlw-00001"),
52-
("5.3.18.rhlw-00003", "rhlw-00003"),
53-
("5.3.17.rhlw-00001-n0001", "rhlw-00001-n0001"),
54-
("5.3.18.lw-1", "lw-1"),
55-
("0.1.rhlw-00003", "rhlw-00003"),
56-
("1.0.foo-bar", "foo-bar"),
57-
("1.0.rhlw-١", "rhlw-١"),
54+
("5.3.17+test.1", "test.1"),
55+
("5.3.18+test.2", "test.2"),
56+
("5.3.17+test.1.n1", "test.1.n1"),
57+
("5.3.17+test.1.n1.hf2", "test.1.n1.hf2"),
58+
("1.0.0+foo.bar", "foo.bar"),
59+
("1.2.3a1+test.1", "test.1"),
60+
("1.0+", ""),
5861
("5.3.18.anything", ""),
5962
("4.3.0-redhat-1", ""),
6063
("5.3.18-anything", ""),
61-
("1.0.rhlw-", ""),
64+
("5.3.17.test-00001", ""),
6265
("", ""),
6366
(None, ""),
6467
],

0 commit comments

Comments
 (0)