Fifty-four keys across 25 files, and a script that can find the rest. The script reports rather than deletes, because a key with no caller is a question and not a verdict: this cycle has twice found one that only described a feature whose button was torn out, and deleting it would have made the restoration cost 25 files of re-translation. The answer lives in the git history of the deletion, not in a grep. So only the ones where that history says the feature went on purpose: the web interface, the settings card overview the sidebar replaced, the save-and-discard model this window does not have, the LiteDB migration dialog, and three one-time announcements for versions long past. Plus nine this cycle superseded itself, including the three notes telling the reader to press Save first. 251 keys still have no caller. That is not a to-do list -- it is the inventory the search pass turned up: timestamp layouts, collapse duplicate messages, the About tab's prose, the honorific glow, the novice network button. Every one of them describes something that used to work. They stay until each has been decided one way or the other, which is the whole premise of this cycle.
36 lines
1.2 KiB
Bash
Executable File
36 lines
1.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Lists resource keys with no caller in the C# sources.
|
|
#
|
|
# Written for the v1.12.0 cleanup and kept, because the count only stays
|
|
# honest if it can be re-measured: every block of that cycle both revived
|
|
# orphans and created new ones, so a list taken once is wrong by the next
|
|
# commit.
|
|
#
|
|
# Reports rather than deletes. A key without a caller is a question -- was the
|
|
# feature removed on purpose, or did it only lose its button? -- and the answer
|
|
# is in the git history, not in this script.
|
|
set -euo pipefail
|
|
cd "$(dirname "$0")/.."
|
|
|
|
for bundle in HellionStrings Language; do
|
|
echo "=== ${bundle} ==="
|
|
python3 - "$bundle" <<'PY'
|
|
import sys, re, pathlib, xml.etree.ElementTree as E
|
|
|
|
bundle = sys.argv[1]
|
|
root = pathlib.Path("HellionChat")
|
|
keys = [d.get("name") for d in E.parse(root / f"Resources/{bundle}.resx").getroot().findall("data")]
|
|
|
|
sources = "\n".join(
|
|
p.read_text(encoding="utf-8")
|
|
for p in root.rglob("*.cs")
|
|
if "obj/" not in p.as_posix() and "/bin/" not in p.as_posix() and "Designer.cs" not in p.name
|
|
)
|
|
|
|
orphans = [k for k in keys if f"{bundle}.{k}" not in sources and f"nameof({k})" not in sources]
|
|
print(f"{len(orphans)} of {len(keys)} keys have no caller")
|
|
for k in sorted(orphans):
|
|
print(f" {k}")
|
|
PY
|
|
done
|