mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-11-13 12:23:38 +01:00
98 lines
5.4 KiB
Bash
Executable File
98 lines
5.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# e2e-needed: does a diff touch anything the Windows e2e binaries are built from?
|
|
# e2e-needed [--range | --since REV] [--to REV] [--closure] (run in a jj workspace root)
|
|
# The Windows e2e runs komorebi.exe, komorebic.exe and komorebi-testwin.exe (windows-komorebi-testwin-e2e in flake.nix). Their
|
|
# inputs are (a) the source directories of the workspace crates they depend on, from `cargo tree
|
|
# --target x86_64-pc-windows-msvc -e normal,build` (dev-dependencies are not in the binaries),
|
|
# (b) files pulled in with include_str!/include_bytes!/include! from those crates, (c) fixed
|
|
# inputs: Cargo.lock, the root Cargo.toml, rust-toolchain.toml, flake.nix, flake.lock, build
|
|
# scripts, and the e2e harness itself (e2e/). Anything else cannot change those binaries.
|
|
# Verdict NO means: every touched file is outside all of that, so a passing e2e of the previous
|
|
# binaries carries over unchanged. Verdict YES prints which files decided it. Files that are not
|
|
# understood count as YES. Uses `cargo tree --offline` (about 1-2 s, no build). Never writes.
|
|
# NOT covered by this verdict: the other gates (nextest, clippy, the bar screenshot, KDE VM, schema oracles).
|
|
# shellcheck disable=SC2001 # the sed one-liners indent multi-line output
|
|
set -uo pipefail
|
|
FROM=""; TO="@"; SHOWCL=0
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--range) FROM='trunk()' ;;
|
|
--since) shift; FROM="${1:?--since needs a revset}" ;;
|
|
--to) shift; TO="${1:?--to needs a revset}" ;;
|
|
--closure) SHOWCL=1 ;;
|
|
-h|--help) sed -n '2,16p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
|
|
*) echo "usage: e2e-needed [--range | --since REV] [--to REV] [--closure]" >&2; exit 2 ;;
|
|
esac
|
|
shift
|
|
done
|
|
ROOT="$(jj root 2>/dev/null)" || { echo "e2e-needed: not in a jj workspace" >&2; exit 2; }
|
|
cd "$ROOT" || exit 2
|
|
if [ -n "$FROM" ]; then FILES="$(jj diff --name-only --from "$FROM" --to "$TO")"; else FILES="$(jj diff --name-only -r "$TO")"; fi
|
|
[ -n "$FILES" ] || { echo "NO (nothing changed in @; use --since REV)"; exit 0; }
|
|
|
|
# (a) closure: workspace crate directories (relative to root)
|
|
CL=""
|
|
for p in komorebi komorebi-windows komorebic komorebi-testwin; do
|
|
CL+="$(CARGO_BUILD_JOBS=1 nice -n 19 cargo tree --offline --locked -p "$p" --target x86_64-pc-windows-msvc \
|
|
--prefix none -e normal,build 2>/dev/null | grep -o "(${ROOT}[^)]*)" | tr -d '()' | sed "s#^${ROOT}/\{0,1\}##")"$'\n'
|
|
done
|
|
CL="$(echo "$CL" | sed '/^$/d' | sort -u)"
|
|
[ -n "$CL" ] || { echo "YES (could not compute the dependency closure: cargo tree failed; treating as needed)"; exit 0; }
|
|
[ $SHOWCL = 1 ] && { echo "closure directories:"; echo "$CL" | sed 's/^/ /'; }
|
|
|
|
# (b) include!-ed files, resolved against the including file
|
|
INC=""
|
|
while IFS= read -r d; do
|
|
[ -d "$d" ] || continue
|
|
while IFS=: read -r f _ rest; do
|
|
rel="$(grep -o 'include[a-z_]*!("[^"]*")' <<<"$rest" | sed 's/.*("\(.*\)")/\1/')"
|
|
for r in $rel; do
|
|
case "$r" in /*) continue ;; esac
|
|
INC+="$(realpath -m --relative-to="$ROOT" "$(dirname "$f")/$r")"$'\n'
|
|
done
|
|
done < <(grep -rn 'include[a-z_]*!(' "$d" --include='*.rs' 2>/dev/null)
|
|
done <<<"$CL"
|
|
INC="$(echo "$INC" | sed '/^$/d' | sort -u)"
|
|
[ $SHOWCL = 1 ] && { echo "include-d files:"; echo "$INC" | sed 's/^/ /'; }
|
|
|
|
yes=();
|
|
while IFS= read -r f; do
|
|
[ -n "$f" ] || continue
|
|
reason=""
|
|
case "$f" in
|
|
Cargo.lock|Cargo.toml|rust-toolchain.toml|flake.nix|flake.lock|nix/windows/*|nix/workspace-src.nix|nix/lib.nix|nix/common.nix) reason="fixed input" ;;
|
|
e2e/*|crates/komorebi-e2e-agent/*) reason="e2e harness / guest" ;;
|
|
*/build.rs) reason="build script" ;;
|
|
crates/komorebi-linux/*|crates/komorebi-hotkeys/*|crates/komorebi-macos/*|nix/linux/*|nix/macos/*|scripts/linux/*|schemas/linux/*|schemas/macos/*) ;; # the other platforms, not in the Windows closure
|
|
*.md|docs/*|tools/*|.github/*) ;; # docs and dev tools (include!-ed docs are caught below)
|
|
esac
|
|
if [ -z "$reason" ]; then
|
|
while IFS= read -r d; do
|
|
case "$f" in "$d"/*) reason="in closure crate $d"; break ;; esac
|
|
done <<<"$CL"
|
|
fi
|
|
if [ -z "$reason" ]; then
|
|
while IFS= read -r i; do
|
|
[ -n "$i" ] || continue
|
|
case "$f" in "$i"|"$i"/*) reason="include-d by a closure crate"; break ;; esac
|
|
done <<<"$INC"
|
|
fi
|
|
if [ -z "$reason" ]; then
|
|
case "$f" in
|
|
crates/komorebi-linux/*|crates/komorebi-hotkeys/*|crates/komorebi-macos/*|nix/linux/*|nix/macos/*|scripts/linux/*|schemas/linux/*|schemas/macos/*|*.md|docs/*|tools/*|.github/*) ;;
|
|
komorebi-bar/*|komorebi-gui/*|komorebi-shortcuts/*|komorebic-no-console/*|crates/komorebi-bar-core/*|schemas/windows/*|schema*.json|komorebic.lib.ahk|wix/*|justfile|mkdocs.yml|deny.toml|rustfmt.toml|*.json)
|
|
# known Windows-tree paths outside the closure (crates not in the closure were checked above)
|
|
case "$f" in */*.json|*.json) [ "$f" = dependencies.json ] || [ "${f#schema}" != "$f" ] || reason="json file outside known oracle files: treated as needed" ;; esac ;;
|
|
*) reason="not understood: treated as needed" ;;
|
|
esac
|
|
fi
|
|
[ -n "$reason" ] && yes+=("$f ($reason)")
|
|
done <<<"$FILES"
|
|
if [ ${#yes[@]} -eq 0 ]; then
|
|
echo "NO: none of $(echo "$FILES" | wc -l) touched files is an input of komorebi.exe, komorebic.exe or komorebi-testwin.exe"
|
|
else
|
|
echo "YES: ${#yes[@]} touched file(s) are inputs of the e2e binaries or the harness:"
|
|
printf ' %s\n' "${yes[@]}" | head -15
|
|
[ ${#yes[@]} -gt 15 ] && echo " ... and $(( ${#yes[@]} - 15 )) more"
|
|
fi
|