diff --git a/collector/jq_collector/forge.py b/collector/jq_collector/forge.py index 378d590..1c4316f 100644 --- a/collector/jq_collector/forge.py +++ b/collector/jq_collector/forge.py @@ -63,6 +63,15 @@ def normalise_gitlab_status(status: str) -> str: An unrecognised status becomes ``stale`` rather than ``failure``: GitLab has added states before and will again, and a new one appearing as a fleet-wide red is a worse failure mode than it appearing as "no verdict yet". + + >>> normalise_gitlab_status("failed") + 'failure' + >>> normalise_gitlab_status(" Canceled ") + 'cancelled' + >>> normalise_gitlab_status("manual") + 'cancelled' + >>> normalise_gitlab_status("some_future_state") + 'stale' """ return _GITLAB_STATUS.get((status or "").strip().lower(), "stale") diff --git a/collector/jq_collector/origin.py b/collector/jq_collector/origin.py index 80b2cce..983067c 100644 --- a/collector/jq_collector/origin.py +++ b/collector/jq_collector/origin.py @@ -58,6 +58,11 @@ def forge_for_host(host: str) -> str: exactly as they did before this module existed; a fleet on some other forge says so with an explicit ``forge:`` in repos.yml rather than relying on a guess from a hostname. + + >>> forge_for_host("gitlab.com"), forge_for_host("gitlab.example.org") + ('gitlab', 'gitlab') + >>> forge_for_host("github.example.org"), forge_for_host("") + ('github', 'github') """ host = host.lower() if host == "gitlab.com" or host.startswith("gitlab."): @@ -70,6 +75,21 @@ def parse(url: str) -> Origin | None: Handles the four shapes a remote is written in: ``scheme://host/path``, the scp-like ``[user@]host:path``, and a bare absolute or relative path. + + >>> parse("git@github.com:Jebel-Quant/monitoring.git") + Origin(host='github.com', namespace='Jebel-Quant', name='monitoring') + + A GitLab namespace keeps every segment, not just the last one: + + >>> parse("https://gitlab.com/acme/platform/infra/web.git").full_name + 'acme/platform/infra/web' + + A path remote has no host, so only its tail names the repo: + + >>> parse("/srv/mirrors/o/r") + Origin(host='', namespace='o', name='r') + >>> parse("git@github.com:lonely") is None + True """ url = url.strip().removesuffix(".git") if not url: diff --git a/collector/pyproject.toml b/collector/pyproject.toml index 73b5b8c..5fe2a10 100644 --- a/collector/pyproject.toml +++ b/collector/pyproject.toml @@ -20,10 +20,12 @@ packages = ["jq_collector"] dev = ["pytest>=8.0", "pytest-cov>=5.0", "ruff>=0.16"] [tool.pytest.ini_options] -testpaths = ["tests"] +# The package too, for its doctests: an example in a docstring is a claim, +# and --doctest-modules is what keeps the claims true. +testpaths = ["tests", "jq_collector"] # tests/ imports conftest helpers directly, so it needs to be on sys.path. pythonpath = ["tests"] -addopts = "-q" +addopts = "-q --doctest-modules" [tool.coverage.run] # The package, not the tests - measuring the tests inflates the figure with