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 <zeke@github.com>
This commit is contained in:
@@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
// [end-readme]
|
// [end-readme]
|
||||||
|
|
||||||
const fs = require('fs')
|
const fs = require('fs/promises')
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
const matter = require('gray-matter')
|
const matter = require('gray-matter')
|
||||||
const walk = require('walk-sync')
|
const walk = require('walk-sync')
|
||||||
@@ -27,46 +27,56 @@ async function main () {
|
|||||||
})
|
})
|
||||||
.map(filename => `translations/${filename}`)
|
.map(filename => `translations/${filename}`)
|
||||||
|
|
||||||
const extractFrontmatter = async (path) => {
|
console.log(
|
||||||
const fileContents = await readFileAsync(path, 'utf8')
|
(await Promise.all(
|
||||||
return fm(fileContents)
|
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/<language code>
|
||||||
|
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 localisedFrontmatter = await extractFrontmatter(localisedAbsPath)
|
||||||
const localisedAbsPath = path.posix.join(__dirname, '../..', relPath)
|
if (!localisedFrontmatter) return `${relPath}: No localised frontmatter`
|
||||||
// find the corresponding english file by removing the first 2 path segments: /translations/<language code>
|
|
||||||
const engAbsPath = path.posix.join(__dirname, '../..', relPath.split(path.sep).slice(2).join(path.sep))
|
|
||||||
|
|
||||||
if (!fs.existsSync(engAbsPath)) {
|
// Look for differences between the english and localised non-translatable properties
|
||||||
// This happens when an English file has been moved or deleted and translations are not in sync.
|
let overwroteSomething = false
|
||||||
// It does mean this script will not homogenous those translated files, but the docs site does not
|
for (const prop in localisedFrontmatter.data) {
|
||||||
// load translated files that don't correlate to an English file, so those translated files can't break things.
|
if (!fm.schema.properties[prop].translatable && englishFrontmatter.data[prop] && localisedFrontmatter.data[prop] !== englishFrontmatter.data[prop]) {
|
||||||
console.log(`English file does not exist: ${engAbsPath}`)
|
localisedFrontmatter.data[prop] = englishFrontmatter.data[prop]
|
||||||
continue
|
overwroteSomething = true
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const localisedFrontmatter = await extractFrontmatter(localisedAbsPath)
|
// rewrite the localised file, if it changed
|
||||||
if (!localisedFrontmatter) continue
|
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
|
// return `${relPath}: updated`
|
||||||
const englishFrontmatter = await extractFrontmatter(engAbsPath)
|
// silence
|
||||||
|
|
||||||
// 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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user