fix: fetch rosdistro yaml from <distro>/distro.yaml

This commit is contained in:
Maik Knof
2025-12-29 16:37:04 +00:00
parent 4b9b7b6336
commit c4ec2bb6c1
3 changed files with 58 additions and 19 deletions

View File

@@ -17,9 +17,6 @@ def _raw_url(base_url: str, owner: str, repo: str, branch: str, file_path: str)
def _parse_package_ref(value: str) -> tuple[str, str, str]:
"""
Parses "owner/repo@ref" into (owner, repo, ref).
"""
value = value.strip()
if "@" not in value:
@@ -45,6 +42,15 @@ def _parse_package_ref(value: str) -> tuple[str, str, str]:
return owner, repo, ref
def _fetch_text(url: str, timeout_s: float) -> str:
resp = requests.get(url, timeout=timeout_s)
if resp.status_code != 200:
raise RuntimeError(
f"Failed to fetch '{url}' (HTTP {resp.status_code}): {resp.text}"
)
return resp.text
def fetch_rosdistro_packages(
*,
base_url: str,
@@ -55,22 +61,42 @@ def fetch_rosdistro_packages(
timeout_s: float = 20.0,
) -> Dict[str, Package]:
"""
Fetches rosdistro/<rosdistro>/distro.yaml from a Gitea repo and parses it into:
Tries these paths (in order):
1) <rosdistro>/distro.yaml (your current layout)
2) rosdistro/<rosdistro>/distro.yaml (fallback / older layout)
Returns:
{ package_name: Package(name, owner, repo, ref) }
"""
file_path = f"rosdistro/{rosdistro}/distro.yaml"
url = _raw_url(base_url, owner, repo, branch, file_path)
candidates = [
f"{rosdistro}/distro.yaml",
f"rosdistro/{rosdistro}/distro.yaml",
]
resp = requests.get(url, timeout=timeout_s)
if resp.status_code != 200:
raise RuntimeError(
f"Failed to fetch '{url}' (HTTP {resp.status_code}): {resp.text}"
last_err: Exception | None = None
text: str | None = None
used_path: str | None = None
for file_path in candidates:
url = _raw_url(base_url, owner, repo, branch, file_path)
try:
text = _fetch_text(url, timeout_s)
used_path = file_path
break
except Exception as e:
last_err = e
if text is None or used_path is None:
raise (
last_err
if last_err is not None
else RuntimeError("Failed to fetch rosdistro YAML")
)
data = yaml.safe_load(resp.text)
data = yaml.safe_load(text)
if not isinstance(data, dict):
raise ValueError(
f"Invalid YAML structure in {file_path}: expected mapping at root"
f"Invalid YAML structure in {used_path}: expected mapping at root"
)
packages: Dict[str, Package] = {}

View File

@@ -1,6 +1,6 @@
from __future__ import annotations
from typing import Any, Dict
from typing import Dict
from ros2cli.verb import VerbExtension
@@ -8,7 +8,7 @@ from ..package import Package
class ListVerb(VerbExtension):
"""List packages from rosdistro/<rosdistro>/distro.yaml."""
"""List packages from <rosdistro>/distro.yaml."""
def add_arguments(self, parser, cli_name):
parser.add_argument(
@@ -22,9 +22,17 @@ class ListVerb(VerbExtension):
packages: Dict[str, Package] = getattr(args, "packages", {})
if args.format == "yaml":
for name in sorted(packages.keys()):
pkg = packages[name]
print(f"{name}: {pkg.owner}/{pkg.repo}@{pkg.ref}")
out = {}
for name, pkg in packages.items():
out[name] = {
"owner": pkg.owner,
"repo": pkg.repo,
"ref": pkg.ref,
}
import yaml
print(yaml.dump(out, sort_keys=True))
return 0
for name in sorted(packages.keys()):
@@ -36,6 +44,11 @@ class ListVerb(VerbExtension):
def add_list_verb(subparsers):
parser = subparsers.add_parser("list", help="List packages from rosdistro")
verb = ListVerb()
verb.add_arguments(parser, "buildfarm")
parser.set_defaults(main=verb.main)
def _run_list_verb(args):
return verb.main(args=args)
parser.set_defaults(main=_run_list_verb)

View File

@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<package format="3">
<name>buildfarm</name>
<version>0.0.1</version>
<version>0.0.2</version>
<description>Scripts to build ROS2 packages as .deb packages.</description>
<maintainer email="mail@maikknof.de">Maik Knof</maintainer>
<license>TODO</license>