mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-10-05 19:28:25 +00:00
Wires compose_escaping_check.py into the two layers that already police the identical orphan-strings desync, mirroring pre-push-orphan-strings.sh: - the fast `lint` job in build.yml, next to the orphan check - a PreToolUse hook, so a push or PR from an agent session is gated too CI is the layer that matters here. As amethyst/src/main/res/CLAUDE.md records for the orphan desync, these arrive through bot-authored PRs -- the Crowdin sync reintroduced 2,068 escaped apostrophes across 40 locales twice in two days, with no local session anywhere in the path. Verified end to end: a payload with no push exits 0 without spawning python; a push against a clean tree exits 0; a push with values-tr-rTR restored to its pre-repair state exits 1 and names the file with a per-escape breakdown. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V1CzYQvWyHfipSW7x3j4Yo
35 lines
1.4 KiB
Bash
Executable File
35 lines
1.4 KiB
Bash
Executable File
#!/bin/bash
|
|
# PreToolUse gate: the Compose resource catalog must not carry Android escaping.
|
|
#
|
|
# Fires on `git push` (Bash tool) and on the create_pull_request MCP tool.
|
|
# Delegates to compose_escaping_check.py, which scans
|
|
# `*/src/*/composeResources/values*/strings.xml` for \' \" \? \@ and `tools:`
|
|
# attributes. Compose resolves only \uXXXX, \n and \t, so anything else carried
|
|
# verbatim out of an Android res tree renders literally -- the login screen once
|
|
# read `Don\'t have a Nostr account?`.
|
|
#
|
|
# Why a dedicated hook: this is reintroduced by every Crowdin sync, because
|
|
# Crowdin holds the Android-escaped source. It came back twice in two days, 2,068
|
|
# escaped apostrophes across 40 locales each time. Nothing in the Gradle build
|
|
# fails on it -- the strings simply ship wrong -- so there is no slow gate this
|
|
# stands in for; it is the only gate.
|
|
#
|
|
# Run the scan by hand any time with: .claude/hooks/compose_escaping_check.py
|
|
set -uo pipefail
|
|
|
|
hook_dir="$(cd "$(dirname "$0")" && pwd)"
|
|
cd "${CLAUDE_PROJECT_DIR:-.}" || exit 0
|
|
|
|
payload="$(cat)"
|
|
|
|
# Same cheap pre-filter as the orphan-strings gate: only a payload mentioning a
|
|
# push or the PR tool can possibly match, and this runs on every Bash call.
|
|
case "$payload" in
|
|
*push*|*pull_request*) ;;
|
|
*) exit 0 ;;
|
|
esac
|
|
|
|
printf '%s' "$payload" | python3 "$hook_dir/lib/git_push_gate.py" || exit 0
|
|
|
|
exec python3 "$hook_dir/compose_escaping_check.py"
|