You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix: accept the two release files an unpacked release has
Castle.Peer.release_file/1 listed the version directory, filtered for
*.rel and required exactly one, refusing anything else as ambiguous. An
unpacked release always holds two, so the peer path refused every
release it will ever be asked to configure - found by Forecastle's e2e
suite the first time it drove this path.
Mix writes one release file into the version directory, <name>.rel, the
one belonging to the start script. release_handler adds a second on
unpack: it extracts the tarball's <name>-<vsn>.rel, reads that to decide
what the version is - check_rel on the way in, and RELEASES written from
the record it returns - and then copies it in beside Mix's, "keeping
this for backwards compatibility reasons with older systools:make_tar,
where there is no copy of the .rel file in the releases/<vsn> dir. See
OTP-9746." For a tarball systools built the two names are the same and
that copy overwrites Mix's, which is why OTP's comment reads as
harmless. They differ here, so both survive.
Two shapes are therefore expected and no others: one file, which is a
version as Mix assembled it, and that pair, which is an unpacked one.
release_handler's copy is the one read, because it is the file the
version was admitted on and the applications and emulator version
RELEASES records came from those very bytes - so if the two ever
disagreed, it is the release as the system understands it. They are
byte-identical in practice: Forecastle writes the tarball's copy from
Mix's with File.cp!, the tar carries it unchanged, and
release_handler's copy is a read and a write of the whole file, all
three checked rather than assumed. Nothing compares them, deliberately.
This is a choice of which file is authoritative rather than a tie-break
between equals, so it holds however the two differ, and a difference in
bytes that cannot change the answer is no reason to refuse an install
that works.
The pair is recognised by the version alone, which is the version
directory's own name - release_handler copies into releases/<Vsn> for
the Vsn it has just read out of the file, and Mix assembles into
releases/<version> - so the release name never has to be found from
anywhere. Anything else refuses as before and still names what it
found: two names that are not that pair are two release files rather
than two copies of one, and so is any third.
The comment saying a version directory holds exactly one is what
shipped this. It was true of an assembled release and false of every
unpacked one, which is the only kind this path meets, and
Castle.SyntheticRelease modelled the assembled shape faithfully enough
that seven rounds of review had nothing to notice. So the fixture now
builds the unpacked shape as well - and builds it by default, since the
peer path is reached from install and commit and so meets a version
that came out of a tarball. 29 of the 45 tests in peer_test.exs fail
against 3ec5979 for that reason alone, every one that materialises
anything, which is the gap that mattered here rather than the missing
clause.
Six tests are new. The unpacked shape resolves, and its two files are
asserted to hold the same bytes. The copy unpacking left is the one
read, shown by planting a bogus emulator version in Mix's copy: with
the two identical, nothing but a difference between them can show which
was read. A version Mix assembled still resolves from its one file. And
three directories that are genuinely ambiguous are still refused - two
unrelated names, a copy belonging to another version, and a third file
beside the pair - the second of which is what stops the pair being
recognised by suffix rather than by this version.
No RELEASE.md entry. The peer path is new in this unreleased version and
has never been reachable from a released one, so no consumer could have
seen the refusal; what the Added entry already promises is what now
works.
Verified on 1.19.5 and on 1.20.0 through mise, a recent change here
having compiled clean on 1.19 and failed 1.20's type checker: mix
compile --warnings-as-errors is clean and the suite passes 90 under
both.
Refs: #13
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C4oaMvbR1cbxrZBj8qwkqN
0 commit comments