Coverage for src/gitlabracadabra/packages/pulp_manifest.py: 80%
38 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-19 07:59 +0100
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-19 07:59 +0100
1#
2# Copyright (C) 2019-2025 Mathieu Parent <math.parent@gmail.com>
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU Lesser General Public License as published by
6# the Free Software Foundation, either version 3 of the License, or
7# (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU Lesser General Public License for more details.
13#
14# You should have received a copy of the GNU Lesser General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
17from __future__ import annotations
19from logging import getLogger
20from urllib.parse import urljoin
22from requests import codes
24from gitlabracadabra.packages.package_file import PackageFile
25from gitlabracadabra.packages.source import Source
27logger = getLogger(__name__)
30class PulpManifestSource(Source):
31 """PULP_MANIFEST repository."""
33 def __init__(
34 self,
35 *,
36 log_prefix: str = "",
37 url: str,
38 package_name: str,
39 package_version: str | None = None,
40 ) -> None:
41 """Initialize a PULP_MANIFEST Source object.
43 Args:
44 log_prefix: Log prefix.
45 url: PULP_MANIFEST URL.
46 package_name: Destination package name.
47 package_version: Destination package version.
48 """
49 super().__init__()
50 self._log_prefix = log_prefix
51 self._url = url
52 self._package_name = package_name
53 self._package_version = package_version or "0"
55 def __str__(self) -> str:
56 """Return string representation.
58 Returns:
59 A string.
60 """
61 return f"PULP_MANIFEST repository (url={self._url})"
63 @property
64 def package_files(self) -> list[PackageFile]:
65 """Return list of package files.
67 Returns:
68 List of package files.
69 """
70 package_files: list[PackageFile] = []
71 pulp_manifest_response = self.session.request("get", self._url, stream=True)
72 if pulp_manifest_response.status_code != codes["ok"]: 72 ↛ 73line 72 didn't jump to line 73 because the condition on line 72 was never true
73 logger.warning(
74 "%sUnexpected HTTP status for PULP_MANIFEST url %s: received %i %s",
75 self._log_prefix,
76 self._url,
77 pulp_manifest_response.status_code,
78 pulp_manifest_response.reason,
79 )
80 return []
81 if pulp_manifest_response.encoding is None: 81 ↛ 82line 81 didn't jump to line 82 because the condition on line 81 was never true
82 pulp_manifest_response.encoding = "utf-8"
83 for pulp_manifest_line in pulp_manifest_response.iter_lines(decode_unicode=True):
84 try:
85 filename, sha256_checksum, size_in_bytes = pulp_manifest_line.split(",", 3)
86 except ValueError:
87 logger.warning(
88 "%sInvalid PULP_MANIFEST line: %s",
89 self._log_prefix,
90 pulp_manifest_line,
91 )
92 continue
93 package_file = self._package_file(filename, sha256_checksum, size_in_bytes)
94 if package_file: 94 ↛ 83line 94 didn't jump to line 83 because the condition on line 94 was always true
95 package_files.append(package_file)
96 return package_files
98 def _package_file(self, filename: str, sha256_checksum: str, size_in_bytes: str) -> PackageFile | None:
99 url = urljoin(self._url, filename, allow_fragments=False)
100 return PackageFile(
101 url,
102 "raw",
103 self._package_name,
104 self._package_version,
105 url.split("/").pop(),
106 metadata={
107 "sha256_checksum": sha256_checksum,
108 "size_in_bytes": size_in_bytes,
109 },
110 )