From 3ae40b7b1fd9a9a93feaf5cab07608dc021cce73 Mon Sep 17 00:00:00 2001 From: Remmy Cat Stock <3317423+remmycat@users.noreply.github.com> Date: Sun, 6 Nov 2022 20:36:10 +0100 Subject: [PATCH] Improve translation progress report --- scripts/check-translation-jsons.ts | 210 ++++++++++++++++++++++------- 1 file changed, 159 insertions(+), 51 deletions(-) diff --git a/scripts/check-translation-jsons.ts b/scripts/check-translation-jsons.ts index 505812029..219aca009 100644 --- a/scripts/check-translation-jsons.ts +++ b/scripts/check-translation-jsons.ts @@ -3,10 +3,19 @@ import path from "path"; import prettier from "prettier"; const NO_WRITE_KEY = "--no-write"; +const dontWrite = process.argv.includes(NO_WRITE_KEY); const KNOWN_SUFFIXES = ["_zero", "_one", "_two", "_few", "_many", "_other"]; -const dontWrite = process.argv.includes(NO_WRITE_KEY); +const REPO_TRANSLATIONS_INFO_URL = + "https://github.com/Sendouc/sendou.ink#translations"; + +const MD = { + inlineCode: (s: string) => `\`${s}\``, + strong: (s: string) => `**${s}**`, + h2: (s: string) => `## ${s}`, + li: (s: string) => `- ${s}`, +}; const otherLanguageTranslationPath = (code?: string, fileName?: string) => path.join( @@ -26,7 +35,9 @@ const missingTranslations: Record< const totalTranslationCounts: Record = {}; -for (const file of fs.readdirSync(otherLanguageTranslationPath("en"))) { +const fileNames: string[] = fs.readdirSync(otherLanguageTranslationPath("en")); + +for (const file of fileNames) { const englishContent = JSON.parse( fs.readFileSync(otherLanguageTranslationPath("en", file), "utf8").trim() ) as Record; @@ -238,6 +249,142 @@ function getKeysWithoutSuffix( return keys; } +type StatusProps = { + totalCount: number; + missingCount: number; + percentage?: boolean; +}; +function MDCompletionStatus({ + totalCount, + missingCount, + percentage, +}: StatusProps) { + const circle = + missingCount === 0 ? "🟢" : missingCount === totalCount ? "🔴" : "🟡"; + + const nonMissingCount = totalCount - missingCount; + + if (!percentage) { + return `${circle} ${nonMissingCount}/${totalCount}`; + } + + const percent = + totalCount === 0 ? 100 : Math.floor((nonMissingCount / totalCount) * 100); + + return `${circle} ${percent}%`; +} + +function MDOverviewTable({ + totalTranslationCounts, +}: { + totalTranslationCounts: Record; +}) { + const totalKeysCount = Object.values(totalTranslationCounts).reduce( + (a, b) => a + b, + 0 + ); + const relevantFiles = fileNames.filter( + (name) => name !== "weapons.json" && name !== "gear.json" + ); + + const rows = []; + + rows.push( + `| Language | Total | ${relevantFiles.map(MD.inlineCode).join(" | ")} |` + ); + + rows.push(`| :-- | :-: | ${relevantFiles.map(() => ":-:").join(" | ")} |`); + + for (const [lang, missingKeysObj] of Object.entries(missingTranslations)) { + const cells = []; + + cells.push(MD.strong(lang)); + + const totalAmountOfMissingKeys = Object.values(missingKeysObj).reduce( + (a, b) => a + b.length, + 0 + ); + + cells.push( + MD.strong( + MDCompletionStatus({ + totalCount: totalKeysCount, + missingCount: totalAmountOfMissingKeys, + percentage: true, + }) + ) + ); + + for (const file of relevantFiles) { + const fileKey = file.replace(".json", ""); + const missingKeysInFile = missingKeysObj[fileKey]; + if (!missingKeysInFile) { + return ""; + } + + cells.push( + MDCompletionStatus({ + totalCount: totalTranslationCounts[fileKey]!, + missingCount: missingKeysInFile.length, + }) + ); + } + + rows.push(`| ${cells.join(" | ")} |`); + } + + return rows.join("\n"); +} + +function MDDetails({ summary, content }: { summary: string; content: string }) { + return `
${summary}\n\n${content}\n\n
`; +} + +function MDMissingKeysList({ + missingTranslations, +}: { + missingTranslations: Record>>; +}) { + const blocks = []; + + for (const [lang, missingKeysObj] of Object.entries(missingTranslations)) { + const totalAmountOfMissingKeys = Object.values(missingKeysObj).reduce( + (a, b) => a + b.length, + 0 + ); + + if (totalAmountOfMissingKeys === 0) { + continue; + } + + const parts = []; + + parts.push(MD.h2(lang)); + + const filteredEntries = Object.entries(missingKeysObj).filter( + ([_, missingKeys]) => missingKeys.length > 0 + ); + + for (const [fileKey, missingKeys] of filteredEntries) { + parts.push( + MDDetails({ + summary: `${fileKey}.json`, + content: + missingKeys.length === totalTranslationCounts[fileKey]! + ? `All keys missing - Create a fresh copy of ${MD.inlineCode( + `en/${fileKey}.json` + )} to get started.` + : missingKeys.map(MD.li).join("\n"), + }) + ); + } + + blocks.push(parts.join("\n\n")); + } + + return blocks.join("\n\n"); +} + function createTranslationProgessMarkdown({ missingTranslations, totalTranslationCounts, @@ -245,59 +392,20 @@ function createTranslationProgessMarkdown({ missingTranslations: Record>>; totalTranslationCounts: Record; }) { - const totalKeysCount = Object.values(totalTranslationCounts).reduce( - (a, b) => a + b, - 0 - ); + return ` +> 🤖 This issue is fully automated, it should always be up-to-date. - return `# Translation Progress -${Object.entries(missingTranslations) - .map(([lang, missingKeysObj]) => { - const totalAmountOfMissingKeys = Object.values(missingKeysObj).reduce( - (a, b) => a + b.length, - 0 - ); - const status = - totalAmountOfMissingKeys === 0 - ? "🟢 Done" - : totalAmountOfMissingKeys === totalKeysCount - ? "🔴 Not started" - : "🟡 In progress"; +# Translation Progress - const headers = () => { - if (status !== "🟡 In progress") return ""; +If you want to contribute by adding missing translations, make sure to read the [project description](${REPO_TRANSLATIONS_INFO_URL}) on how to do this 💚 - return Object.entries(missingKeysObj) - .map(([file, missingKeys]) => { - const statusDot = - missingKeys.length === 0 - ? "🟢" - : missingKeys.length === totalTranslationCounts[file]! - ? "🔴" - : "🟡"; +## Overview - return `### ${statusDot} ${file}.json -**${ - totalTranslationCounts[file]! - missingKeys.length - }/${totalTranslationCounts[file]!}** -${ - missingKeys.length === 0 || - missingKeys.length === totalTranslationCounts[file]! - ? "" - : `
-Missing +Key: 🟢 = Done, 🟡 = In progress, 🔴 = Not started -${missingKeys.map((key) => `- ${key}`).join("\n")} +${MDOverviewTable({ totalTranslationCounts })} -
` -}`; - }) - .join("\n\n"); - }; - - return `## /${lang} (${status}) - -${headers()}`; - }) - .join("\n\n---\n\n")}`; +## Missing Keys + +${MDMissingKeysList({ missingTranslations })}`; }