#!/bin/bash # Check for hardcoded Russian/Cyrillic user-facing strings in source code. # Excludes locale files, docs, tests with explicit locale checks. set -e ROOT="$(cd "$(dirname "$0")/.." && pwd)" EXIT=0 # Explicitly allowed Go files that may contain Cyrillic (test data, SQL migrations, i18n catalog). # These are NOT user-facing strings — they are test fixtures, embedded SQL, or locale definitions. ALLOWED_GO_CYRILLIC=( "internal/core/worklog/worklog_test.go" "internal/core/worklog/worklog.go" "internal/core/smoke_test.go" "internal/core/nodes/types.go" "internal/core/nodes/repository_test.go" "internal/core/plugins/manager_test.go" "internal/core/actions/action_test.go" "internal/core/actions/action.go" "internal/core/files/file.go" "internal/core/storage/migrations_008.sql.go" "internal/gui/index.html.go" "internal/i18n/catalog.go" "cmd/verstak-gui/main.go" "internal/core/templates/safename.go" "internal/core/templates/safename_test.go" "cmd/verstak-gui/vault_layout_test.go" ) echo "=== Checking for hardcoded Cyrillic in source code ===" # Search for Cyrillic characters in Go files (excluding locale files) GO_CYRILLIC=$(find "$ROOT" -name '*.go' \ ! -path "*/i18n/locales/*" \ -exec grep -l '[А-Яа-я]' {} \; 2>/dev/null || true) # Filter out allowed files FILTERED="" for f in $GO_CYRILLIC; do rel="${f#$ROOT/}" skip=0 for allowed in "${ALLOWED_GO_CYRILLIC[@]}"; do if [ "$rel" = "$allowed" ]; then skip=1 break fi done if [ "$skip" -eq 0 ]; then FILTERED="$FILTERED $f" fi done if [ -n "$FILTERED" ]; then echo "" echo "FAIL: Cyrillic found in Go source files (outside allowed exceptions):" echo "$FILTERED" echo "" echo "These should use i18n.T() instead of hardcoded Russian strings." EXIT=1 fi # Search for Cyrillic in Svelte/JS files (excluding locale files) JS_CYRILLIC=$(find "$ROOT/frontend/src" -name '*.svelte' -o -name '*.js' | \ grep -v 'i18n/locales' | \ xargs grep -l '[А-Яа-я]' 2>/dev/null || true) if [ -n "$JS_CYRILLIC" ]; then echo "" echo "FAIL: Cyrillic found in frontend source files (outside locale files):" echo "$JS_CYRILLIC" echo "" echo "These should use t() from lib/i18n instead." EXIT=1 fi # Check for common bidi/control unicode characters echo "" echo "=== Checking for bidi/control Unicode characters ===" BIDI=$(find "$ROOT" -name '*.go' -o -name '*.svelte' -o -name '*.js' | \ xargs grep -Pl '[\x{202A}-\x{202E}\x{2066}-\x{2069}\x{200E}\x{200F}\x{061C}]' 2>/dev/null || true) if [ -n "$BIDI" ]; then echo "FAIL: Bidi/control Unicode characters found in:" echo "$BIDI" EXIT=1 else echo "OK: No bidi/control characters found" fi # Check that locale keys match between ru and en for frontend AND Go echo "" echo "=== Checking locale key consistency ===" # Frontend JS locales RU_KEYS=$(grep -oP "^\s+'[^']+'" "$ROOT/frontend/src/lib/i18n/locales/ru.js" | sed "s/^ *'//;s/'$//" | sort) EN_KEYS=$(grep -oP "^\s+'[^']+'" "$ROOT/frontend/src/lib/i18n/locales/en.js" | sed "s/^ *'//;s/'$//" | sort) MISSING_EN=$(comm -23 <(echo "$RU_KEYS") <(echo "$EN_KEYS")) MISSING_RU=$(comm -23 <(echo "$EN_KEYS") <(echo "$RU_KEYS")) if [ -n "$MISSING_EN" ]; then echo "FAIL: Keys in frontend ru.js but missing in en.js:" echo "$MISSING_EN" EXIT=1 fi if [ -n "$MISSING_RU" ]; then echo "FAIL: Keys in frontend en.js but missing in ru.js:" echo "$MISSING_RU" EXIT=1 fi if [ -z "$MISSING_EN" ] && [ -z "$MISSING_RU" ]; then echo "OK: All frontend locale keys match between ru.js and en.js" fi # Go locales GO_RU_KEYS=$(grep -oP '"[^"]+":\s*"' "$ROOT/internal/i18n/locales/ru.json" | sed 's/":.*//' | sed 's/"//g' | sort) GO_EN_KEYS=$(grep -oP '"[^"]+":\s*"' "$ROOT/internal/i18n/locales/en.json" | sed 's/":.*//' | sed 's/"//g' | sort) GO_MISSING_EN=$(comm -23 <(echo "$GO_RU_KEYS") <(echo "$GO_EN_KEYS")) GO_MISSING_RU=$(comm -23 <(echo "$GO_EN_KEYS") <(echo "$GO_RU_KEYS")) if [ -n "$GO_MISSING_EN" ]; then echo "FAIL: Keys in Go ru.json but missing in en.json:" echo "$GO_MISSING_EN" EXIT=1 fi if [ -n "$GO_MISSING_RU" ]; then echo "FAIL: Keys in Go en.json but missing in ru.json:" echo "$GO_MISSING_RU" EXIT=1 fi if [ -z "$GO_MISSING_EN" ] && [ -z "$GO_MISSING_RU" ]; then echo "OK: All Go locale keys match between ru.json and en.json" fi exit $EXIT