extract-translations.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. const path = require('path');
  2. const fs = require('fs-extra');
  3. const spawn = require('cross-spawn');
  4. const { exec } = require('child_process');
  5. const MESSAGES_DIR = path.join(__dirname, '../src/lib/static/i18n-messages');
  6. extractTranslations().then(
  7. () => {
  8. process.exit(0);
  9. },
  10. error => {
  11. console.log(error);
  12. process.exit(1);
  13. },
  14. );
  15. /**
  16. * Extracts translation tokens into the i18n-messages files found in the MESSAGES_DIR.
  17. */
  18. async function extractTranslations() {
  19. const locales = fs.readdirSync(MESSAGES_DIR).map(file => path.basename(file).replace('.json', ''));
  20. const report = {
  21. generatedOn: new Date().toISOString(),
  22. lastCommit: await getLastGitCommitHash(),
  23. translationStatus: {},
  24. };
  25. console.log(`locales`, locales);
  26. for (const locale of locales) {
  27. const outputPath = path.join(
  28. path.relative(path.join(__dirname, '..'), MESSAGES_DIR),
  29. `${locale}.json`,
  30. );
  31. console.log(`Extracting translation tokens for "${outputPath}"`);
  32. try {
  33. await runExtraction(locale);
  34. const { tokenCount, translatedCount, percentage } = getStatsForLocale(locale);
  35. console.log(`${locale}: ${translatedCount} of ${tokenCount} tokens translated (${percentage}%)`);
  36. console.log('');
  37. report.translationStatus[locale] = { tokenCount, translatedCount, percentage };
  38. } catch (e) {
  39. console.log(e);
  40. }
  41. }
  42. const reportFile = path.join(__dirname, '../i18n-coverage.json');
  43. fs.writeFileSync(reportFile, JSON.stringify(report, null, 2), 'utf-8');
  44. console.log(`Report saved to "${reportFile}"`);
  45. }
  46. function runExtraction(locale) {
  47. const command = 'npx';
  48. const args = getNgxTranslateExtractCommand(locale);
  49. return new Promise((resolve, reject) => {
  50. try {
  51. const child = spawn(command, args, { stdio: ['inherit', 'inherit', 'inherit'] });
  52. child.on('close', x => {
  53. resolve();
  54. });
  55. child.on('error', err => {
  56. reject(err);
  57. });
  58. } catch (e) {
  59. reject(e);
  60. }
  61. });
  62. }
  63. function getStatsForLocale(locale) {
  64. const content = fs.readJsonSync(path.join(MESSAGES_DIR, `${locale}.json`), 'utf-8');
  65. let tokenCount = 0;
  66. let translatedCount = 0;
  67. for (const section of Object.keys(content)) {
  68. const sectionTranslations = Object.values(content[section]);
  69. tokenCount += sectionTranslations.length;
  70. translatedCount += sectionTranslations.filter(val => val !== '').length;
  71. }
  72. const percentage = Math.round((translatedCount / tokenCount) * 100);
  73. return {
  74. tokenCount,
  75. translatedCount,
  76. percentage,
  77. };
  78. }
  79. function getNgxTranslateExtractCommand(locale) {
  80. return [
  81. `ngx-translate-extract`,
  82. '--input',
  83. './src',
  84. '--output',
  85. `./src/lib/static/i18n-messages/${locale}.json`,
  86. `--clean`,
  87. `--sort`,
  88. `--format`,
  89. `namespaced-json`,
  90. `--format-indentation`,
  91. ` `,
  92. `-m`,
  93. `_`,
  94. ];
  95. }
  96. function getLastGitCommitHash() {
  97. return new Promise((resolve, reject) => {
  98. exec('git rev-parse HEAD', (err, result) => {
  99. if (err) {
  100. reject(err);
  101. } else {
  102. resolve(result.replace('\n', ''));
  103. }
  104. });
  105. });
  106. }