about summary refs log tree commit diff
path: root/config/webpack
diff options
context:
space:
mode:
authorClaire <claire.github-309c@sitedethib.com>2022-12-21 22:13:14 +0100
committerGitHub <noreply@github.com>2022-12-21 22:13:14 +0100
commita5e446a4a0bf567e2c293cb68f84ca141f527a21 (patch)
treed295cf11d3341576a5c8f76ff9642ff167fe1a0c /config/webpack
parent18bcabf26a744703660ae403014209fa78dd6c56 (diff)
Change locales file generation to use JSON sources (#2028)
* Change locales file generation to use JSON sources

Instead of inheriting in JS files, set locale inheritance in the
theme's YML file, and inherit in the generated locale file, rather
than the source file.

* Convert glitch-soc JS translation files to JSON

Obtained running the following:

```sh
sed -i -z "s/import inherited from '.*';\s*\nconst messages = //" *.js
sed -i "s/\s*\/\/.*//" *.js
sed -i -z "s/;\s*export default .*/\n/" *.js
for i in *.js; do
  json5 $i | json_pp > ${i}on;
done
```

* Change `yarn manage:translations` to exclude any translation already defined upstream

* Run yarn manage:translations
Diffstat (limited to 'config/webpack')
-rw-r--r--config/webpack/generateLocalePacks.js28
-rw-r--r--config/webpack/translationRunner.js27
2 files changed, 43 insertions, 12 deletions
diff --git a/config/webpack/generateLocalePacks.js b/config/webpack/generateLocalePacks.js
index 09fba4a18..b1b818159 100644
--- a/config/webpack/generateLocalePacks.js
+++ b/config/webpack/generateLocalePacks.js
@@ -20,18 +20,25 @@ module.exports = Object.keys(flavours).reduce(function (map, entry) {
   if (!flavour.locales) {
     return map;
   }
-  const locales = readdirSync(flavour.locales).filter(
-    filename => /\.js(?:on)?$/.test(filename) && !/defaultMessages|whitelist|index/.test(filename)
-  );
+  const locales = readdirSync(flavour.locales).filter(filename => {
+    return /\.json$/.test(filename) &&
+      !/defaultMessages/.test(filename) &&
+      !/whitelist/.test(filename);
+  }).map(filename => filename.replace(/\.json$/, ''));
+
+  let inherited_locales_path = null;
+  if (flavour.inherit_locales && flavours[flavour.inherit_locales]?.locales) {
+    inherited_locales_path = flavours[flavour.inherit_locales]?.locales;
+  }
+
   const outPath = resolve('tmp', 'locales', entry);
 
   rimraf.sync(outPath);
   mkdirp.sync(outPath);
 
   locales.forEach(function (locale) {
-    const localeName = locale.replace(/\.js(?:on)?$/, '');
-    const localePath = join(outPath, `${localeName}.js`);
-    const baseLocale = localeName.split('-')[0]; // e.g. 'zh-TW' -> 'zh'
+    const localePath = join(outPath, `${locale}.js`);
+    const baseLocale = locale.split('-')[0]; // e.g. 'zh-TW' -> 'zh'
     const localeDataPath = [
       // first try react-intl
       `node_modules/react-intl/locale-data/${baseLocale}.js`,
@@ -45,21 +52,22 @@ module.exports = Object.keys(flavours).reduce(function (map, entry) {
       filename => filename.replace(/(?:node_modules|app\/javascript)\//, '')
     )[0];
     const localeContent = `//
-// locales/${entry}/${localeName}.js
+// locales/${entry}/${locale}.js
 // automatically generated by generateLocalePacks.js
 //
 
-import messages from '../../../${flavour.locales}/${locale.replace(/\.js$/, '')}';
+${inherited_locales_path ? `import inherited from '../../../${inherited_locales_path}/${locale}.json';` : ''}
+import messages from '../../../${flavour.locales}/${locale}.json';
 import localeData from '${localeDataPath}';
 import { setLocale } from 'locales';
 
 setLocale({
   localeData,
-  messages,
+  ${inherited_locales_path ? 'messages: Object.assign({}, inherited, messages)' : 'messages'},
 });
 `;
     writeFileSync(localePath, localeContent, 'utf8');
-    map[`locales/${entry}/${localeName}`] = localePath;
+    map[`locales/${entry}/${locale}`] = localePath;
   });
 
   return map;
diff --git a/config/webpack/translationRunner.js b/config/webpack/translationRunner.js
index 38050baf8..c7f84cc7e 100644
--- a/config/webpack/translationRunner.js
+++ b/config/webpack/translationRunner.js
@@ -1,11 +1,12 @@
 const fs = require('fs');
 const path = require('path');
-const { default: manageTranslations } = require('react-intl-translations-manager');
+const { default: manageTranslations, readMessageFiles } = require('react-intl-translations-manager');
 
 const RFC5646_REGEXP = /^[a-z]{2,3}(?:-(?:x|[A-Za-z]{2,4}))*$/;
 
 const rootDirectory = path.resolve(__dirname, '..', '..');
-const translationsDirectory = path.resolve(rootDirectory, 'app', 'javascript', 'mastodon', 'locales');
+const externalDefaultMessages = path.resolve(rootDirectory, 'app', 'javascript', 'mastodon', 'locales', 'defaultMessages.json');
+const translationsDirectory = path.resolve(rootDirectory, 'app', 'javascript', 'flavours', 'glitch', 'locales');
 const messagesDirectory = path.resolve(rootDirectory, 'build', 'messages');
 const availableLanguages = fs.readdirSync(translationsDirectory).reduce((languages, filename) => {
   const basename = path.basename(filename, '.json');
@@ -86,6 +87,25 @@ validateLanguages(languages, [
   !argv.force && testAvailability,
 ].filter(Boolean));
 
+// Override `provideExtractedMessages` to ignore translation strings provided upstream already
+const provideExtractedMessages = () => {
+  const extractedMessages = readMessageFiles(messagesDirectory);
+  const originalExtractedMessages = JSON.parse(fs.readFileSync(externalDefaultMessages, 'utf8'));
+  const originalKeys = new Set();
+
+  originalExtractedMessages.forEach(file => {
+    file.descriptors.forEach(descriptor => {
+      originalKeys.add(descriptor.id)
+    });
+  });
+
+  extractedMessages.forEach(file => {
+    file.descriptors = file.descriptors.filter((descriptor) => !originalKeys.has(descriptor.id));
+  });
+
+  return extractedMessages.filter((file) => file.descriptors.length > 0);
+};
+
 // manage translations
 manageTranslations({
   messagesDirectory,
@@ -96,4 +116,7 @@ manageTranslations({
   jsonOptions: {
     trailingNewline: true,
   },
+  overrideCoreMethods: {
+    provideExtractedMessages,
+  },
 });