diff --git a/buildfarm/rosdistro_loader.py b/buildfarm/rosdistro_loader.py index 4051796..a7b18ff 100644 --- a/buildfarm/rosdistro_loader.py +++ b/buildfarm/rosdistro_loader.py @@ -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//distro.yaml from a Gitea repo and parses it into: + Tries these paths (in order): + 1) /distro.yaml (your current layout) + 2) 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] = {} diff --git a/buildfarm/verb/list.py b/buildfarm/verb/list.py index 61d247a..1db902b 100644 --- a/buildfarm/verb/list.py +++ b/buildfarm/verb/list.py @@ -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//distro.yaml.""" + """List packages from /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) diff --git a/package.xml b/package.xml index d5996be..0fbdfdb 100644 --- a/package.xml +++ b/package.xml @@ -1,7 +1,7 @@ buildfarm - 0.0.1 + 0.0.2 Scripts to build ROS2 packages as .deb packages. Maik Knof TODO