Coverage for src/gitlabracadabra/containers/manifest_base.py: 94%
29 statements
« prev ^ index » next coverage.py v7.8.0, created at 2025-04-14 23:10 +0200
« prev ^ index » next coverage.py v7.8.0, created at 2025-04-14 23:10 +0200
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 json import loads as json_loads
20from typing import TYPE_CHECKING, Any
22from gitlabracadabra.containers.const import MANIFEST
23from gitlabracadabra.containers.with_digest import WithDigest
25if TYPE_CHECKING: 25 ↛ 26line 25 didn't jump to line 26 because the condition on line 25 was never true
26 from gitlabracadabra.containers.registry_importer import RegistryImporter
29class ManifestBase(WithDigest):
30 """Base methods for manifest or manifest list."""
32 supported_mime_types = MANIFEST
34 def __init__(
35 self,
36 registry: RegistryImporter,
37 manifest_name: str,
38 digest: str | None = None,
39 *,
40 size: int | None = None,
41 mime_type: str | None = None,
42 tag: str = "latest",
43 ) -> None:
44 """Instanciate a manifest.
46 Args:
47 registry: Registry.
48 manifest_name: Manifest name (Example: library/debian).
49 digest: Digest.
50 size: Size.
51 mime_type: Content-Type / mediaType.
52 tag: Manifest tag (Example: latest).
53 """
54 super().__init__(registry, manifest_name, digest, size=size, mime_type=mime_type)
55 self.tag = tag or "latest"
56 self._json = None
57 self.platform = None
58 self._retrieve_mehod = "get"
60 @property
61 def json(self) -> Any:
62 """Get JSON.
64 Returns:
65 JSON.
66 """
67 if self._json is None:
68 self._ensure_cached()
69 with self as opened_manifest:
70 self._json = json_loads(opened_manifest.read().decode("utf-8"))
71 return self._json
73 @property
74 def registry_path(self) -> str:
75 """Get relative path of the manifest in the registry.
77 Returns:
78 The path.
79 """
80 if self._digest is not None:
81 return f"/v2/{self.manifest_name}/manifests/{self._digest}"
82 return f"/v2/{self.manifest_name}/manifests/{self.tag}"
84 def __str__(self) -> str:
85 """Get string representation.
87 Returns:
88 The full reference
89 (docker.io/library/busybox:latest@sha256:c6b45a95f932202dbb27c31333c4789f45184a744060f6e569cc9d2bf1b9ad6f).
90 """
91 return "{}/{}:{}{}".format(
92 self.registry.hostname,
93 self.manifest_name,
94 self.tag,
95 f"@{self._digest}" if self._digest else "",
96 )