docs(V2): subos.env, and why a new module needs a type() probe - #496
Merged
Conversation
Two bugs the same reinstall command hit at once:
1. In-place `patchelf --set-rpath <exe>` fails with
patchelf: open: Text file busy
whenever the user reinstalls godot with an editor still running
-- Linux refuses to truncate a mapped, executing binary. Switch
to `patchelf --output <tmp> && mv <tmp> <exe>`: rename(2) unlinks
the old inode and the running process keeps its own reference,
so live editors keep working while new invocations pick up the
patched file at the same path.
2. Every reinstall re-appended the probed host GUI dirs onto an
rpath that already contained them, growing it unboundedly:
.../lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu
:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu ← 2nd install
:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu ← 3rd install
...
The shell helper now dedupes per-directory (case match on
`:$new:`), and short-circuits when the target rpath and DT_RPATH
tag are already in place -- so a reinstall that has nothing to
change makes no patchelf call at all, sidestepping ETXTBSY too.
Verified locally:
* fresh install: RPATH set once, no duplicates
* reinstall (already correct): no patchelf invocation, RPATH
unchanged, install reports success
* reinstall while `godot` is running: no ETXTBSY, no error
`if xvm.files then` is correct only because `xvm` is a module older clients
already ship, so the missing FIELD really is nil. A missing MODULE never is:
import() answers an unknown module with a permissive proxy whose every key is
a truthy, callable table. A recipe probing `if subos.env then` takes the new
branch on every client, the call evaporates on the ones that predate it, and
the install reports success having configured nothing.
Documents both the rule (`type(subos.env) == "function"`) and the
`subos.env{}` API it gates: fields, the placeholder requirement, why an
unresolvable placeholder is left verbatim rather than blanked, that uninstall
cleanup must NOT be written by the recipe, and how conflicts resolve.
Pinned by xlings E2E-61, which runs one recipe through a real released binary
and the current build and asserts both readings.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
libxpkg 0.0.48 adds
subos.env{}— a package declaring an environment variable its subos must export. This documents the API and, more importantly, corrects the probe rule for it.The correction
The spec's existing guidance is
if xvm.files then. That is correct only becausexvmis a module older clients already ship, so the missing field really isnil.A missing module never is.
import()answers an unknown module with a permissive proxy whose every key returns a truthy, callable table:The old client takes the new branch, calls the function, and the call evaporates. Install succeeds, nothing is configured, nothing complains.
For a capability introduced as a new module the probe must test the type — the stub is a
tablewith__call, the real entry point is afunction:xlings E2E-61 runs one recipe through a real released binary and the current build and asserts both readings (truthiness
trueon both,type()falsethentrue). Ifimport()ever stops stubbing unknown modules, that test is what says the rule can be relaxed.Also documented
subos.env{var, op, value, binding}: fields, thatappend/set-if-unsetare refused rather than silently downgraded, the placeholder requirement (${pkgdir}etc.) and why an unresolvable one is left verbatim instead of blanked, that recipes must not write uninstall cleanup (declarations are provider-scoped), and that conflicts resolve by binding order with every conflict reported.Upstream: openxlings/libxpkg#32 · mcpplibs/mcpp-index#153