Bounded waits and validated arguments in run.sh and ui-drive.sh, a seeded settings directory and root-only staged rootfs permissions with their own tests, qmp.py and imgtools.py hardening, the fetch scripts checking what they download, and ASCII typography throughout. Each fix carries its test under qemu/tests or tests/. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N3G6m9Aw5RyVY4ZowtKzEj
106 lines
4.3 KiB
Bash
Executable File
106 lines
4.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Obtain (or verify) the third-party trees pinned in build/vendor.manifest.
|
|
#
|
|
# These trees are shared between worktrees and are far too large to live in git
|
|
# (the vendor SDK alone is 21 GB, and its host tools bake in absolute paths, so
|
|
# it must sit at ONE stable path anyway). What belongs in git is the answer to
|
|
# "which commit" -- that is the manifest, and this is the only thing that reads
|
|
# it.
|
|
#
|
|
# fetch-vendor.sh --check [DIR] report each tree's state; non-zero if any
|
|
# is missing or off its pin (default: check)
|
|
# fetch-vendor.sh --fetch [DIR] clone what is missing, then check
|
|
#
|
|
# DIR defaults to $WARDEN_VENDOR_DIR, else the conventional shared location
|
|
# alongside a flare-edge checkout. Nothing is ever moved or reset: a tree that
|
|
# has drifted is REPORTED, because a local change to a vendor tree is usually
|
|
# someone's debugging session, not something to silently throw away.
|
|
set -uo pipefail
|
|
|
|
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
MANIFEST="$HERE/vendor.manifest"
|
|
MODE="check"
|
|
DIR=""
|
|
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--check) MODE="check"; shift ;;
|
|
--fetch) MODE="fetch"; shift ;;
|
|
# Print the header comment (line 1 is the shebang, so start at 2) and
|
|
# stop at the first line of code rather than a hardcoded line count --
|
|
# a fixed range silently starts printing code again the next time the
|
|
# header comment grows or shrinks.
|
|
-h|--help) awk '/^set /{exit} NR>1{print}' "$0"; exit 0 ;;
|
|
*) DIR="$1"; shift ;;
|
|
esac
|
|
done
|
|
|
|
[ -r "$MANIFEST" ] || { echo "FATAL: no manifest at $MANIFEST" >&2; exit 1; }
|
|
command -v git >/dev/null || { echo "FATAL: git not on PATH" >&2; exit 1; }
|
|
|
|
# A stalled clone (dead peer, wedged proxy) must not hang this script forever
|
|
# with no way for a caller to tell "still working" from "wedged" -- the
|
|
# luckfox-pico tree alone is ~21 GB, so a plain wall-clock timeout would also
|
|
# abort a clone that is merely slow. Abort only on a stall instead: git's http
|
|
# transport already aborts a transfer whose average speed drops below
|
|
# LOW_SPEED_LIMIT bytes/sec for LOW_SPEED_TIME seconds straight, so a slow but
|
|
# progressing clone is never penalized. Both are overridable for a link that
|
|
# is legitimately slow.
|
|
: "${WARDEN_VENDOR_LOW_SPEED_LIMIT:=1000}"
|
|
: "${WARDEN_VENDOR_LOW_SPEED_TIME:=60}"
|
|
export GIT_HTTP_LOW_SPEED_LIMIT="$WARDEN_VENDOR_LOW_SPEED_LIMIT"
|
|
export GIT_HTTP_LOW_SPEED_TIME="$WARDEN_VENDOR_LOW_SPEED_TIME"
|
|
|
|
if [ -z "$DIR" ]; then
|
|
DIR="${WARDEN_VENDOR_DIR:-$HOME/projects/scada/flare-edge}"
|
|
fi
|
|
|
|
# Where each tree conventionally lives. lvgl sits under ui/ because that is the
|
|
# shared tree flare-edge worktrees symlink into (ui-src/lvgl).
|
|
tree_path() {
|
|
case "$1" in
|
|
lvgl) echo "$DIR/ui/lvgl" ;;
|
|
luckfox-pico) echo "$DIR/sdk" ;;
|
|
*) echo "$DIR/$1" ;;
|
|
esac
|
|
}
|
|
|
|
rc=0
|
|
while IFS=$'\t' read -r name url commit desc; do
|
|
case "$name" in ''|\#*) continue ;; esac
|
|
path="$(tree_path "$name")"
|
|
|
|
# -e, not -d: a git worktree or submodule has a .git FILE, and lvgl is
|
|
# checked out as one here.
|
|
if [ ! -e "$path/.git" ]; then
|
|
if [ "$MODE" = "fetch" ]; then
|
|
echo "== cloning $name -> $path"
|
|
mkdir -p "$(dirname "$path")"
|
|
git clone --quiet "$url" "$path" || { echo " FAILED to clone $name" >&2; rc=1; continue; }
|
|
git -C "$path" checkout --quiet "$commit" || { echo " FAILED to check out $commit" >&2; rc=1; continue; }
|
|
else
|
|
echo "MISSING $name ($path)"
|
|
rc=1
|
|
continue
|
|
fi
|
|
fi
|
|
|
|
have="$(git -C "$path" rev-parse HEAD 2>/dev/null)"
|
|
if [ "$have" = "$commit" ]; then
|
|
# Local changes are reported but are NOT a failure. The vendor SDK is
|
|
# expected to carry them: tools/build-firmware.sh applies our sdk-patches
|
|
# series into that tree as part of every build, so a clean luckfox-pico
|
|
# checkout is the unusual state, not the healthy one.
|
|
dirty=""
|
|
[ -n "$(git -C "$path" status --porcelain 2>/dev/null | head -1)" ] && dirty=" (locally modified)"
|
|
echo "OK $name ${commit:0:12}$dirty"
|
|
else
|
|
echo "DRIFTED $name want ${commit:0:12} have ${have:0:12} ($path)"
|
|
echo " not reset automatically: check whether that is deliberate, then"
|
|
echo " either 'git -C $path checkout $commit' or update the manifest."
|
|
rc=1
|
|
fi
|
|
done < "$MANIFEST"
|
|
|
|
exit "$rc"
|