#!/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"