#!/usr/bin/env bash # Applies this app's local patches on top of the shared Zephyr checkout, so # that checkout stays a clean, reusable resource for other projects while # still carrying the changes this app needs. Run once after a fresh # `west update`, or after pulling upstream changes into the shared tree. # # Patches are tracked in zephyr-patches/ as plain `git format-patch` # output; applied with `git am` so they land as real commits (reviewable, # revertable) rather than a silent working-tree diff. set -euo pipefail ZEPHYR_BASE="${ZEPHYR_BASE:-./zephyrproject/zephyr}" PATCH_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/zephyr-patches" if [ ! -d "$ZEPHYR_BASE/.git" ]; then echo "error: $ZEPHYR_BASE is not a git checkout" >&2 exit 1 fi cd "$ZEPHYR_BASE" if [ -n "$(git status --porcelain)" ]; then echo "error: $ZEPHYR_BASE has uncommitted changes - commit, stash, or" >&2 echo " reset it before applying patches, so it's clear which" >&2 echo " commits came from these patches vs. local hacking." >&2 exit 1 fi for patch in "$PATCH_DIR"/*.patch; do # git mailinfo is the same header parser `git am` itself uses, so it # correctly strips "[PATCH]"/"[PATCH 1/2]" prefixes and un-wraps a # subject line that spans multiple header lines - a plain sed/grep # on "Subject:" got this wrong for a >1-patch series and silently # skipped every patch without applying them (grep -qF against an # empty extracted subject matches any line). msgfile=$(mktemp) bodyfile=$(mktemp) subject=$(git mailinfo "$msgfile" "$bodyfile" < "$patch" | sed -n 's/^Subject: //p') rm -f "$msgfile" "$bodyfile" if [ -z "$subject" ]; then echo "error: could not extract a Subject from $(basename "$patch")" >&2 exit 1 fi history=$(git log --oneline) if grep -qF "$subject" <<< "$history"; then echo "skip (already applied): $subject" continue fi echo "applying: $(basename "$patch")" git am "$patch" done echo "done - $ZEPHYR_BASE now carries $(ls "$PATCH_DIR"/*.patch | wc -l | tr -d ' ') local patch(es)."