From 43ba58ab1424c33d7ee421494eafbb3739375c99 Mon Sep 17 00:00:00 2001 From: gavanderhoorn Date: Fri, 3 Jul 2026 19:04:48 +0200 Subject: [PATCH 1/4] distro: introduce raw URL formatters Refactor GitHub formatting code and add GitLab formatter. --- vinca/distro.py | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/vinca/distro.py b/vinca/distro.py index 84fcade..008e33c 100644 --- a/vinca/distro.py +++ b/vinca/distro.py @@ -215,3 +215,39 @@ def get_package_xml_for_additional_package(self, pkg_info): return xml_content except Exception as e: raise RuntimeError(f"Failed to fetch package.xml from {raw_url}: {e}") + + # Based on https://github.com/ros-infrastructure/rosdistro/blob/fad8d9f647631945847cb18bc1d1f43008d7a282/src/rosdistro/manifest_provider/github.py#L51C1-L69C29 + # But with the option to specify the name of the package.xml file in case the repo uses a non-standard name + def _construct_raw_url_github(self, pkg_info): + # Build raw GitHub URL for package.xml + raw_url_base = pkg_info.get("url") + if raw_url_base.endswith(".git"): + raw_url_base = raw_url_base[:-4] + if "github.com" not in raw_url_base: + raise RuntimeError(f"Cannot handle non-GitHub URL: {raw_url_base}") + # Extract owner/repo + owner_repo = raw_url_base.split("github.com/")[-1] + # Use rev if available, otherwise fallback to tag + ref = pkg_info.get("rev") or pkg_info.get("tag") + xml_name = pkg_info.get("package_xml_name", "package.xml") + additional_folder = pkg_info.get("additional_folder", "") + if additional_folder != "": + additional_folder = additional_folder + "/" + raw_url = f"https://raw.githubusercontent.com/{owner_repo}/{ref}/{additional_folder}{xml_name}" + return raw_url + + # format (checked against GitLab 19.x): https://gitlab.com//-/raw// + def _construct_raw_url_gitlab(self, pkg_info): + raw_url_base = pkg_info.get("url") + if raw_url_base.endswith(".git"): + raw_url_base = raw_url_base[:-4] + if "gitlab.com" not in raw_url_base: + raise RuntimeError(f"Cannot handle non-GitLab URL: {raw_url_base}") + # Use rev if available, otherwise fallback to tag + ref = pkg_info.get("rev") or pkg_info.get("tag") + xml_name = pkg_info.get("package_xml_name", "package.xml") + additional_folder = pkg_info.get("additional_folder", "") + if additional_folder != "": + additional_folder = additional_folder + "/" + raw_url = f"{raw_url_base}/-/raw/{ref}/{additional_folder}{xml_name}" + return raw_url From c37decca909a3ee53f9450571c49bae4c965ee41 Mon Sep 17 00:00:00 2001 From: gavanderhoorn Date: Fri, 3 Jul 2026 19:06:29 +0200 Subject: [PATCH 2/4] distro: add manifest download helper Return either cached version or attempt download and return result. --- vinca/distro.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/vinca/distro.py b/vinca/distro.py index 008e33c..b49caad 100644 --- a/vinca/distro.py +++ b/vinca/distro.py @@ -216,6 +216,17 @@ def get_package_xml_for_additional_package(self, pkg_info): except Exception as e: raise RuntimeError(f"Failed to fetch package.xml from {raw_url}: {e}") + def _download_raw_pkg_xml_or_cached(self, url): + if url in self._additional_xml_cache: + return self._additional_xml_cache[url] + try: + with urllib.request.urlopen(url) as resp: + xml_content = resp.read().decode("utf-8") + self._additional_xml_cache[url] = xml_content + return xml_content + except Exception as e: + raise RuntimeError(f"Failed to fetch package.xml from {url}: {e}") + # Based on https://github.com/ros-infrastructure/rosdistro/blob/fad8d9f647631945847cb18bc1d1f43008d7a282/src/rosdistro/manifest_provider/github.py#L51C1-L69C29 # But with the option to specify the name of the package.xml file in case the repo uses a non-standard name def _construct_raw_url_github(self, pkg_info): From 096ce104186b350992b9abb60f5b73b98e00985e Mon Sep 17 00:00:00 2001 From: gavanderhoorn Date: Fri, 3 Jul 2026 19:08:24 +0200 Subject: [PATCH 3/4] distro: download GitHub raw URL using helpers --- vinca/distro.py | 28 ++++------------------------ 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/vinca/distro.py b/vinca/distro.py index b49caad..c427a66 100644 --- a/vinca/distro.py +++ b/vinca/distro.py @@ -190,31 +190,11 @@ def get_package_names(self): # Based on https://github.com/ros-infrastructure/rosdistro/blob/fad8d9f647631945847cb18bc1d1f43008d7a282/src/rosdistro/manifest_provider/github.py#L51C1-L69C29 # But with the option to specify the name of the package.xml file in case the repo uses a non-standard name def get_package_xml_for_additional_package(self, pkg_info): - # Build raw GitHub URL for package.xml raw_url_base = pkg_info.get("url") - if raw_url_base.endswith(".git"): - raw_url_base = raw_url_base[:-4] - if "github.com" not in raw_url_base: - raise RuntimeError(f"Cannot handle non-GitHub URL: {raw_url_base}") - # Extract owner/repo - owner_repo = raw_url_base.split("github.com/")[-1] - # Use rev if available, otherwise fallback to tag - ref = pkg_info.get("rev") or pkg_info.get("tag") - xml_name = pkg_info.get("package_xml_name", "package.xml") - additional_folder = pkg_info.get("additional_folder", "") - if additional_folder != "": - additional_folder = additional_folder + "/" - raw_url = f"https://raw.githubusercontent.com/{owner_repo}/{ref}/{additional_folder}{xml_name}" - if raw_url in self._additional_xml_cache: - return self._additional_xml_cache[raw_url] - - try: - with urllib.request.urlopen(raw_url) as resp: - xml_content = resp.read().decode("utf-8") - self._additional_xml_cache[raw_url] = xml_content - return xml_content - except Exception as e: - raise RuntimeError(f"Failed to fetch package.xml from {raw_url}: {e}") + if "github.com" in raw_url_base: + raw_url = self._construct_raw_url_github(pkg_info) + return self._download_raw_pkg_xml_or_cached(url=raw_url) + raise RuntimeError(f"Cannot handle unknown repository hoster: {raw_url_base}") def _download_raw_pkg_xml_or_cached(self, url): if url in self._additional_xml_cache: From 0fa52f4f415a9a255a8d2b52754540a84cd1d18f Mon Sep 17 00:00:00 2001 From: gavanderhoorn Date: Fri, 3 Jul 2026 19:09:22 +0200 Subject: [PATCH 4/4] distro: support GitLab hosted pkgs and manifests --- vinca/distro.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/vinca/distro.py b/vinca/distro.py index c427a66..f096fab 100644 --- a/vinca/distro.py +++ b/vinca/distro.py @@ -194,6 +194,9 @@ def get_package_xml_for_additional_package(self, pkg_info): if "github.com" in raw_url_base: raw_url = self._construct_raw_url_github(pkg_info) return self._download_raw_pkg_xml_or_cached(url=raw_url) + if "gitlab.com" in raw_url_base: + raw_url = self._construct_raw_url_gitlab(pkg_info) + return self._download_raw_pkg_xml_or_cached(url=raw_url) raise RuntimeError(f"Cannot handle unknown repository hoster: {raw_url_base}") def _download_raw_pkg_xml_or_cached(self, url):