Files
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

151 lines
5.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# apply-opencode-patches.sh — apply .patches/*.patch to the opencode submodule.
#
# See .patches/README.md for the patch catalog. Per-patch motivation is
# summarized in the patch header and in each patch's docstring inside
# the changed file.
#
# Every patch must `git apply --check` cleanly against its predecessor's
# output. Any failure short-circuits with a non-zero exit and a message
# naming the offending patch.
#
# Usage:
# bash experimental/python/perfxpert/scripts/apply-opencode-patches.sh
#
# Environment:
# PERFXPERT_PATCH_DIR override the default .patches dir (for testing)
# PERFXPERT_PATCH_MANIFEST override the default SHA256SUMS manifest
# PERFXPERT_OPENCODE_DIR override the default submodule dir
# PERFXPERT_PATCH_CHECK_ONLY=1 run only `git apply --check`, do NOT apply
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PERFXPERT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
PATCH_DIR="${PERFXPERT_PATCH_DIR:-${PERFXPERT_ROOT}/.patches}"
PATCH_MANIFEST="${PERFXPERT_PATCH_MANIFEST:-${PATCH_DIR}/SHA256SUMS}"
OPENCODE_DIR="${PERFXPERT_OPENCODE_DIR:-${PERFXPERT_ROOT}/opencode}"
CHECK_ONLY="${PERFXPERT_PATCH_CHECK_ONLY:-0}"
if [[ ! -d "${PATCH_DIR}" ]]; then
echo "apply-opencode-patches: patch dir not found: ${PATCH_DIR}" >&2
exit 2
fi
if [[ ! -d "${OPENCODE_DIR}" ]]; then
echo "apply-opencode-patches: opencode submodule not found: ${OPENCODE_DIR}" >&2
echo " Run: git submodule update --init --recursive" >&2
exit 2
fi
# Collect patches in lexicographic order. Using a glob here rather than
# `ls | sort` because glob expansion is already lexicographic in bash.
shopt -s nullglob
patches=( "${PATCH_DIR}"/*.patch )
shopt -u nullglob
if [[ ${#patches[@]} -eq 0 ]]; then
echo "apply-opencode-patches: no patches found in ${PATCH_DIR} — nothing to do" >&2
exit 0
fi
if [[ ! -f "${PATCH_MANIFEST}" ]]; then
echo "apply-opencode-patches: patch manifest not found: ${PATCH_MANIFEST}" >&2
exit 2
fi
manifest_names=()
while read -r checksum relpath _rest; do
[[ -n "${checksum}" ]] || continue
name="$(basename "${relpath}")"
manifest_names+=( "${name}" )
done < "${PATCH_MANIFEST}"
if [[ ${#manifest_names[@]} -eq 0 ]]; then
echo "apply-opencode-patches: patch manifest is empty: ${PATCH_MANIFEST}" >&2
exit 2
fi
for patch in "${patches[@]}"; do
name="$(basename "${patch}")"
if ! printf '%s\n' "${manifest_names[@]}" | grep -Fxq "${name}"; then
echo "apply-opencode-patches: manifest missing entry for ${name}" >&2
exit 1
fi
done
for name in "${manifest_names[@]}"; do
if [[ ! -f "${PATCH_DIR}/${name}" ]]; then
echo "apply-opencode-patches: manifest references missing patch ${name}" >&2
exit 1
fi
done
if [[ ${#manifest_names[@]} -ne ${#patches[@]} ]]; then
echo "apply-opencode-patches: manifest/patch set mismatch in ${PATCH_DIR}" >&2
exit 1
fi
if ! (
cd "${PATCH_DIR}"
if command -v sha256sum >/dev/null 2>&1; then
sha256sum --check --status "${PATCH_MANIFEST}"
elif command -v shasum >/dev/null 2>&1; then
while read -r expected relpath _rest; do
[[ -n "${expected}" ]] || continue
actual="$(shasum -a 256 "${relpath}" | awk '{print $1}')"
[[ "${actual}" == "${expected}" ]] || exit 1
done < "${PATCH_MANIFEST}"
else
echo "apply-opencode-patches: need sha256sum or shasum for manifest verification" >&2
exit 2
fi
); then
echo "apply-opencode-patches: checksum verification failed for ${PATCH_MANIFEST}" >&2
exit 1
fi
echo "apply-opencode-patches: ${#patches[@]} patches to apply (check_only=${CHECK_ONLY})"
echo "apply-opencode-patches: manifest OK — ${PATCH_MANIFEST}"
cd "${OPENCODE_DIR}"
# Check mode requires a clean submodule since we apply & reset.
if ! git diff --quiet HEAD --; then
echo "apply-opencode-patches: refusing to run: submodule has uncommitted changes" >&2
echo " Run: (cd ${OPENCODE_DIR} && git checkout HEAD -- .)" >&2
exit 1
fi
applied=()
for patch in "${patches[@]}"; do
name="$(basename "${patch}")"
# In both modes we apply in sequence: a later patch may depend on an
# earlier one, so a pristine `git apply --check` is insufficient.
echo " checking ${name}"
if ! git apply --check "${patch}"; then
echo "apply-opencode-patches: FAILED --check for ${name}" >&2
echo " already-applied patches: ${applied[*]:-<none>}" >&2
# Roll back
git checkout HEAD -- . >/dev/null 2>&1 || true
exit 1
fi
echo " applying ${name}"
if ! git apply "${patch}"; then
echo "apply-opencode-patches: FAILED apply for ${name}" >&2
git checkout HEAD -- . >/dev/null 2>&1 || true
exit 1
fi
applied+=( "${name}" )
done
if [[ "${CHECK_ONLY}" == "1" || "${CHECK_ONLY}" == "true" ]]; then
# Check-only mode: revert everything we just applied so the submodule
# goes back to pristine state.
git checkout HEAD -- . >/dev/null 2>&1 || true
echo "apply-opencode-patches: CHECK OK — ${#patches[@]} patch(es) verified (reverted)"
else
echo "apply-opencode-patches: OK — ${#patches[@]} patch(es) applied"
fi