|
| 1 | +#!/usr/bin/env bash |
| 2 | +# |
| 3 | +# sqlite-diff — compare the upstream SQLite source artifacts between two trees. |
| 4 | +# |
| 5 | +# Unlike a plain `diff -urN A B`, this only looks at the files that *upstream* |
| 6 | +# SQLite ships in its src/ directory (the hand-written .c/.h/.y/.in/... sources). |
| 7 | +# That skips: |
| 8 | +# - generated/built files (sqlite3.c amalgamation, parse.c, opcodes.*, tsrc/, ...) |
| 9 | +# - autoconf output (Makefile, libtool, config.*) |
| 10 | +# - .git internals |
| 11 | +# - libSQL's own additions (vectordiskann.c, ext/crr, ...) that upstream lacks |
| 12 | +# |
| 13 | +# The result is a unified diff suitable for piping to `diffstat`, `less`, or |
| 14 | +# `git apply`. |
| 15 | +# |
| 16 | +# Usage: |
| 17 | +# scripts/sqlite-diff <upstream-dir> <other-dir> |
| 18 | +# scripts/sqlite-diff <upstream-dir> <other-dir> | diffstat |
| 19 | +# |
| 20 | +# The first argument is the reference tree: its src/ file list defines what |
| 21 | +# counts as a "source artifact". The second is the tree compared against it. |
| 22 | + |
| 23 | +set -euo pipefail |
| 24 | + |
| 25 | +usage() { |
| 26 | + echo "usage: $(basename "$0") <upstream-dir> <other-dir>" >&2 |
| 27 | + echo " compares upstream's src/ source files against <other-dir>/src/" >&2 |
| 28 | + exit 2 |
| 29 | +} |
| 30 | + |
| 31 | +[ $# -eq 2 ] || usage |
| 32 | + |
| 33 | +upstream=$1 |
| 34 | +other=$2 |
| 35 | + |
| 36 | +# Which subdirectory holds the source artifacts (override with SUBDIR=... if needed). |
| 37 | +subdir=${SUBDIR:-src} |
| 38 | + |
| 39 | +for d in "$upstream" "$other"; do |
| 40 | + [ -d "$d" ] || { echo "error: not a directory: $d" >&2; exit 1; } |
| 41 | +done |
| 42 | +[ -d "$upstream/$subdir" ] || { echo "error: no $subdir/ in upstream: $upstream" >&2; exit 1; } |
| 43 | + |
| 44 | +# Iterate over the files upstream ships in src/, diffing each against the other |
| 45 | +# tree. Using a NUL-delimited list keeps unusual filenames safe. -N treats a |
| 46 | +# file missing from <other> as an empty file, so deletions show up in full. |
| 47 | +status=0 |
| 48 | +while IFS= read -r -d '' rel; do |
| 49 | + # rel is relative to "$upstream", e.g. "src/btree.c" |
| 50 | + a="$upstream/$rel" |
| 51 | + b="$other/$rel" |
| 52 | + # --label makes the diff read like git's a/ b/ and keeps diffstat -p1 happy, |
| 53 | + # regardless of where the two trees live on disk. |
| 54 | + if ! diff -uN --label "a/$rel" --label "b/$rel" "$a" "$b"; then |
| 55 | + status=1 |
| 56 | + fi |
| 57 | +done < <(cd "$upstream" && find "$subdir" -type f -print0 | sort -z) |
| 58 | + |
| 59 | +# diff/while exit non-zero when differences were found; that's expected, not an |
| 60 | +# error, so report success unless an actual diff invocation failed otherwise. |
| 61 | +exit 0 |
0 commit comments