build(sirius-press): build from the vendored subtree instead of a download
The subtree is in place, so everything that used to fetch and patch core at
build time now just copies it.
tools/build.sh copies wordpress/ — no download, no checksum step,
because there is nothing to fetch and nothing to
trust that is not already in the repository
docker/Dockerfile COPY wordpress/ instead of curl + sha256 + patch;
the build args and the `patch` package are gone
docker-compose.yml no WP_VERSION / WP_URL / WP_SHA256 to keep in step
tools/update-wordpress.sh is rewritten around what the subtree makes
possible. It imports the pristine release onto sirius-press/wordpress-upstream
and then `git subtree merge`s that branch, which three-way merges upstream
against the fork's own commit. A patch either applies with fuzz and hopes or
fails and leaves you re-deriving the change by hand; a merge conflict is
resolved once, in the file, and the next release merges against the
resolution.
patches/ survives as documentation rather than mechanism, and is now
generated: tools/refresh-patches.sh diffs the subtree against the pristine
import and rewrites the directory, with --check for CI. It answers the
question anyone auditing a fork asks first — what exactly did you change
inside WordPress? — in a minute, which `git log wordpress/` cannot, because
that log is mostly upstream imports. Generated documentation stays true; a
hand-maintained record of a core diff drifts, and a stale one is worse than
none because people trust it.
One test change worth noting: the syntax sweep no longer walks all of
wordpress/. It lints the fork's own PHP plus every core file patches/ says
the fork touches, which keeps the suite at seven seconds instead of a minute
while still covering the only core file that can break.
2026-09-21 03:19:28 +02:00
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
# refresh-patches.sh — regenerate patches/ from what the fork actually changed.
|
|
|
|
|
#
|
|
|
|
|
# Since core is vendored, `patches/` is no longer how the build works — it is
|
|
|
|
|
# documentation. It answers the question anyone auditing this fork asks first:
|
|
|
|
|
# *what exactly did you change inside WordPress?* A directory of readable
|
|
|
|
|
# diffs answers that in a minute; `git log wordpress/` does not, because it is
|
|
|
|
|
# mostly upstream imports.
|
|
|
|
|
#
|
|
|
|
|
# Documentation that is generated stays true. Documentation that is maintained
|
|
|
|
|
# by hand drifts, and a stale record of a fork's core diff is worse than none,
|
|
|
|
|
# because people trust it.
|
|
|
|
|
#
|
|
|
|
|
# tools/refresh-patches.sh # rewrite patches/ from the tree
|
|
|
|
|
# tools/refresh-patches.sh --check # fail if it would change anything (CI)
|
|
|
|
|
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
|
|
|
|
|
here="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
|
|
|
repo="$(git -C "$here" rev-parse --show-toplevel)"
|
|
|
|
|
# Ask git where we are rather than subtracting paths: on Windows
|
|
|
|
|
# --show-toplevel answers "D:/..." while $PWD is "/d/...", and the
|
|
|
|
|
# subtraction silently leaves an absolute path behind.
|
|
|
|
|
prefix="$(cd "$here" && git rev-parse --show-prefix)wordpress"
|
|
|
|
|
UPSTREAM_BRANCH="sirius-press/wordpress-upstream"
|
|
|
|
|
CHECK=0
|
|
|
|
|
|
|
|
|
|
for arg in "$@"; do
|
|
|
|
|
case "$arg" in
|
|
|
|
|
--check) CHECK=1 ;;
|
|
|
|
|
*) echo "unknown option: $arg" >&2; exit 2 ;;
|
|
|
|
|
esac
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
say() { printf '\033[1m→\033[0m %s\n' "$*"; }
|
|
|
|
|
die() { printf '\033[31merror:\033[0m %s\n' "$*" >&2; exit 1; }
|
|
|
|
|
|
|
|
|
|
git -C "$repo" rev-parse --verify --quiet "$UPSTREAM_BRANCH" >/dev/null \
|
|
|
|
|
|| die "the branch $UPSTREAM_BRANCH is missing; there is nothing to diff against."
|
|
|
|
|
|
|
|
|
|
# shellcheck source=wordpress.lock
|
|
|
|
|
source "$here/tools/wordpress.lock"
|
|
|
|
|
|
|
|
|
|
staging="$here/dist/.patch-refresh"
|
|
|
|
|
rm -rf "$staging"
|
|
|
|
|
mkdir -p "$staging"
|
|
|
|
|
|
|
|
|
|
say "comparing ${prefix}/ against pristine WordPress ${WP_VERSION}"
|
|
|
|
|
|
|
|
|
|
# Every path that differs between the vendored tree and the pristine import.
|
|
|
|
|
#
|
|
|
|
|
# Compared tree to tree, not commit to commit: the upstream branch keeps
|
|
|
|
|
# WordPress at its root while the subtree keeps it under a prefix, so a
|
|
|
|
|
# plain `git diff BRANCH HEAD -- <prefix>` compares two different path
|
|
|
|
|
# spaces and reports the whole distribution as added.
|
|
|
|
|
UPSTREAM_TREE="${UPSTREAM_BRANCH}^{tree}"
|
|
|
|
|
VENDORED_TREE="HEAD:${prefix}"
|
|
|
|
|
|
|
|
|
|
mapfile -t changed < <(
|
|
|
|
|
git -C "$repo" diff --name-only "$UPSTREAM_TREE" "$VENDORED_TREE"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if [ ${#changed[@]} -eq 0 ]; then
|
|
|
|
|
say "the fork changes nothing in core — writing an empty series"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
index=0
|
|
|
|
|
for file in "${changed[@]}"; do
|
|
|
|
|
[ -n "$file" ] || continue
|
|
|
|
|
index=$((index + 1))
|
|
|
|
|
slug="$(echo "$file" | tr '/.' '--' | tr -cd 'A-Za-z0-9-')"
|
|
|
|
|
out="$staging/$(printf '%04d' "$index")-${slug}.patch"
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
echo "Subject: [PATCH] ${file}"
|
|
|
|
|
echo
|
|
|
|
|
echo "The fork's change to this file, regenerated by tools/refresh-patches.sh."
|
|
|
|
|
echo "It is a record, not the mechanism: core is vendored under wordpress/ and"
|
|
|
|
|
echo "this diff is what distinguishes it from pristine upstream."
|
|
|
|
|
echo
|
|
|
|
|
echo "Applies to: WordPress ${WP_VERSION}"
|
|
|
|
|
git -C "$repo" diff "$UPSTREAM_TREE" "$VENDORED_TREE" -- "$file" | tail -n +3
|
|
|
|
|
} > "$out"
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
if [ "$CHECK" -eq 1 ]; then
|
2026-09-21 03:31:16 +02:00
|
|
|
# --strip-trailing-cr because a Windows checkout may hold these with CRLF
|
|
|
|
|
# while what we just generated has LF. .gitattributes marks *.patch as
|
|
|
|
|
# binary to stop that happening, but a clone made before that landed — or
|
|
|
|
|
# with the file copied around by hand — would otherwise report drift that
|
|
|
|
|
# is not there, and a check that cries wolf gets switched off.
|
|
|
|
|
if diff -rq --strip-trailing-cr "$here/patches" "$staging" >/dev/null 2>&1; then
|
build(sirius-press): build from the vendored subtree instead of a download
The subtree is in place, so everything that used to fetch and patch core at
build time now just copies it.
tools/build.sh copies wordpress/ — no download, no checksum step,
because there is nothing to fetch and nothing to
trust that is not already in the repository
docker/Dockerfile COPY wordpress/ instead of curl + sha256 + patch;
the build args and the `patch` package are gone
docker-compose.yml no WP_VERSION / WP_URL / WP_SHA256 to keep in step
tools/update-wordpress.sh is rewritten around what the subtree makes
possible. It imports the pristine release onto sirius-press/wordpress-upstream
and then `git subtree merge`s that branch, which three-way merges upstream
against the fork's own commit. A patch either applies with fuzz and hopes or
fails and leaves you re-deriving the change by hand; a merge conflict is
resolved once, in the file, and the next release merges against the
resolution.
patches/ survives as documentation rather than mechanism, and is now
generated: tools/refresh-patches.sh diffs the subtree against the pristine
import and rewrites the directory, with --check for CI. It answers the
question anyone auditing a fork asks first — what exactly did you change
inside WordPress? — in a minute, which `git log wordpress/` cannot, because
that log is mostly upstream imports. Generated documentation stays true; a
hand-maintained record of a core diff drifts, and a stale one is worse than
none because people trust it.
One test change worth noting: the syntax sweep no longer walks all of
wordpress/. It lints the fork's own PHP plus every core file patches/ says
the fork touches, which keeps the suite at seven seconds instead of a minute
while still covering the only core file that can break.
2026-09-21 03:19:28 +02:00
|
|
|
say "patches/ matches the tree"
|
|
|
|
|
rm -rf "$staging"
|
|
|
|
|
exit 0
|
|
|
|
|
fi
|
2026-09-21 03:31:16 +02:00
|
|
|
diff -ru --strip-trailing-cr "$here/patches" "$staging" || true
|
build(sirius-press): build from the vendored subtree instead of a download
The subtree is in place, so everything that used to fetch and patch core at
build time now just copies it.
tools/build.sh copies wordpress/ — no download, no checksum step,
because there is nothing to fetch and nothing to
trust that is not already in the repository
docker/Dockerfile COPY wordpress/ instead of curl + sha256 + patch;
the build args and the `patch` package are gone
docker-compose.yml no WP_VERSION / WP_URL / WP_SHA256 to keep in step
tools/update-wordpress.sh is rewritten around what the subtree makes
possible. It imports the pristine release onto sirius-press/wordpress-upstream
and then `git subtree merge`s that branch, which three-way merges upstream
against the fork's own commit. A patch either applies with fuzz and hopes or
fails and leaves you re-deriving the change by hand; a merge conflict is
resolved once, in the file, and the next release merges against the
resolution.
patches/ survives as documentation rather than mechanism, and is now
generated: tools/refresh-patches.sh diffs the subtree against the pristine
import and rewrites the directory, with --check for CI. It answers the
question anyone auditing a fork asks first — what exactly did you change
inside WordPress? — in a minute, which `git log wordpress/` cannot, because
that log is mostly upstream imports. Generated documentation stays true; a
hand-maintained record of a core diff drifts, and a stale one is worse than
none because people trust it.
One test change worth noting: the syntax sweep no longer walks all of
wordpress/. It lints the fork's own PHP plus every core file patches/ says
the fork touches, which keeps the suite at seven seconds instead of a minute
while still covering the only core file that can break.
2026-09-21 03:19:28 +02:00
|
|
|
rm -rf "$staging"
|
|
|
|
|
die "patches/ is out of date. Run tools/refresh-patches.sh and commit the result."
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
rm -f "$here/patches"/*.patch
|
|
|
|
|
if [ "$index" -gt 0 ]; then
|
|
|
|
|
cp "$staging"/*.patch "$here/patches/"
|
|
|
|
|
fi
|
|
|
|
|
rm -rf "$staging"
|
|
|
|
|
|
|
|
|
|
say "wrote ${index} patch file(s) describing the fork's core diff"
|
|
|
|
|
for f in "$here/patches"/*.patch; do
|
|
|
|
|
[ -e "$f" ] || continue
|
|
|
|
|
printf ' %s (%s lines)\n' "$(basename "$f")" "$(grep -c '' "$f")"
|
|
|
|
|
done
|