ADR 008 Finding a version in the repository - nekrozis/qtogo GitHub Wiki
Status: Accepted (2026-10-09).
-
Listing what a repository holds, and later planning an install, both begin by walking the same path: a host and a target name a directory, its children name versions, and one of those leads to an
Updates.xml. This is discovery, and it is the prerequisite bothlist-qt(P1) and the planner (P2) share. ADR-004 left the path template open on purpose โ "the candidate paths are an ordered probe list in the discovery layer" โ and this is that record. -
The layout is not one shape. Measured against
download.qt.io, a version's directory takes one of three observed shapes:shape what the version directory holds captured sample flat the aggregate Updates.xmland the package directories itselfโฆ/windows_x86/desktop/qt5_5152/nested one same-named child, qt6_680/qt6_680/, which holds themโฆ/windows_x86/desktop/qt6_680/arch-split children <ver>_<ext>/, one per architectureโฆ/windows_x86/desktop/qt6_6110/(A fourth arrangement,
<ver>_<ext>directly under the target, is seen for the pre-6.8 cross targets and forall_os/qt; it is the same probe entered one level up, and it gets its own fixture when those targets are listed.) -
Which shape a version uses is not a function of the version number.
windows_x86/ desktopbecame arch-split at 6.11.0,all_os/androidandall_os/wasmat 6.8.0, andlinux_x64,linux_arm64,mac_x64andwindows_arm64desktops are still nested at 6.11.0 and 6.12.0. The same version is nested on one host and split on another, so no single number can express the boundary. -
The reference tool encodes it as version checks and hardcoded architecture sets (
EXTENSIONS_WIN_X64_QT6_11and the like) and has paid for it with a maintenance burden measured in dozens of issues (D4 research ยง24). The captured listings underdev/qtogo/qt-repo-layout/html/are the evidence, and the three fixtures named above are the same shapes.
-
Discovery probes an ordered list of the observed shapes; it never branches on a version. A version directory is listed once, and the shapes are checked against that listing in a fixed order โ an
Updates.xmlof its own (flat), else a same-named child (nested), else<ver>_<ext>children (arch-split) โ and the first that matches decides. The three captured fixtures are exactly those three listings, which is what makes the probe a table-driven test rather than a hope. A new shape is added to the list with a captured sample. A rule of the formif version >= 6.8may not appear in this layer, because the table above shows the boundary is per host and target. -
Updates.xmlis authoritative; a directory name is a candidate. A token decoded by ADR-004 says a version may exist. The metadata inside the leaf says what it holds โ packages, versions, dependencies. Nothing is listed, installed or planned from a directory name alone. -
Architectures are read from the listing, not from a table. The
<ver>_<ext>children name the architectures a target offers, andextis everything after<ver>_: the split is at the first two underscores, soqt6_6110_msvc2022_arm64_cross_compiledkeepsmsvc2022_arm64_cross_compiledwhole. A hardcoded set of architectures is the reference tool's mistake and is not repeated. -
A page is a listing only if it says so. A listing must carry
Index of <path>matching the request; a 404 page is a failure, never an empty directory. The check is on the marker, not the size โ a one-child listing is a legitimate page, and the size test once misread one as a placeholder. -
The walk starts from an observed segment, and the segment is probed too. A host and target are addressed by a directory segment (
windows_x86,linux_x64,all_os, โฆ). There is no rule that a cross target sits underall_os:ioslives undermac_x64, whileandroidandwasmare underall_os. The segment for a (host, target) comes from an observed table, by the same discipline as the layout โ not derived from a version, and not derived from which kind of target it is. Where a target has lived under more than one segment, the candidates are tried in a fixed order. The table is a whitelist, and the walk never takes a directory child for a segment merely because it is one: the root holdsdefault_install, andall_osholdsqtcreator,license_agreementsand the like. The table lives with the code and grows from evidence, like the shape list.
- The probe is where the repository's shape changes are absorbed: a new layout is a new entry in a list and a fixture, not a branch in the planner or the CLI.
- The same code lists a 5.12 flat target and a 6.11 split one; the D4 research's four-shape model needs no version table to be encoded.
- A shape this project has not seen is reported as "not a recognised layout" rather than guessed at, so an upstream change surfaces as a failure to notice rather than as a wrong listing.
- Discovery costs one listing per level walked โ the segment and the version directory โ
plus a request for the leaf's
Updates.xml; the cache absorbs them later and the levels are few.
The exhaustive host/target-to-segment table and which targets are listable; caching a
listing; all_os/qt (source, documentation and examples) and the extensions repository
(โฆ/extensions/<module>/โฆ), which have their own shapes and arrive with them; and
everything about downloading or installing.
-
Branch on the version (
>= 6.8nested,>= 6.11split). Rejected: the boundary differs per target, so the rule is wrong forlinux_x64and forall_os. - Trust the directory name and skip the metadata. Rejected: the token is ambiguous (ADR-004) and says nothing about packages or architectures; the metadata is the truth.
- Hardcode the architecture suffixes, as the reference tool does. Rejected: it is the maintenance burden the D4 research measured, and the listing already states them.
-
Treat any page that returns 200 as a listing. Rejected: MirrorBrain answers a
missing path with a small "Not Found" page, which without the
Index ofcheck would read as an empty version directory.