Coverage for src/backoffice/check_compatibility.py: 0%
42 statements
« prev ^ index » next coverage.py v7.10.7, created at 2025-11-12 10:26 +0000
« prev ^ index » next coverage.py v7.10.7, created at 2025-11-12 10:26 +0000
1"""check compatibility of tools against resources in the index.json"""
3import json
4import shutil
5import traceback
6import warnings
7from pathlib import Path
8from typing import TYPE_CHECKING, Callable
10from loguru import logger
12from .utils_pure import get_tool_report_path
14try:
15 from tqdm import tqdm
16except ImportError:
17 tqdm = list
20if TYPE_CHECKING:
21 from .compatibility import ToolCompatibilityReport
22 from .compatibility_pure import (
23 ToolCompatibilityReportDict as ToolCompatibilityReportDict,
24 )
27ItemId = str
28ItemVersion = str
29Url = str
30Sha256 = str
33def check_tool_compatibility(
34 tool_name: str,
35 tool_version: str,
36 *,
37 index_path: Path = Path("index.json"),
38 check_tool_compatibility_impl: Callable[
39 [ItemId, ItemVersion, Url, Sha256],
40 "ToolCompatibilityReport | ToolCompatibilityReportDict",
41 ],
42 applicable_types: set[str],
43 id_startswith: str = "",
44):
45 """helper to implement tool compatibility checks
47 Args:
48 tool_name: name of the tool (without version), e.g. "ilastik"
49 tool_version: version of the tool, e.g. "1.4"
50 index_path: Path to the `index.json` file.
51 check_tool_compatibility_impl:
52 Function accepting two positional arguments:
53 URL to an rdf.yaml, SHA-256 of that rdf.yaml.
54 And returning a compatibility report.
55 applicable_types: Set of resource types
56 **check_tool_compatibility_impl** is applicable to.
57 """
58 with index_path.open() as f:
59 items = json.load(f)["items"]
61 filtered_items = [
62 item
63 for item in items
64 if item["type"] in applicable_types and item["id"].startswith(id_startswith)
65 ]
66 print(f"found {len(filtered_items)} starting with '{id_startswith}'")
68 for item in tqdm(filtered_items):
69 for version in item["versions"]:
70 rdf_url = version["source"]
71 sha256 = version["sha256"]
73 report_path = get_tool_report_path(
74 item["id"], version["version"], tool_name, tool_version
75 )
76 if report_path.exists():
77 logger.info("found existing report at {}", report_path)
78 continue
80 try:
81 report = check_tool_compatibility_impl(
82 item["id"], version["version"], rdf_url, sha256
83 )
84 except Exception as e:
85 traceback.print_exc()
86 warnings.warn(f"failed to check '{rdf_url}': {e}")
87 else:
88 if not isinstance(report, dict):
89 report = report.model_dump(mode="json")
91 report_path.parent.mkdir(parents=True, exist_ok=True)
92 with report_path.open("wt", encoding="utf-8") as f:
93 json.dump(report, f, indent=4, sort_keys=True, ensure_ascii=False)
95 _total, _used, free = shutil.disk_usage(".")
96 if free < 7_000_000_000:
97 raise RuntimeError("less than 7GB disk space left, stopping now")