From 9ba7e6bc3433a836064d5d5a44eb6d9c1b51a851 Mon Sep 17 00:00:00 2001 From: Kevin Heis Date: Mon, 24 May 2021 09:27:50 -0700 Subject: [PATCH] Update homogenize-frontmatter script to not stop on errors and concurrency yes (#19480) * Update homogenize-frontmatter script to not stop on errors and concurrency yes * Update homogenize-frontmatter.js * Speed up by avoiding exists check Node docs: Using fs.exists() to check for the existence of a file before calling fs.open(), fs.readFile() or fs.writeFile() is not recommended. Doing so introduces a race condition, since other processes may change the file's state between the two calls. Instead, user code should open/read/write the file directly and handle the error raised if the file does not exist. * Update homogenize-frontmatter.js Co-authored-by: Zeke Sikelianos --- script/i18n/homogenize-frontmatter.js | 82 +++++++++++++++------------ 1 file changed, 46 insertions(+), 36 deletions(-) diff --git a/script/i18n/homogenize-frontmatter.js b/script/i18n/homogenize-frontmatter.js index 134d0ae6bd..e900da0bee 100755 --- a/script/i18n/homogenize-frontmatter.js +++ b/script/i18n/homogenize-frontmatter.js @@ -7,7 +7,7 @@ // // [end-readme] -const fs = require('fs') +const fs = require('fs/promises') const path = require('path') const matter = require('gray-matter') const walk = require('walk-sync') @@ -27,46 +27,56 @@ async function main () { }) .map(filename => `translations/${filename}`) - const extractFrontmatter = async (path) => { - const fileContents = await readFileAsync(path, 'utf8') - return fm(fileContents) + console.log( + (await Promise.all( + translatedMarkdownFiles + .map(async relPath => updateTranslatedMarkdownFile(relPath) + .catch(e => `Error in ${relPath}: ${e.message}`) + ) + )).filter(Boolean).join('\n') + ) +} + +async function extractFrontmatter (path) { + const fileContents = await readFileAsync(path, 'utf8') + return fm(fileContents) +} + +async function updateTranslatedMarkdownFile (relPath) { + const localisedAbsPath = path.posix.join(__dirname, '../..', relPath) + // find the corresponding english file by removing the first 2 path segments: /translations/ + const engAbsPath = path.posix.join(__dirname, '../..', relPath.split(path.sep).slice(2).join(path.sep)) + + // Load frontmatter from the source english file + let englishFrontmatter + try { + englishFrontmatter = await extractFrontmatter(engAbsPath) + } catch { + // This happens when an English file has been moved or deleted and translations are not in sync. + // It does mean this script will not homogenous those translated files, but the docs site does not + // load translated files that don't correlate to an English file, so those translated files can't break things. + // return `${relPath}: English file does not exist: ${engAbsPath}` + return // silence } - for (const relPath of translatedMarkdownFiles) { - const localisedAbsPath = path.posix.join(__dirname, '../..', relPath) - // find the corresponding english file by removing the first 2 path segments: /translations/ - const engAbsPath = path.posix.join(__dirname, '../..', relPath.split(path.sep).slice(2).join(path.sep)) + const localisedFrontmatter = await extractFrontmatter(localisedAbsPath) + if (!localisedFrontmatter) return `${relPath}: No localised frontmatter` - if (!fs.existsSync(engAbsPath)) { - // This happens when an English file has been moved or deleted and translations are not in sync. - // It does mean this script will not homogenous those translated files, but the docs site does not - // load translated files that don't correlate to an English file, so those translated files can't break things. - console.log(`English file does not exist: ${engAbsPath}`) - continue + // Look for differences between the english and localised non-translatable properties + let overwroteSomething = false + for (const prop in localisedFrontmatter.data) { + if (!fm.schema.properties[prop].translatable && englishFrontmatter.data[prop] && localisedFrontmatter.data[prop] !== englishFrontmatter.data[prop]) { + localisedFrontmatter.data[prop] = englishFrontmatter.data[prop] + overwroteSomething = true } + } - const localisedFrontmatter = await extractFrontmatter(localisedAbsPath) - if (!localisedFrontmatter) continue + // rewrite the localised file, if it changed + if (overwroteSomething) { + const toWrite = matter.stringify(localisedFrontmatter.content, localisedFrontmatter.data, { lineWidth: 10000, forceQuotes: true }) + await fs.writeFile(localisedAbsPath, toWrite) - // Load frontmatter from the source english file - const englishFrontmatter = await extractFrontmatter(engAbsPath) - - // Look for differences between the english and localised non-translatable properties - let overwroteSomething = false - for (const prop in localisedFrontmatter.data) { - if (!fm.schema.properties[prop].translatable && englishFrontmatter.data[prop] && localisedFrontmatter.data[prop] !== englishFrontmatter.data[prop]) { - localisedFrontmatter.data[prop] = englishFrontmatter.data[prop] - overwroteSomething = true - } - } - - // rewrite the localised file, if it changed - if (overwroteSomething) { - const toWrite = matter.stringify(localisedFrontmatter.content, localisedFrontmatter.data, { lineWidth: 10000, forceQuotes: true }) - fs.writeFileSync(localisedAbsPath, toWrite) - - // if it's fixable, output its path to store in the log file - console.log(relPath) - } + // return `${relPath}: updated` + // silence } }