-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: use
atlas
in make pull_translations
Changes ------- - Add `generateSupportedLangs.js` script to generate `currentlySupportedLangs.jsx` - Add `atlas` into `make pull_translations` when `OPENEDX_ATLAS_PULL` environment variable is set. - Add step to generate `currentlySupportedLangs.jsx` to use any list of languages in Makefile Refs: [FC-0012 project](https://openedx.atlassian.net/l/cp/XGS0iCcQ) implementing Translation Infrastructure OEP-58.
- Loading branch information
1 parent
4b63ee6
commit 2116cdb
Showing
7 changed files
with
236 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
#!/usr/bin/env node | ||
|
||
const scriptHelpDocument = ` | ||
NAME | ||
generateSupportedLangs.js — Script to generate the 'src/i18n/messages/currentlySupportedLangs.jsx' file which contains static import for react-intl data. | ||
SYNOPSIS | ||
generateSupportedLangs.js [comma separated list of languages] | ||
DESCRIPTION | ||
Run this script after 'atlas' has pulled the files in the following structure: | ||
$ generateSupportedLangs.js ar,es_419,fr_CA | ||
This script is intended as a temporary solution until the studio-frontend can dynamically load the languages from the react-intl data like the other micro-frontends. | ||
`; | ||
|
||
const fs = require('fs'); | ||
const path = require('path'); | ||
|
||
const loggingPrefix = path.basename(`${__filename}`); // the name of this JS file | ||
|
||
// Header note for generated src/i18n/index.js file | ||
const filesCodeGeneratorNoticeHeader = '// This file is generated by the "i18n/scripts/generateSupportedLangs.js" script.'; | ||
|
||
/** | ||
* Create main `src/i18n/index.js` messages import file. | ||
* | ||
* | ||
* @param languages - List of directories with a boolean flag whether its "index.js" file is written | ||
* The format is "[\{ directory: "frontend-component-example", isWritten: false \}, ...]" | ||
* @param log - Mockable process.stdout.write | ||
* @param writeFileSync - Mockable fs.writeFileSync | ||
* @param i18nDir` - Path to `src/i18n` directory | ||
*/ | ||
function generateSupportedLangsFile({ | ||
languages, | ||
log, | ||
writeFileSync, | ||
i18nDir, | ||
}) { | ||
const importLines = []; | ||
const exportLines = []; | ||
|
||
languages.forEach(language => { | ||
const [languageFamilyCode] = language.split('_'); // Get `es` from `es-419` | ||
|
||
const importVariableName = `${languageFamilyCode.toLowerCase()}Data`; | ||
const dashLanguageCode = language.toLowerCase().replace(/_/g, '-'); | ||
importLines.push(`import ${importVariableName} from 'react-intl/locale-data/${languageFamilyCode}';`); | ||
|
||
// Note: These imports are not directly consumed by the studio-frontend React app. They're imported to ensure that | ||
// the messages/*.json files exists and they can be loaded via the load_sfe_i18n_messages() function in | ||
// the `edx-platform`. | ||
// | ||
// This pattern should probably be refactored to pull the translations directly within the `edx-platform`. | ||
const jsonFilename = `${language}.json`; | ||
if (fs.existsSync(`${i18nDir}/messages/${jsonFilename}`)) { | ||
importLines.push(`import './${jsonFilename}';`); | ||
log(`${loggingPrefix}: Notice: Not importing 'messages/${jsonFilename}' because the file wasn't found.\n`); | ||
} | ||
|
||
exportLines.push(` '${dashLanguageCode}': ${importVariableName},`); | ||
}); | ||
|
||
// See the help message above for sample output. | ||
const indexFileContent = [ | ||
filesCodeGeneratorNoticeHeader, | ||
importLines.join('\n'), | ||
'\nexport default {', | ||
exportLines.join('\n'), | ||
'};\n', | ||
].join('\n'); | ||
|
||
writeFileSync(`${i18nDir}/messages/currentlySupportedLangs.jsx`, indexFileContent); | ||
} | ||
|
||
/* | ||
* Main function of the file. | ||
*/ | ||
function main({ | ||
parameters, | ||
log, | ||
writeFileSync, | ||
pwd, | ||
}) { | ||
const i18nDir = `${pwd}/src/i18n`; // The Micro-frontend i18n root directory | ||
const [languagesString] = parameters; | ||
|
||
if (parameters.includes('--help') || parameters.includes('-h')) { | ||
log(scriptHelpDocument); | ||
} else if (!parameters.length) { | ||
log(scriptHelpDocument); | ||
log(`${loggingPrefix}: Error: A comma separated list of languages is required.\n`); | ||
} else { | ||
generateSupportedLangsFile({ | ||
languages: languagesString.split(','), | ||
log, | ||
writeFileSync, | ||
i18nDir, | ||
}); | ||
log(`${loggingPrefix}: Finished generating the 'currentlySupportedLangs.jsx' file.`); | ||
} | ||
} | ||
|
||
if (require.main === module) { | ||
// Run the main() function if called from the command line. | ||
main({ | ||
parameters: process.argv.slice(2), | ||
log: text => process.stdout.write(text), | ||
writeFileSync: fs.writeFileSync, | ||
pwd: process.env.PWD, | ||
}); | ||
} | ||
|
||
module.exports.main = main; // Allow tests to use the main function. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
// Tests for the generateSupportedLangs.js command line. | ||
|
||
import path from 'path'; | ||
import { main as realMain } from './generateSupportedLangs'; | ||
|
||
const sempleAppDirectory = path.join(__dirname, '../../../test-app'); | ||
|
||
// History for `process.stdout.write` mock calls. | ||
const logHistory = { | ||
log: [], | ||
latest: '', | ||
}; | ||
|
||
// History for `fs.writeFileSync` mock calls. | ||
const writeFileHistory = { | ||
log: [], | ||
latest: null, | ||
}; | ||
|
||
// Mock for process.stdout.write | ||
const log = (text) => { | ||
logHistory.latest = text; | ||
logHistory.log.push(text); | ||
}; | ||
|
||
// Mock for fs.writeFileSync | ||
const writeFileSync = (filename, content) => { | ||
const entry = { filename, content }; | ||
writeFileHistory.latest = entry; | ||
writeFileHistory.log.push(entry); | ||
}; | ||
|
||
// Main with mocked output | ||
const main = (...parameters) => realMain({ | ||
parameters, | ||
log, | ||
writeFileSync, | ||
pwd: sempleAppDirectory, | ||
}); | ||
|
||
// Clean up mock histories | ||
afterEach(() => { | ||
logHistory.log = []; | ||
logHistory.latest = null; | ||
writeFileHistory.log = []; | ||
writeFileHistory.latest = null; | ||
}); | ||
|
||
describe('help document', () => { | ||
it('should print help for --help', () => { | ||
main('--help'); | ||
expect(logHistory.latest).toMatch( | ||
"generateSupportedLangs.js — Script to generate the 'src/i18n/messages/currentlySupportedLangs.jsx'" | ||
); | ||
}); | ||
|
||
it('should print help for -h', () => { | ||
main('-h'); | ||
expect(logHistory.latest).toMatch( | ||
"generateSupportedLangs.js — Script to generate the 'src/i18n/messages/currentlySupportedLangs.jsx'" | ||
); | ||
}); | ||
}); | ||
|
||
describe('generate with three languages', () => { | ||
main('ar,de,fr_CA'); // German doesn't have a messages file in the `test-app` | ||
|
||
expect(writeFileHistory.log.length).toBe(1); | ||
expect(writeFileHistory.latest.filename).toBe(`${sempleAppDirectory}/src/i18n/messages/currentlySupportedLangs.jsx`); | ||
|
||
// It should write the file with the following content: | ||
// - import 'react-intl/locale-data/ar' and ar.json messages | ||
// - import 'react-intl/locale-data/de' without de.json because it doesn't exist in the | ||
// test-app/src/i18n/messages directory | ||
// - import 'react-intl/locale-data/fr' and fr_CA.json messages | ||
// - export the imported locale-data | ||
expect(writeFileHistory.latest.content).toMatch(`// This file is generated by the "i18n/scripts/generateSupportedLangs.js" script. | ||
import arData from 'react-intl/locale-data/ar'; | ||
import './ar.json'; | ||
import deData from 'react-intl/locale-data/de'; | ||
import frData from 'react-intl/locale-data/fr'; | ||
import './fr_CA.json'; | ||
export default { | ||
'ar': arData, | ||
'de': deData, | ||
'fr-ca': frData, | ||
}; | ||
`); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Test i18n directory | ||
|
||
These test files are used by the `src/i18n/scripts/generateSupportedLangs.test.js` file. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"a11yBodyPolicyLink": "سياسة إمكانية الوصول" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"a11yBodyPolicyLink": "Politique d'accessibilité" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"a11yBodyPolicyLink": "网站可访问策略" | ||
} |