···11+#!/usr/bin/env bash
22+set -euo pipefail
33+44+# Tangled has no releases for the knot-rs era and isn't on GitHub, so
55+# nix-update can't follow it: bump src to the head of master, take the
66+# frontend assets (the flake's *-src inputs) from its flake.lock and probe the
77+# Go vendor and cargo hashes.
88+attr=tangled
99+url=https://tangled.org/tangled.org/core
1010+1111+# Run by update-pkgs from the flake root ($0 is a read-only store copy).
1212+dir=pkgs/tangled
1313+pkg=$dir/package.nix
1414+# Linux-only package: always evaluate/build the x86_64-linux variant.
1515+build_attr=".#packages.x86_64-linux.$attr"
1616+1717+new_rev=$(git ls-remote "$url" refs/heads/master | cut -f1)
1818+old_rev=$(sed -n 's|^ *rev = "\([^"]*\)";|\1|p' "$pkg")
1919+if [ "$old_rev" = "$new_rev" ]; then
2020+ echo "$attr: already up to date ($new_rev)"
2121+ exit 0
2222+fi
2323+2424+# The flake fetcher's narHash is fetchgit's hash, and its store path has the
2525+# flake.lock with the asset pins.
2626+prefetch=$(nix flake prefetch --json "git+$url?rev=$new_rev")
2727+src_hash=$(jq -r .hash <<<"$prefetch")
2828+src_path=$(jq -r .storePath <<<"$prefetch")
2929+new_date=$(date -u -d "@$(jq -r .locked.lastModified <<<"$prefetch")" +%F)
3030+new_version="0-unstable-$new_date"
3131+3232+jq '.nodes as $n
3333+ | [.nodes.root.inputs | to_entries[] | select(.key | endswith("-src"))
3434+ | { key, value: ($n[.value].locked
3535+ | { type, url } + (if .rev then { rev } else {} end) + { hash: .narHash }) }]
3636+ | sort_by(.key) | from_entries' "$src_path/flake.lock" >"$dir/assets.json"
3737+3838+# Bump rev + version and blank the derived hashes: with the old ones in place
3939+# nix reuses the cached FODs and the build "succeeds" on stale code.
4040+sed -i \
4141+ -e "s|^\( *\)rev = \".*\";|\1rev = \"$new_rev\";|" \
4242+ -e "s|^\( *\)version = \".*\";|\1version = \"$new_version\";|" \
4343+ -e "s|^\( *\)hash = \"sha256-.*\";|\1hash = \"$src_hash\";|" \
4444+ -e "s|^\( *\)vendorHash = \".*\";|\1vendorHash = \"\";|" \
4545+ -e "s|^\( *\)cargoHash = \".*\";|\1cargoHash = \"\";|" \
4646+ "$pkg"
4747+4848+# The probe build is *expected* to fail (hash mismatch); `|| true` keeps
4949+# pipefail/errexit from turning that into an empty `got`. awk must not
5050+# `exit` early or tee dies of SIGPIPE and takes the pipeline with it.
5151+probe_hash() {
5252+ { nix build --no-link "$build_attr$1" 2>&1 || true; } | tee /dev/stderr |
5353+ awk '/got:/ && !seen { print $2; seen = 1 }' || true
5454+}
5555+5656+# Probe each FOD on its own so a hash is never attributed to the wrong field.
5757+for spec in vendorHash:.appview.goModules cargoHash:.knot-rs.cargoDeps; do
5858+ field=${spec%%:*}
5959+ got=$(probe_hash "${spec#*:}")
6060+ if [ -z "$got" ]; then
6161+ echo "$attr: no hash reported for $field" >&2
6262+ exit 1
6363+ fi
6464+ sed -i "s|^\( *\)$field = \"[^\"]*\";|\1$field = \"$got\";|" "$pkg"
6565+ echo "$attr: $field → $got"
6666+done
6767+6868+echo "$attr: updated to $new_rev ($new_version)"
6969+nix build --no-link "$build_attr"