mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-08 17:06:15 -08:00
fix(i18n): keep the baseline intact on failed updates and strict audits
`--update-baseline` now writes nothing while any locale is unreadable or has missing or extra keys, so an incomplete translation cannot reshape the baseline. `--fail-on-identical` no longer reads the baseline it ignores, so a damaged file cannot block a strict audit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
97d7541e62
commit
72a1771cf9
3 files changed
+40
-6
No files matched your search
@@ -260,7 +260,8 @@ text changes, so copying reworded English into a locale fails as well.
|
||||
Baseline entries that are no longer English-identical (translated, removed, or
|
||||
reworded) are reported but do not fail. `pnpm run i18n:baseline:update`
|
||||
rewrites the baseline from the current locale files, dropping those entries
|
||||
and printing every added one. Run it only after translating, or for a value
|
||||
and printing every added one; it writes nothing while any locale is unreadable
|
||||
or has missing or extra keys. Run it only after translating, or for a value
|
||||
that is legitimately identical in that language; review the diff, and never
|
||||
run it in CI. A new locale starts with no baseline entries, so it has to
|
||||
record its legitimate identical values the same way.
|
||||
|
||||
@@ -269,7 +269,8 @@ export function run({
|
||||
enLeaves = collectLeaves(
|
||||
readJson(resolve(i18nDir, `${EN_LOCALE}.json`))
|
||||
);
|
||||
baseline = readBaseline(baselinePath);
|
||||
// A strict audit ignores the baseline, so a damaged file cannot block it.
|
||||
baseline = strict ? new Map() : readBaseline(baselinePath);
|
||||
} catch (error) {
|
||||
if (!enLeaves || !update) {
|
||||
log(`FAIL ${formatError(error)}`);
|
||||
@@ -283,7 +284,6 @@ export function run({
|
||||
const identicalByLocale = new Map();
|
||||
const rejected = [];
|
||||
let failed = false;
|
||||
let unreadable = false;
|
||||
let staleTotal = 0;
|
||||
|
||||
for (const locale of locales) {
|
||||
@@ -292,7 +292,7 @@ export function run({
|
||||
try {
|
||||
result = checkLocale({ i18nDir, locale, enLeaves, baseline, mode });
|
||||
} catch (error) {
|
||||
failed = unreadable = true;
|
||||
failed = true;
|
||||
log(`FAIL ${file}: ${formatError(error)}`);
|
||||
continue;
|
||||
}
|
||||
@@ -318,8 +318,11 @@ export function run({
|
||||
reportRejected(log, rejected, enLeaves, mode);
|
||||
|
||||
if (update) {
|
||||
if (unreadable) {
|
||||
log('FAIL baseline not written: a locale file could not be read.');
|
||||
// Only a complete, readable set of locales is a state worth recording.
|
||||
if (failed) {
|
||||
log(
|
||||
'FAIL baseline not written: fix the unreadable, missing or extra keys above first.'
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
writeBaseline(log, baselinePath, baseline, identicalByLocale);
|
||||
|
||||
@@ -214,6 +214,36 @@ test('--update-baseline keeps the old baseline when a locale is unreadable', ()
|
||||
assert.deepEqual(readBaselineFile(), { de: { PIN: 'PIN' } });
|
||||
});
|
||||
|
||||
test('--update-baseline keeps the old baseline while keys are missing or extra', () => {
|
||||
writeLocale('en', EN);
|
||||
writeLocale('de', { APP: { TITLE: 'IPTVnator', OLD: 'Alt' }, PIN: 'PIN' });
|
||||
writeBaseline({ de: { 'APP.SAVE': 'Save', PIN: 'PIN' } });
|
||||
|
||||
const { code, output } = check('--update-baseline');
|
||||
|
||||
assert.equal(code, 1);
|
||||
assert.match(output, /baseline not written/);
|
||||
assert.deepEqual(readBaselineFile(), {
|
||||
de: { 'APP.SAVE': 'Save', PIN: 'PIN' },
|
||||
});
|
||||
});
|
||||
|
||||
test('--fail-on-identical audits even when the baseline is damaged', () => {
|
||||
writeLocale('en', EN);
|
||||
writeLocale('de', {
|
||||
APP: { TITLE: 'IPTVnator', SAVE: 'Speichern' },
|
||||
PIN: 'PIN-Code',
|
||||
});
|
||||
writeFileSync(baselinePath, '{ broken');
|
||||
|
||||
const { code, output } = check('--fail-on-identical');
|
||||
|
||||
assert.equal(code, 1);
|
||||
assert.match(output, /^FAIL de\.json: missing=0 extra=0 identical_en=1$/m);
|
||||
assert.match(output, /de\.json APP\.TITLE: "IPTVnator"/);
|
||||
assert.equal(check().code, 1);
|
||||
});
|
||||
|
||||
test('rejects unknown and conflicting flags', () => {
|
||||
writeLocale('en', EN);
|
||||
|
||||
|
||||
Reference in new issue
Block a user