mirror of
https://github.com/kuhyx/utils.git
synced 2026-11-10 21:27:14 +01:00
Some checks are pending
dependency freshness / dependencies on newest stable (push) Waiting to run
file length / file-length (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
palette drift / palette (push) Waiting to run
shared gate tests / gate unit tests (push) Waiting to run
Three findings from proving the JitPack fix on the TachiyomiSY gate:
- The first repository with a stable answer used to win. Central still
carries com.github.ben-manes:gradle-versions-plugin 0.11.1 (2016) while
the plugin portal has 0.54.0, so a 0.51.0 pin graded "current". Every
repository is now asked and the newest stable across the pooled lists is
the answer.
- ~900 lookups, eight at a time, each resolving the registry host (A+AAAA)
per connection: the LAN router's forwarder started dropping queries for
every client on the LAN and the gate degraded itself. socket.getaddrinfo
is memoised per (host, port, hints) for the run, and the per-host probe
runs under a lock so eight workers make one probe, not eight.
- A resolver EAI_AGAIN ("temporary failure") during the probe marked the
registry unreachable for the whole run. The probe retries it
HTTP_ATTEMPTS times; a permanent failure still fails immediately.
Both retry loops lost their unreachable `return` sentinel (http.py is at
100% branch now); the resolver tests live in test_http_resolver.py to keep
test_http.py under the 250-line cap.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016P4KZw1E2sXJjYqfcZWf1x
84 lines
3.5 KiB
Python
84 lines
3.5 KiB
Python
"""Maven repositories: newest stable of `group:artifact`, from maven-metadata.
|
|
|
|
Three repositories, ALL asked: Google Maven (every `androidx.*` and
|
|
`com.android.*` artifact lives ONLY there), Maven Central and the Gradle
|
|
plugin portal (plugin marker artifacts `<id>:<id>.gradle.plugin`). The
|
|
version lists are pooled and the newest stable across them wins. Stopping at
|
|
the first repository that knew the artifact graded
|
|
`com.github.ben-manes:gradle-versions-plugin` current at 0.51.0 because
|
|
Central still carries its 2016 releases (0.11.1) while the plugin portal has
|
|
0.54.0 (2026-09-18). A 404 means "not here", not "not anywhere"; anything
|
|
else surfaces as `Offline` from the HTTP layer.
|
|
|
|
JitPack used to be the fourth: it served tag metadata for `com.github.*`
|
|
artifacts published nowhere else (PhotoView, DirectionalViewPager). Since
|
|
2026-09 that endpoint answers HTTP 401 "No access token" while the artifacts
|
|
themselves still download, so a `com.github.<owner>:<repo>` name that no
|
|
repository knows is answered from the GitHub repo's tags over `git
|
|
ls-remote` (unmetered, no token). JitPack's version IS the tag name, `v`
|
|
prefix included, so the tags are compared as they are.
|
|
|
|
`<latest>` and `<release>` in the metadata are not trusted: AndroidX writes
|
|
`1.2.0-alpha03` into `<latest>` routinely. The full `<versions>` list goes
|
|
through `newest_stable` like every other ecosystem. Only when NO repository
|
|
has a stable release at all does the newest pre-release become the reference
|
|
(`versions.reference`), which is how `androidx.biometric:biometric-ktx`,
|
|
alpha-only since 2021, gets a checkable answer. Google's API clients
|
|
(`v3-rev20260901-2.0.0`) are neither: for those the answer is the newest
|
|
revision of every generation, and the judge picks the pin's own.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from xml.etree import ElementTree
|
|
|
|
from dep_freshness._tables import GITHUB_REMOTE, MAVEN_REPOS
|
|
from dep_freshness.registries._git import ls_remote
|
|
from dep_freshness.registries.gitcommit import source_repo
|
|
from dep_freshness.registries.http import get_text
|
|
from dep_freshness.versions import newest_per_generation, reference
|
|
|
|
|
|
def metadata_url(repo: str, name: str) -> str | None:
|
|
"""`.../group/path/artifact/maven-metadata.xml`, or None for a bad name."""
|
|
group, sep, artifact = name.partition(":")
|
|
if not sep or not group or not artifact:
|
|
return None
|
|
return f"{repo}{group.replace('.', '/')}/{artifact}/maven-metadata.xml"
|
|
|
|
|
|
def versions_in(xml: str) -> list[str]:
|
|
"""Every `<version>` in a maven-metadata document; [] when unparseable."""
|
|
try:
|
|
root = ElementTree.fromstring(xml)
|
|
except ElementTree.ParseError:
|
|
return []
|
|
return [
|
|
(node.text or "").strip()
|
|
for node in root.iter("version")
|
|
if node.text and node.text.strip()
|
|
]
|
|
|
|
|
|
def github_tags(name: str) -> list[str]:
|
|
"""Every tag of the GitHub repo behind a JitPack coordinate; [] otherwise."""
|
|
repo = source_repo(name)
|
|
if repo is None:
|
|
return []
|
|
lines = ls_remote(GITHUB_REMOTE.format(repo=repo), "--tags", "--refs")
|
|
return [line.rpartition("refs/tags/")[2] for line in lines if "refs/tags/" in line]
|
|
|
|
|
|
def latest(name: str) -> str | None:
|
|
seen: list[str] = []
|
|
for repo in MAVEN_REPOS:
|
|
url = metadata_url(repo, name)
|
|
if url is None:
|
|
return None
|
|
body = get_text(url)
|
|
if body is not None:
|
|
seen.extend(versions_in(body))
|
|
if not seen:
|
|
seen.extend(github_tags(name))
|
|
return reference(seen) or newest_per_generation(seen)
|