Patch module lockfiles after the modules are cloned, not before

The later 1.4.6 -> 1.4.8 bump ran before the module repositories were cloned,
found no lockfiles and patched nothing, so every module then failed on later's
tinycthread vs glibc >= 2.43. The manual build only escaped because its module
checkouts already existed from an earlier run. Move the patch after the clone
loop and fail if there is nothing to patch.

Claude-Session: https://claude.ai/code/session_01GGe7kUhooMFuzY6GaDb2w9
This commit is contained in:
agw
2026-09-30 22:00:00 +02:00
parent 00463ae4b3
commit 0395eec43d
+41 -35
View File
@@ -233,41 +233,6 @@ Rscript -e "
stop('failed to install remotes')
"
# Some of the versions JASP pins in its module renv.lock files predate the
# toolchain on a current Arch and cannot compile. Bump only those, by name, with
# the reason recorded — never a blanket "use latest", which would silently
# change the analysis code users get.
#
# later 1.4.6 bundles a tinycthread whose `#define once_flag pthread_once_t`
# collides with the C11 once_flag that glibc >= 2.43 now declares under
# C23, so it fails with "conflicting types for pthread_once_t".
# Fixed upstream in later 1.4.7 (r-lib/later#257). The 2026-04-22 RSPM
# snapshot the lockfiles already reference carries 1.4.8.
log "patching module lockfile pins that cannot build on this toolchain"
python3 - <<'PY'
import json, pathlib
OVERRIDES = {"later": "1.4.8"}
root = pathlib.Path("ModuleBundleBuildDir/Modules")
patched = 0
for lock in root.glob("*/renv.lock"):
data = json.loads(lock.read_text())
packages = data.get("Packages", {})
changed = False
for name, want in OVERRIDES.items():
pkg = packages.get(name)
if pkg and pkg.get("Version") != want:
print(f" {lock.parent.name}: {name} {pkg['Version']} -> {want}")
pkg["Version"] = want
# The recorded hash no longer matches the bumped version.
pkg.pop("Hash", None)
changed = True
if changed:
lock.write_text(json.dumps(data, indent=2) + "\n")
patched += 1
print(f"patched {patched} lockfiles")
PY
# renv restores packages concurrently and its ordering is not always
# dependency-correct: a module can be lazy-loaded while a package it needs is
@@ -405,6 +370,47 @@ for module in "${ALL_MODULES[@]}"; do
fi
done
# This has to run after the modules are cloned: it once ran before, found no
# lockfiles, patched nothing, and every module then failed on later 1.4.6.
#
# Some of the versions JASP pins in its module renv.lock files predate the
# toolchain on a current Arch and cannot compile. Bump only those, by name, with
# the reason recorded — never a blanket "use latest", which would silently
# change the analysis code users get.
#
# later 1.4.6 bundles a tinycthread whose `#define once_flag pthread_once_t`
# collides with the C11 once_flag that glibc >= 2.43 now declares under
# C23, so it fails with "conflicting types for pthread_once_t".
# Fixed upstream in later 1.4.7 (r-lib/later#257). The 2026-04-22 RSPM
# snapshot the lockfiles already reference carries 1.4.8.
log "patching module lockfile pins that cannot build on this toolchain"
python3 - <<'PY'
import json, pathlib
OVERRIDES = {"later": "1.4.8"}
root = pathlib.Path("ModuleBundleBuildDir/Modules")
patched = 0
for lock in root.glob("*/renv.lock"):
data = json.loads(lock.read_text())
packages = data.get("Packages", {})
changed = False
for name, want in OVERRIDES.items():
pkg = packages.get(name)
if pkg and pkg.get("Version") != want:
print(f" {lock.parent.name}: {name} {pkg['Version']} -> {want}")
pkg["Version"] = want
# The recorded hash no longer matches the bumped version.
pkg.pop("Hash", None)
changed = True
if changed:
lock.write_text(json.dumps(data, indent=2) + "\n")
patched += 1
print(f"patched {patched} lockfiles")
if not any(root.glob("*/renv.lock")):
raise SystemExit("error: no module lockfiles to patch - modules not cloned yet?")
PY
for attempt in 1 2 3; do
# Hand over only modules without a bundle yet: the script rebuilds everything
# it is given, so a retry would otherwise redo every finished module.