Skip to content

Commit 26b6ef9

Browse files
committed
handy: add passthru.updateScript with custom per-platform refresh
`nix-update-script` alone cannot keep the per-platform `frontendDepsHashes` table in sync: it can refresh the entry for the current host via `--subpackage frontendDeps`, but it does not reset the other platforms' entries, so after a version bump the stale hashes from the previous release stay in place and eventually pass a hash check on any host that just rebuilds without running the script. The custom update script at `pkgs/by-name/ha/handy/update.sh` plugs that gap: 1. `nix-update handy` bumps `version`, `src.hash`, `cargoHash`. 2. On a version change, every `frontendDepsHashes` entry is reset to `lib.fakeHash` so the package throws on any host until a fresh hash is computed there. 3. `handy.passthru.frontendDeps` is rebuilt on the current host, the "got:" line is parsed, and the matching entry is written back with the real value. Running the script on each target host (or via remote builders) refreshes the table one entry at a time, without silently reusing stale data from the previous release. The update flow is pure shell + `sed` + `awk`, wrapped in a `nix-shell` shebang so the required tooling (`nix-update`, `nix`, ...) is fetched automatically when `maintainers/scripts/update.nix --argstr package handy` is invoked.
1 parent 89316cc commit 26b6ef9

2 files changed

Lines changed: 95 additions & 2 deletions

File tree

pkgs/by-name/ha/handy/package.nix

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -272,10 +272,17 @@ rustPlatform.buildRustPackage (
272272
"$out/Applications/Handy.app/Contents/MacOS/handy"
273273
'';
274274

275-
# Expose frontendDeps so it can be built directly (e.g. by the update
276-
# script) without dragging in the full handy compile.
277275
passthru = {
276+
# Expose frontendDeps so the update script (and maintainers by
277+
# hand) can build it directly without dragging in the full handy
278+
# compile.
278279
inherit frontendDeps;
280+
281+
# Custom update script: nix-update alone cannot refresh the
282+
# per-platform `frontendDepsHashes` table, and a naive refresh
283+
# leaves the other platforms' entries stale after a version
284+
# bump. See the script's header for the full flow.
285+
updateScript = ./update.sh;
279286
};
280287

281288
meta = {

pkgs/by-name/ha/handy/update.sh

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#!/usr/bin/env nix-shell
2+
#!nix-shell -i bash -p nix-update nix gnused gnugrep gawk coreutils git
3+
# shellcheck shell=bash
4+
5+
# update.sh — refresh Handy version, src hash, cargoHash, and the
6+
# `frontendDepsHashes` entry for the host this script runs on.
7+
#
8+
# Usage:
9+
# nix-shell maintainers/scripts/update.nix --argstr package handy
10+
# # or manually, from the nixpkgs root:
11+
# ./pkgs/by-name/ha/handy/update.sh # follow upstream latest
12+
# ./pkgs/by-name/ha/handy/update.sh 0.8.3 # pin an explicit version
13+
#
14+
# What it does:
15+
# 1. `nix-update handy` bumps `version`, `src.hash`, `cargoHash`.
16+
# 2. On a version bump, *all* `frontendDepsHashes` entries are reset
17+
# to `lib.fakeHash` so stale values from the previous release
18+
# cannot silently pass a hash check on a host where we do not
19+
# rebuild.
20+
# 3. `handy.passthru.frontendDeps` is rebuilt to capture the real
21+
# hash for the current host's system; that entry is rewritten
22+
# from `lib.fakeHash` back to the real value.
23+
# 4. The remaining entries stay `lib.fakeHash`. Re-run the script on
24+
# each target host (or over a remote builder) to fill them in;
25+
# attempts to build handy on those hosts until then will fail
26+
# loudly on the hash mismatch rather than silently using stale
27+
# data.
28+
29+
set -euo pipefail
30+
31+
repo_root=$(git rev-parse --show-toplevel)
32+
pkg_file="$repo_root/pkgs/by-name/ha/handy/package.nix"
33+
cd "$repo_root"
34+
35+
if [[ ! -f "$pkg_file" ]]; then
36+
echo "update.sh: $pkg_file not found" >&2
37+
exit 1
38+
fi
39+
40+
read_version() {
41+
sed -n 's|^\s*version = "\([^"]*\)";.*|\1|p' "$pkg_file" | head -n1
42+
}
43+
44+
nix_update_args=(handy)
45+
if [[ $# -gt 0 ]]; then
46+
nix_update_args+=(--version "$1")
47+
fi
48+
49+
old_version=$(read_version)
50+
nix-update "${nix_update_args[@]}"
51+
new_version=$(read_version)
52+
53+
if [[ "$old_version" != "$new_version" ]]; then
54+
echo "update.sh: version bump $old_version$new_version; resetting stale frontendDepsHashes"
55+
# Operate only on lines inside the `frontendDepsHashes = { ... };` block.
56+
sed -i -e '/frontendDepsHashes = {/,/^ };$/ s|"sha256-[^"]*"|lib.fakeHash|g' "$pkg_file"
57+
fi
58+
59+
system=$(nix --extra-experimental-features nix-command eval --impure --raw --expr 'builtins.currentSystem')
60+
61+
# Force the current host's entry to lib.fakeHash so the next build
62+
# reports the real value via the "got:" diagnostic even if it happens
63+
# to still match the previous one.
64+
sed -i "s|\"$system\" = \"sha256-[^\"]*\";|\"$system\" = lib.fakeHash;|" "$pkg_file"
65+
66+
if ! grep -q "\"$system\" = lib.fakeHash;" "$pkg_file"; then
67+
echo "update.sh: no frontendDepsHashes entry for $system to refresh" >&2
68+
exit 1
69+
fi
70+
71+
echo "update.sh: rebuilding handy.passthru.frontendDeps on $system to capture the new hash"
72+
build_out=$(nix-build -A handy.passthru.frontendDeps --no-out-link 2>&1 || true)
73+
new_hash=$(awk '/got:/ { print $2; exit }' <<<"$build_out")
74+
if [[ -z "${new_hash:-}" ]]; then
75+
echo "update.sh: failed to parse the new hash from nix-build output" >&2
76+
printf '%s\n' "$build_out" | tail -n40 >&2
77+
exit 1
78+
fi
79+
80+
sed -i "s|\"$system\" = lib.fakeHash;|\"$system\" = \"$new_hash\";|" "$pkg_file"
81+
82+
echo "update.sh: $system$new_hash"
83+
if [[ "$old_version" != "$new_version" ]]; then
84+
echo "update.sh: other frontendDepsHashes entries are still lib.fakeHash;"
85+
echo "update.sh: re-run on each target host to fill them in."
86+
fi

0 commit comments

Comments
 (0)