AtlatestRepositorycore-channel

core-channel / tree / seed / scriptsverify-sources.sh

1#!/bin/sh
2# Verify the INPUTS the seed is about to be built from.
3#
4# This script read `$seed/MANIFEST` until 2026-07-31, and MANIFEST pins the
5# seed TARBALL -- the OUTPUT. So `build-seed.sh` checked the artifact it was
6# about to overwrite and never checked a single source it was about to compile.
7# The name said "verify-sources"; the behaviour was "verify the previous
8# output". It passed every time, which is exactly why nobody noticed.
9#
10# It also could not survive a re-pin: the moment MANIFEST's hash moves ahead of
11# the tarball on disk, a rebuild refuses for a reason that has nothing to do
12# with its sources.
14# MANIFEST.sources is the input pin, and it is what this verifies.
15set -eu
16seed=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
17manifest="$seed/MANIFEST.sources"
18[ -f "$manifest" ] || { echo "verify-sources: no $manifest" >&2; exit 1; }
20checked=0
21while read -r hash url file; do
22 case "$hash" in ''|'#'*) continue ;; esac
23 [ -f "$seed/$file" ] || {
24 echo "verify-sources: missing source $file (run bootstrap or gate-crosspath.sh)" >&2
25 exit 1
26 }
27 actual=$(sha256sum "$seed/$file" | awk '{print $1}')
28 [ "$actual" = "$hash" ] || {
29 echo "verify-sources: sha256 mismatch: $file" >&2
30 echo " expected $hash" >&2
31 echo " actual $actual" >&2
32 exit 1
33 }
34 echo "verified $file"
35 checked=$((checked+1))
36done < "$manifest"
38# A loop that verified nothing exits 0 and prints nothing, which reads exactly
39# like a clean run. Refuse instead.
40[ "$checked" -gt 0 ] || {
41 echo "verify-sources: REFUSING: $manifest listed no sources to verify" >&2
42 exit 1
44echo "verify-sources: $checked source(s) verified against MANIFEST.sources"