Skip to content
rlsbl.tag_explanation
On this page

The one consultation over whether a tag is accounted for: by an archived version whose refs include it, by an archive's recorded shipped_as spelling, or by the transition record.

#rlsbl.tag_explanation

#rlsbl.tag_explanation

Is this tag explained? -- the one consultation, for every reader of a tag namespace.

A repository's tag namespace is writable by anything, and two rlsbl commands have to walk it and decide, per tag, whether this repository can account for it:

  • rlsbl release backfill lists every tag it cannot explain FIRST and refuses

to write anything while one remains;

  • rlsbl release reconcile fires its publication tripwire on a ref origin

holds that no record explains.

Both used to answer from their own reading. This module is the answer, and the consumers differ only in what they DO with it.

The three explanations ----------------------

archived-version The tag is one of the refs a version its release archives record OWNS. The caller supplies that mapping, and it comes from expected_refs -- the single authority for a version's ref set -- in both consumers: reconcile asks it per archived version, and the backfill asks it per scope. This module never derives a spelling of its own.

shipped-as An archive records shipped_as = "<tag>": the historical spelling that version ACTUALLY shipped under, from before a rename or a repository boundary moved. Without this, a renamed project's whole published tag history reads as unexplained.

non-version-tag The transition record carries a non-version-tag event naming it: a tag deliberately outside the version model, recorded by an operator so that everything walking the namespace can account for it instead of reporting it forever.

Anything else is unexplained, and what that costs is the consumer's own decision -- a hard refusal in the backfill, a tripwire in reconcile.

Reading archives tolerantly, on purpose ---------------------------------------

shipped_as is read with :mod:tomllib rather than through :func:rlsbl.release_file.read_release_file. The strict reader requires the strictspec format_version gate, and the archives the backfill exists to repair are exactly the ones written before that gate -- asking the strict reader would refuse to look at the file whose one field is being read. Only that field is taken; nothing here validates an archive or acts on one.

#TagExplanation

Why a tag is accounted for.

version names the version the tag belongs to for the two archive-backed sources, and is None for a non-version tag -- which belongs to no version by definition. reason carries the operator's own words from a non-version-tag event.

#describe

python
def describe(self) -> str

One line naming the explanation, for a plan or an error.

#TagExplanations

The explanations available in one repository, keyed by tag.

#explain

python
def explain(self, tag: str) -> TagExplanation | None

The explanation for tag, or None when nothing accounts for it.

#explains

python
def explains(self, tag: str) -> bool

#non_version_tags

python
def non_version_tags(self) -> tuple[str, ...]

Every tag the transition record puts outside the version model.

#shipped_as_index

python
def shipped_as_index(releases_dir: str) -> dict

tag -> version for every archive in releases_dir recording one.

An archive that does not parse, or that carries no shipped_as, contributes nothing: this is a lookup over a field, not a validation pass.

#non_version_tag_index

python
def non_version_tag_index(transition_record_paths) -> dict

tag -> reason for every recorded non-version-tag event.

:func:rlsbl.transition_record.read_events is the read-for-use site and raises on a malformed record, which is the intended behavior: a namespace judged against a record that cannot be read in full would be judged against part of one.

#build

python
def build(*, version_tags=None, releases_dirs=(), transition_record_paths=()) -> TagExplanations

Assemble the explanations available in one repository.

version_tags is the caller's own tag -> version mapping, every spelling the versions it knows about own. The two other sources are read here: every shipped_as across releases_dirs, and every non-version-tag event across transition_record_paths.

Precedence is the order of the sources above, which is the order of decreasing specificity about a RELEASE: a tag the current scheme names is that version's, a tag an archive claims historically is that version's, and only a tag no archive claims can be one an operator put outside the model.

Search