From e581995ab5c1539f5c1ff492dd0119967b5270ac Mon Sep 17 00:00:00 2001 From: Nathaniel Paulus Date: Mon, 23 Dec 2024 23:03:24 -0500 Subject: [PATCH] Add checks to update script --- deno.lock | 13 +++++- update.mts | 128 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 140 insertions(+), 1 deletion(-) diff --git a/deno.lock b/deno.lock index 267383c..fcd6e74 100644 --- a/deno.lock +++ b/deno.lock @@ -2,17 +2,28 @@ "version": "4", "specifiers": { "jsr:@std/bytes@^1.0.2": "1.0.4", - "jsr:@std/io@*": "0.225.0" + "jsr:@std/fs@*": "1.0.5", + "jsr:@std/io@*": "0.225.0", + "jsr:@std/path@^1.0.7": "1.0.7" }, "jsr": { "@std/bytes@1.0.4": { "integrity": "11a0debe522707c95c7b7ef89b478c13fb1583a7cfb9a85674cd2cc2e3a28abc" }, + "@std/fs@1.0.5": { + "integrity": "41806ad6823d0b5f275f9849a2640d87e4ef67c51ee1b8fb02426f55e02fd44e", + "dependencies": [ + "jsr:@std/path" + ] + }, "@std/io@0.225.0": { "integrity": "c1db7c5e5a231629b32d64b9a53139445b2ca640d828c26bf23e1c55f8c079b3", "dependencies": [ "jsr:@std/bytes" ] + }, + "@std/path@1.0.7": { + "integrity": "76a689e07f0e15dcc6002ec39d0866797e7156629212b28f27179b8a5c3b33a1" } }, "workspace": { diff --git a/update.mts b/update.mts index 1b73a37..6a4f3b9 100755 --- a/update.mts +++ b/update.mts @@ -8,6 +8,7 @@ // This doesn't fully solve the problem though, because metadata in the translated files may be different from the English files. import { copy, readerFromStreamReader } from "jsr:@std/io"; +import { walk } from "jsr:@std/fs/walk"; const projectId = Deno.env.get("CROWDIN_PROJECT_ID"); const apiKey = Deno.env.get("CROWDIN_API_KEY"); @@ -211,6 +212,129 @@ async function fetchNotionDocs() { } } +async function runChecks() { + // Check for malformed links in the i18n files + + for await (const dirEntry of walk(`${projectRoot}/i18n`)) { + if (dirEntry.isFile && dirEntry.name.endsWith(".md")) { + const file = await Deno.readTextFile(dirEntry.path); + for (const [index, line] of file.split("\n").entries()) { + // Look for Markdown links that had a space added between the closing parenthesis and the opening bracket + if (/\]\s+\(/.test(line)) { + console.log( + `%cFound malformed link in ${dirEntry.path} at line ${index + 1}`, + "color: red" + ); + console.log(line); + console.log( + " ".repeat(line.indexOf("]") + 1) + "%c^ Erroneous space", + "color: blue" + ); + } + } + } + } + + // Check that all original docs have a corresponding translation, and vice versa + const originalDocs = new Map(); + const docsDir = `${projectRoot}/docs`; + for await (const dirEntry of walk(docsDir)) { + if (dirEntry.isFile && dirEntry.name.endsWith(".md")) { + if (dirEntry.path.indexOf(docsDir) !== 0) + throw new Error("Unexpected path"); + const relativePath = dirEntry.path.slice(docsDir.length + 1); + originalDocs.set(relativePath, await Deno.readTextFile(dirEntry.path)); + } + } + + for (const locale of helpLocales) { + const i18nDir = `${projectRoot}/i18n/${locale.docusaurus}/docusaurus-plugin-content-docs/current`; + + const foundLocalizations = new Set(); + + for await (const dirEntry of walk(i18nDir)) { + if (dirEntry.isFile && dirEntry.name.endsWith(".md")) { + if (dirEntry.path.indexOf(i18nDir) !== 0) + throw new Error("Unexpected path"); + + const relativePath = dirEntry.path.slice(i18nDir.length + 1); + + foundLocalizations.add(relativePath); + + if (!originalDocs.has(relativePath)) { + console.log( + `%cNo original document found for i18n file ${dirEntry.path}`, + "color: red" + ); + } + } + } + for (const [relativePath, content] of originalDocs) { + if (!foundLocalizations.has(relativePath)) { + console.log( + `%cNo translation file found for ${relativePath} in ${i18nDir}`, + "color: red" + ); + } else { + // Check that the front matter matches + const translation = await Deno.readTextFile( + `${i18nDir}/${relativePath}` + ); + const frontMatterRegex = /^---\n(.*?)\n---/s; + const originalFrontMatterMatch = content.match(frontMatterRegex); + const translationFrontMatterMatch = translation.match(frontMatterRegex); + if (originalFrontMatterMatch == null) { + console.log( + `%cNo front matter found in original document ${relativePath}`, + "color: red" + ); + } + if (translationFrontMatterMatch == null) { + console.log( + `%cNo front matter found in translation ${relativePath}`, + "color: red" + ); + } + + if ( + originalFrontMatterMatch == null || + translationFrontMatterMatch == null + ) + continue; + + const originalFrontMatter = originalFrontMatterMatch[1].split("\n"); + const translationFrontMatter = + translationFrontMatterMatch[1].split("\n"); + + if (originalFrontMatter.length !== translationFrontMatter.length) { + console.log( + `%cFront matter length mismatch in ${relativePath} for locale ${locale.docusaurus}`, + "color: red" + ); + } + + for (const [index, line] of originalFrontMatter.entries()) { + // the title can change; everything else should match + if (line.indexOf("title: ") === 0) continue; + if (line !== translationFrontMatter[index]) { + console.log( + `%cFront matter mismatch in ${relativePath} for locale ${ + locale.docusaurus + } at line ${index + 1}`, + "color: red" + ); + console.log(`%cOriginal: ${line}`, "color: blue"); + console.log( + `%cTranslation: ${translationFrontMatter[index]}`, + "color: blue" + ); + } + } + } + } + } +} + try { console.log("--- Deleting existing files ---"); await deleteExistingFiles(); @@ -228,6 +352,10 @@ try { await copyFiles(); console.log(); + console.log("--- Running checks ---"); + await runChecks(); + console.log(); + console.log("--- Completed successfully ---"); } catch (e) { console.error(e);