Coverage for src/phoenixpackagecleanup/package.py: 100%
18 statements
« prev ^ index » next coverage.py v7.10.3, created at 2025-09-05 18:23 +0000
« prev ^ index » next coverage.py v7.10.3, created at 2025-09-05 18:23 +0000
1from collections import defaultdict
2from dataclasses import dataclass
3from datetime import datetime, timezone
6@dataclass
7class PackageInfo:
8 """Package information relevant to decide for deletion
10 The package information are typically retrieved from the `repodata.json` index file of a conda channel repository
12 Attributes
13 ----------
14 filename : str
15 Filename of the package in the channel (key of the package map in `repodata.json`). Typically of the form
16 "{project_name}-[branch_name}-{package_hash}_{package_build_number}.conda"
17 name : str
18 The name of the package (the name used to install the package with eg pixi) "{project_name}"
19 upload_time : datetime
20 Time of the package upload to the channel (unix time)
21 version : str
22 Version associated to the package. For instance "v1.0.0" but can be any string
23 """
25 filename: str
26 name: str
27 upload_time: datetime
28 version: str
31@dataclass
32class PackageInfoCollection:
33 """Collection of PackageInfo to store for instance a entire channel packages information
35 The class groups the packages per channel-name
37 Attributes
38 ----------
39 packages: dict[str, list[PackageInfo]]
40 Dictionary with keys the package name (as used to download the package from channel) and values
41 a list of PackageInfo for each package archive in the channel.
42 """
44 packages_info: dict[str, list[PackageInfo]]
47def parse_repodata(repodata: dict) -> PackageInfoCollection:
48 """Parses the reodata dictionary into a `ChannelPackages`
50 Parameters
51 ----------
52 repodata : dict
53 repodata.json content loaded as a dict
55 Returns
56 -------
57 ChannelPackages
58 Packages available in the channel
59 """
60 # defaultdict(list) allows to create an empty list using dict["missing_key"] so we can append to the list directly
61 packages = defaultdict(list)
62 # conda channels can have either ".tar.gz" archives in "packages" or ".conda" packages in "packages.conda"
63 for packages_dict in [repodata["packages"], repodata["packages.conda"]]:
64 for package_filename, package_info in packages_dict.items():
65 packages[package_info["name"]].append(
66 PackageInfo(
67 filename=package_filename,
68 name=package_info["name"],
69 upload_time=datetime.fromtimestamp(package_info["timestamp"] / 1000, timezone.utc),
70 version=package_info["version"],
71 )
72 )
73 return PackageInfoCollection(dict(packages))