Files
omnigent-ai--omnigent/scripts/normalize_uv_lock_registry.py
2026-07-13 13:12:00 +08:00

128 lines
4.9 KiB
Python

"""Normalize the package index in ``uv.lock`` to the public PyPI URL.
Local ``uv`` runs resolve against whatever index is configured on the
developer's machine (e.g. the Databricks PyPI proxy via ``UV_INDEX_URL``
or ``~/.config/uv``), and ``uv`` rewrites every
``source = { registry = "<url>" }`` entry in ``uv.lock`` to that index.
For this OSS repo the committed lockfile must always point at public
PyPI (``https://pypi.org/simple``) so the lock is reproducible for
contributors who don't have the proxy — CI already pins
``UV_INDEX_URL: https://pypi.org/simple`` for the same reason.
This is a pre-commit *fixer*: it rewrites the registry URL in place and
exits non-zero when it changed anything, so the commit aborts and the
developer re-stages the normalized lockfile (mirroring
``end-of-file-fixer`` and friends). Only ``registry`` sources are
touched; ``git`` / ``path`` / ``editable`` sources are left alone.
Pass ``--check`` to validate without writing: it exits non-zero (and
names the offending URLs) when a file is *not* already canonical, but
leaves it untouched. CI runs this mode against the committed lockfile
*before* any ``uv`` command — a plain ``uv run pre-commit`` can't catch a
committed proxy URL, because ``uv`` re-syncs the working tree to CI's
own index (``pypi.org``) first and masks it.
Usage::
python scripts/normalize_uv_lock_registry.py uv.lock # fix
python scripts/normalize_uv_lock_registry.py --check uv.lock # verify
"""
from __future__ import annotations
import re
import sys
from pathlib import Path
# The canonical public index the committed lockfile must always use.
_CANONICAL_INDEX = "https://pypi.org/simple"
# The canonical file host for wheel/sdist direct URLs.
_CANONICAL_FILES_HOST = "https://files.pythonhosted.org"
# Matches a uv.lock registry source, capturing the surrounding literal so
# only the URL between the quotes is replaced, e.g.
# source = { registry = "https://pypi-proxy.example.com/simple" }
_REGISTRY_RE = re.compile(r'(registry = ")[^"]*(")')
# Matches any non-pypi.org host in a direct wheel/sdist url = "..." entry so
# proxy-resolved URLs (e.g. pypi-proxy.cloud.databricks.com) can be rewritten
# to files.pythonhosted.org. The path component (/packages/…) is identical
# between the proxy and the canonical host.
_DIRECT_URL_RE = re.compile(
r'(url = ")(https?://(?!files\.pythonhosted\.org)[^"]+?/packages/)([^"]*")'
)
def non_canonical_registries(text: str) -> list[str]:
"""Return the registry URLs and direct-URL hosts in *text* that are not canonical.
:param text: Full contents of a ``uv.lock`` file.
:returns: Each non-canonical URL, in order, with duplicates preserved.
"""
bad: list[str] = [
m.group(1)
for m in re.finditer(r'registry = "([^"]*)"', text)
if m.group(1) != _CANONICAL_INDEX
]
bad += [m.group(2) for m in _DIRECT_URL_RE.finditer(text)]
return bad
def normalize_text(text: str) -> str:
"""Return *text* with every registry and direct wheel/sdist URL rewritten to canonical hosts.
:param text: Full contents of a ``uv.lock`` file.
:returns: The normalized text.
"""
return _DIRECT_URL_RE.sub(
rf"\g<1>{_CANONICAL_FILES_HOST}/packages/\g<3>",
_REGISTRY_RE.sub(rf"\g<1>{_CANONICAL_INDEX}\g<2>", text),
)
def main(argv: list[str]) -> int:
"""Normalize (or, with ``--check``, validate) each given lockfile.
:param argv: Filenames to process, optionally preceded/followed by the
``--check`` flag (passed by pre-commit or CI).
:returns: In fix mode, ``1`` when a file was modified (so the commit
aborts and the change is re-staged) else ``0``. In ``--check``
mode, ``1`` when any file is not already canonical (printing the
offending URLs) else ``0``; no file is written.
"""
check = "--check" in argv
files = [a for a in argv if a != "--check"]
if check:
ok = True
for name in files:
offenders = non_canonical_registries(Path(name).read_text())
if offenders:
ok = False
unique = sorted(set(offenders))
print(
f"{name}: {len(offenders)} non-canonical registry "
f"source(s) (expected {_CANONICAL_INDEX}): {', '.join(unique)}"
)
print(
"Fix with: python scripts/normalize_uv_lock_registry.py "
f"{name} && git add {name}"
)
return 0 if ok else 1
changed = False
for name in files:
path = Path(name)
original = path.read_text()
normalized = normalize_text(original)
if normalized != original:
path.write_text(normalized)
print(f"{name}: normalized package index to {_CANONICAL_INDEX}")
changed = True
return 1 if changed else 0
if __name__ == "__main__":
raise SystemExit(main(sys.argv[1:]))