Revert Serbian RESETUJ + add per-locale allowlist for identical-to-English hotspots

Uncle 17:40 UTC correction: 'for Serbian actually the issue is that
word is same in English and serbian' - my prior commit b41c40f wrongly
translated Serbian 'RESET' to 'RESETUJ'. Reverted serbian.json back
to 'RESET' = 'RESET'.

To keep validate-packs green AND preserve Uncle's correction, added a
per-locale allowlist to the validator:
- TranslationValidationRules: new LocaleHotspotAllowlist dictionary
  keyed by filename-without-extension (lowercase-insensitive) -> set
  of hotspot keys that legitimately stay identical to English in that
  locale. Seeded with 'serbian' -> {'RESET'}.
- IsShortKeyEnglishFallback gains an optional localeName parameter.
  When provided and the (locale, key) pair is in the allowlist,
  returns false instead of flagging.
- LanguagePackValidator now passes Path.GetFileNameWithoutExtension
  so the rule can short-circuit for legitimate loan-words.

Build clean. validate-packs reports 0 issues: Serbian 'RESET' =
'RESET' no longer flagged; all other locales still checked against
the global hotspot set (so if french.json ever has 'RESET' = 'RESET'
it will still be caught, because french is not in the allowlist).

Design note: the allowlist is intentionally narrow (one entry) rather
than opening the door to broad 'translator said it is fine' entries.
Extending it should be a conscious per-locale decision, not a default.
Co-Authored-By: 1amKhush <khushvendras99@gmail.com>
This commit is contained in:
r1ckstardev 2026-04-24 17:41:29 +00:00
parent b41c40f481
commit 025e649694
3 changed files with 25 additions and 5 deletions

View File

@ -105,7 +105,7 @@ public class LanguagePackValidator
continue;
}
if (TranslationValidationRules.IsShortKeyEnglishFallback(key, value))
if (TranslationValidationRules.IsShortKeyEnglishFallback(key, value, Path.GetFileNameWithoutExtension(filePath)))
{
issues.Add(new ValidationIssue(Path.GetFileName(filePath), key, "Common UI label left untranslated (value equals English key)"));
if (fix)

View File

@ -131,6 +131,14 @@ internal static class TranslationValidationRules
"More information...",
};
// Per-locale exceptions for hotspot keys that legitimately remain identical to the
// English key in certain languages (e.g. borrowed words, protocol/brand names used as-is).
// Keyed by filename (lowercase, without the .json extension) -> set of allowed identical-to-key entries.
private static readonly Dictionary<string, HashSet<string>> LocaleHotspotAllowlist = new(StringComparer.OrdinalIgnoreCase)
{
["serbian"] = new(StringComparer.Ordinal) { "RESET" },
};
private static readonly HashSet<string> TechnicalAllowTokens = new(StringComparer.OrdinalIgnoreCase)
{
"api",
@ -179,14 +187,26 @@ internal static class TranslationValidationRules
/// <summary>
/// Detects short, common UI keys (Confirm, Continue, Yes, etc.) that were
/// left as English instead of being translated.
/// left as English instead of being translated. Accepts an optional locale
/// hint so per-locale allowlists can suppress legitimate identical-to-English
/// entries (e.g. 'RESET' in Serbian).
/// </summary>
public static bool IsShortKeyEnglishFallback(string key, string value)
public static bool IsShortKeyEnglishFallback(string key, string value, string? localeName = null)
{
if (!string.Equals(key, value, StringComparison.Ordinal))
return false;
return IsShortKeyFallbackHotspot(key);
if (!IsShortKeyFallbackHotspot(key))
return false;
if (localeName != null
&& LocaleHotspotAllowlist.TryGetValue(localeName, out var allowed)
&& allowed.Contains(key))
{
return false;
}
return true;
}
public static bool IsShortKeyFallbackHotspot(string key)

View File

@ -1464,7 +1464,7 @@
"Reserved Addresses": "Rezervisane adrese",
"Reserved At": "Rezervisano",
"Reset": "Reset",
"RESET": "RESETUJ",
"RESET": "RESET",
"Reset app": "Resetuj aplikaciju",
"Reset authenticator app": "Resetuj authenticator aplikaciju",
"Reset Boltcard": "Resetuj Boltcard",