Files
builders_rubenslte/lib/common.sh
T
2026-09-13 20:08:34 +02:00

103 lines
4.1 KiB
Bash

#!/usr/bin/env bash
# Shared helpers for the builders_rubenslte build scripts.
# Source after setting `SCRIPT` to the repo root and `set -euo pipefail`.
# Every function is idempotent so iteration (`--no-sync`, re-runs) is safe.
# Print the script's usage() from its header comments (lines 2-9).
usage_from_header() {
sed -n '2,9p' "$0" | sed 's/^# \{0,1\}//'
}
# Re-execute the current script inside the nix-shell FHS build environment.
# `env_file` - nix expression (absolute path, e.g. "$SCRIPT/shell.nix")
# `in_env_var` - name of the env var that marks "already inside" (prevents recursion)
# `pre_exec` - optional shell snippet (e.g. export RB_CMD=...) echoed before re-entry
#
# `nix-shell --run` cannot be used here: shell.nix's shellHook `exec`s into the
# FHS env and swallows any `--run` argument, so we feed the command via stdin.
reenter_build_env() {
local env_file="$1" in_env_var="$2" pre_exec="${3:-}"
if [ -z "${!in_env_var:-}" ]; then
echo "[*] Re-entering build inside the nix-shell FHS env: $(basename "$env_file") ..."
local script_path
case "$0" in
/*) script_path="$0" ;;
*) script_path="$SCRIPT/$(basename "$0")" ;;
esac
{
printf 'export %s=1\n' "$in_env_var"
[ -n "$pre_exec" ] && printf '%s\n' "$pre_exec"
printf 'bash "%s"\n' "$script_path"
} | nix-shell "$env_file"
exit $?
fi
echo "[*] Already inside the nix-shell FHS env."
}
# Apply every *.patch under `dir_pattern` (repo-root-relative, e.g.
# "patches/twrp") from the current working directory (the tree root), using
# `patch -p1`. Checked reverse-first so re-running is a true no-op: GNU patch
# can otherwise *re-apply* an already-applied hunk (duplicating it) and still
# exit 0. Never run the real forward apply when the change is already present.
apply_patches() {
local dir_pattern="$1" p log
for p in "$SCRIPT"/"$dir_pattern"/*.patch; do
[ -e "$p" ] || continue
if patch -p1 -s -R --dry-run < "$p" >/dev/null 2>&1; then
echo "[*] Already applied: $dir_pattern/$(basename "$p")"
elif patch -p1 -s --dry-run < "$p" >/dev/null 2>&1; then
patch -p1 -s < "$p"
echo "[*] Applied $dir_pattern patch: $(basename "$p")"
else
log="$(mktemp)"
patch -p1 -s < "$p" >"$log" 2>&1 || true
echo "[!] WARNING: patch failed: $dir_pattern/$(basename "$p")"
cat "$log"
rm -f "$log"
fi
done
}
# Samsung bootloaders require the SEANDROIDENFORCE trailer on boot/recovery
# images. Appends it if missing. Never uses command substitution on the image
# (avoids bash "ignored null byte" warnings) - a pipeline test is enough.
append_seandroidenforce() {
local img="$1"
[ -f "$img" ] || return 0
if tail -c 16 "$img" | grep -q 'SEANDROIDENFORCE'; then
echo "[*] $img already has the SEANDROIDENFORCE trailer"
else
echo "[*] Appending SEANDROIDENFORCE trailer to $img"
printf 'SEANDROIDENFORCE' >> "$img"
fi
}
# Check an image exists, report size vs the partition budget (if given) and
# fail loudly on overflow (TWRP omni overflows the recovery partition easily).
verify_image() {
local img="$1" budget="${2:-}"
[ -f "$img" ] || { echo "ERROR: $img was not produced" >&2; exit 1; }
local size
size="$(stat -c%s "$img")"
if [ -n "$budget" ]; then
echo "[*] $img: $size bytes (partition budget: $budget)"
if [ "$size" -gt "$budget" ]; then
echo "ERROR: $img exceeds the partition budget" >&2
exit 1
fi
else
echo "[*] $img: $size bytes"
fi
sha256sum "$img"
echo "Done: $img"
}
# Populate JACK_REPOSITORY if empty. In-process Jack (JACK_NO_SERVER=1) only
# runs when the repository holds the jack/jill jars; a repo sync replaces the
# prebuilts so we (re)seed it with -n (never overwrite a valid copy).
seed_jack_repository() {
local repo="$1" src="$2"
mkdir -p "$repo"
cp -n "$src"/jack-*.jar "$repo/" 2>/dev/null || true
cp -n "$src"/jill-*.jar "$repo/" 2>/dev/null || true
}