You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

103 lines
2.9 KiB

  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}(?:|[A-Z]+)$/;
  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. // eslint-disable-next-line no-console
  36. console.error(`
  37. Error: Specified invalid LANGUAGES:
  38. ${invalidLanguages.map(({ language, error }) => `* ${language}: ${error.message}`).join('\n')}
  39. Use yarn "manage:translations -- --help" for usage information
  40. `);
  41. process.exit(1);
  42. }
  43. };
  44. const { argv } = require('yargs')
  45. .usage(`Usage: yarn manage:translations -- [OPTIONS] [LANGUAGES]
  46. Manage JavaScript translation files in Mastodon. Generates and update translations in translationsDirectory: ${translationsDirectory}
  47. LANGUAGES
  48. The RFC5646 language tag for the language you want to test or fix. If you want to input multiple languages, separate them with space.
  49. Available languages:
  50. ${availableLanguages.join(', ')}
  51. `)
  52. .help('h', 'show this message')
  53. .alias('h', 'help')
  54. .options({
  55. f: {
  56. alias: 'force',
  57. default: false,
  58. describe: 'force using the provided languages. create files if not exists.',
  59. type: 'boolean',
  60. },
  61. });
  62. // check if message directory exists
  63. if (!fs.existsSync(messagesDirectory)) {
  64. // eslint-disable-next-line no-console
  65. console.error(`
  66. Error: messagesDirectory not exists
  67. (${messagesDirectory})
  68. Try to run "yarn build:development" first`);
  69. process.exit(1);
  70. }
  71. // determine the languages list
  72. const languages = (argv._.length > 0) ? argv._ : availableLanguages;
  73. // validate languages
  74. validateLanguages(languages, [
  75. testRFC5646,
  76. !argv.force && testAvailability,
  77. ].filter(Boolean));
  78. // manage translations
  79. manageTranslations({
  80. messagesDirectory,
  81. translationsDirectory,
  82. detectDuplicateIds: false,
  83. singleMessagesFile: true,
  84. languages,
  85. jsonOptions: {
  86. trailingNewline: true,
  87. },
  88. });