translationRunner.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. const fs = require('fs');
  2. const path = require('path');
  3. const { default: manageTranslations } = require('react-intl-translations-manager');
  4. const RFC5646_REGEXP = /^[a-z]{2,3}(?:-(?:x|[A-Za-z]{2,4}))*$/;
  5. const rootDirectory = path.resolve(__dirname, '..', '..');
  6. const translationsDirectory = path.resolve(rootDirectory, 'app', 'javascript', 'mastodon', 'locales');
  7. const messagesDirectory = path.resolve(rootDirectory, 'build', 'messages');
  8. const availableLanguages = fs.readdirSync(translationsDirectory).reduce((languages, filename) => {
  9. const basename = path.basename(filename, '.json');
  10. if (RFC5646_REGEXP.test(basename)) {
  11. languages.push(basename);
  12. }
  13. return languages;
  14. }, []);
  15. const testRFC5646 = language => {
  16. if (!RFC5646_REGEXP.test(language)) {
  17. throw new Error('Not RFC5646 name');
  18. }
  19. };
  20. const testAvailability = language => {
  21. if (!availableLanguages.includes(language)) {
  22. throw new Error('Not an available language');
  23. }
  24. };
  25. const validateLanguages = (languages, validators) => {
  26. const invalidLanguages = languages.reduce((acc, language) => {
  27. try {
  28. validators.forEach(validator => validator(language));
  29. } catch (error) {
  30. acc.push({ language, error });
  31. }
  32. return acc;
  33. }, []);
  34. if (invalidLanguages.length > 0) {
  35. console.error(`
  36. Error: Specified invalid LANGUAGES:
  37. ${invalidLanguages.map(({ language, error }) => `* ${language}: ${error.message}`).join('\n')}
  38. Use yarn "manage:translations -- --help" for usage information
  39. `);
  40. process.exit(1);
  41. }
  42. };
  43. const usage = `Usage: yarn manage:translations [OPTIONS] [LANGUAGES]
  44. Manage JavaScript translation files in Mastodon. Generates and update translations in translationsDirectory: ${translationsDirectory}
  45. LANGUAGES
  46. The RFC5646 language tag for the language you want to test or fix. If you want to input multiple languages, separate them with space.
  47. Available languages:
  48. ${availableLanguages.join(', ')}
  49. `;
  50. const { argv } = require('yargs')
  51. .usage(usage)
  52. .option('f', {
  53. alias: 'force',
  54. default: false,
  55. describe: 'force using the provided languages. create files if not exists.',
  56. type: 'boolean',
  57. });
  58. // check if message directory exists
  59. if (!fs.existsSync(messagesDirectory)) {
  60. console.error(`
  61. Error: messagesDirectory not exists
  62. (${messagesDirectory})
  63. Try to run "yarn build:development" first`);
  64. process.exit(1);
  65. }
  66. // determine the languages list
  67. const languages = (argv._.length > 0) ? argv._ : availableLanguages;
  68. // validate languages
  69. validateLanguages(languages, [
  70. testRFC5646,
  71. !argv.force && testAvailability,
  72. ].filter(Boolean));
  73. // manage translations
  74. manageTranslations({
  75. messagesDirectory,
  76. translationsDirectory,
  77. detectDuplicateIds: false,
  78. singleMessagesFile: true,
  79. languages,
  80. jsonOptions: {
  81. trailingNewline: true,
  82. },
  83. });