fix(sbom): resolve repo path from hub host_paths when --repo-path omitted

Previously defaulted to CWD ("."), causing ingest to silently scan the
state-hub directory instead of the target repo when called without
--repo-path. Now queries GET /repos/{slug}/ for host_paths[hostname]
and exits with a clear error if neither flag nor hub lookup succeeds.

Also deleted the incorrect SBOM snapshot for repo-registry (420 entries
that were actually state-hub packages).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-26 13:27:09 +02:00
parent 6ec47dfde4
commit fa31befeff

View File

@@ -22,6 +22,7 @@ import argparse
import json
import os
import re
import socket
import sys
import urllib.error
import urllib.request
@@ -505,6 +506,23 @@ def post_ingest(api_base: str, repo_slug: str, entries: list[dict]) -> dict:
# Entry point
# ---------------------------------------------------------------------------
def _resolve_repo_path_from_hub(api_base: str, repo_slug: str) -> Path | None:
"""Query the hub for this host's registered path for repo_slug."""
try:
url = f"{api_base}/repos/{repo_slug}/"
with urllib.request.urlopen(url) as resp:
data = json.loads(resp.read())
hostname = socket.gethostname()
host_paths = data.get("host_paths", {})
if hostname in host_paths:
p = Path(host_paths[hostname])
if p.exists():
return p
except Exception:
pass
return None
def main() -> None:
parser = argparse.ArgumentParser(
description="Ingest a repo's lockfiles and tool manifests into the State Hub SBOM store."
@@ -512,14 +530,28 @@ def main() -> None:
parser.add_argument("--repo", required=True, help="Managed-repo slug (e.g. 'the-custodian')")
parser.add_argument("--lockfile", action="append", dest="lockfiles",
metavar="PATH", help="Path to a specific lockfile (repeatable)")
parser.add_argument("--repo-path", default=".", help="Repo root for auto-detection/scan (default: cwd)")
parser.add_argument("--repo-path", default=None,
help="Repo root for auto-detection/scan (default: resolved from hub host_paths)")
parser.add_argument("--scan", action="store_true",
help="Recursively find ALL lockfiles under --repo-path (deprecated; now default behaviour)")
parser.add_argument("--api-base", default=API_BASE, help="State Hub API base URL")
parser.add_argument("--dry-run", action="store_true", help="Parse only — do not submit")
args = parser.parse_args()
repo_root = Path(args.repo_path).resolve()
if args.repo_path is not None:
repo_root = Path(args.repo_path).resolve()
else:
resolved = _resolve_repo_path_from_hub(args.api_base, args.repo)
if resolved:
repo_root = resolved
print(f" Repo path resolved from hub: {repo_root}")
else:
print(
f"ERROR: --repo-path not given and hub lookup failed for '{args.repo}'.\n"
f" Register the repo first or pass --repo-path explicitly.",
file=sys.stderr,
)
sys.exit(1)
all_entries: list[dict] = []
if args.lockfiles: