mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Merge pull request #3763 from MetaMask/i18n-helper
I18n - Improve verify locales utility
This commit is contained in:
commit
f6f144643f
@ -232,7 +232,7 @@
|
|||||||
"done": {
|
"done": {
|
||||||
"message": "Fertig"
|
"message": "Fertig"
|
||||||
},
|
},
|
||||||
"downloadStatelogs": {
|
"downloadStateLogs": {
|
||||||
"message": "Statelogs herunterladen"
|
"message": "Statelogs herunterladen"
|
||||||
},
|
},
|
||||||
"dropped": {
|
"dropped": {
|
||||||
|
@ -247,7 +247,7 @@
|
|||||||
"done": {
|
"done": {
|
||||||
"message": "Completo"
|
"message": "Completo"
|
||||||
},
|
},
|
||||||
"downloadStatelogs": {
|
"downloadStateLogs": {
|
||||||
"message": "Descargar logs de estado"
|
"message": "Descargar logs de estado"
|
||||||
},
|
},
|
||||||
"dropped": {
|
"dropped": {
|
||||||
|
@ -223,7 +223,7 @@
|
|||||||
"done": {
|
"done": {
|
||||||
"message": "संपन्न"
|
"message": "संपन्न"
|
||||||
},
|
},
|
||||||
"downloadStatelogs": {
|
"downloadStateLogs": {
|
||||||
"message": "राज्य लॉग डाउनलोड करें"
|
"message": "राज्य लॉग डाउनलोड करें"
|
||||||
},
|
},
|
||||||
"edit": {
|
"edit": {
|
||||||
|
@ -223,7 +223,7 @@
|
|||||||
"done": {
|
"done": {
|
||||||
"message": "Gedaan"
|
"message": "Gedaan"
|
||||||
},
|
},
|
||||||
"downloadStatelogs": {
|
"downloadStateLogs": {
|
||||||
"message": "Staatslogboeken downloaden"
|
"message": "Staatslogboeken downloaden"
|
||||||
},
|
},
|
||||||
"edit": {
|
"edit": {
|
||||||
|
@ -235,9 +235,8 @@
|
|||||||
"done": {
|
"done": {
|
||||||
"message": "Готово"
|
"message": "Готово"
|
||||||
},
|
},
|
||||||
"downloadStatelogs": {
|
"downloadStateLogs": {
|
||||||
"message": "Скачать журнал состояния"
|
"message": "Скачать журнал состояния"
|
||||||
},
|
|
||||||
"dropped": {
|
"dropped": {
|
||||||
"message": "Отброшена"
|
"message": "Отброшена"
|
||||||
},
|
},
|
||||||
|
@ -223,7 +223,7 @@
|
|||||||
"done": {
|
"done": {
|
||||||
"message": "Končano"
|
"message": "Končano"
|
||||||
},
|
},
|
||||||
"downloadStatelogs": {
|
"downloadStateLogs": {
|
||||||
"message": "Prenesi state dnevnike"
|
"message": "Prenesi state dnevnike"
|
||||||
},
|
},
|
||||||
"edit": {
|
"edit": {
|
||||||
|
@ -223,7 +223,7 @@
|
|||||||
"done": {
|
"done": {
|
||||||
"message": "เสร็จสิ้น"
|
"message": "เสร็จสิ้น"
|
||||||
},
|
},
|
||||||
"downloadStatelogs": {
|
"downloadStateLogs": {
|
||||||
"message": "ดาวน์โหลดล็อกสถานะ"
|
"message": "ดาวน์โหลดล็อกสถานะ"
|
||||||
},
|
},
|
||||||
"edit": {
|
"edit": {
|
||||||
|
@ -235,7 +235,7 @@
|
|||||||
"done": {
|
"done": {
|
||||||
"message": "完成"
|
"message": "完成"
|
||||||
},
|
},
|
||||||
"downloadStatelogs": {
|
"downloadStateLogs": {
|
||||||
"message": "下載狀態紀錄"
|
"message": "下載狀態紀錄"
|
||||||
},
|
},
|
||||||
"dropped": {
|
"dropped": {
|
||||||
|
@ -10,87 +10,88 @@
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
var fs = require('fs')
|
const fs = require('fs')
|
||||||
var path = require('path')
|
const path = require('path')
|
||||||
|
const localeIndex = require('../app/_locales/index.json')
|
||||||
|
|
||||||
console.log('Locale Verification')
|
console.log('Locale Verification')
|
||||||
|
|
||||||
var locale = process.argv[2]
|
const specifiedLocale = process.argv[2]
|
||||||
if (!locale || locale == '') {
|
if (specifiedLocale) {
|
||||||
console.log('Must enter a locale as argument. exitting')
|
console.log(`Verifying selected locale "${specifiedLocale}":\n\n`)
|
||||||
process.exit(1)
|
const locale = localeIndex.find(localeMeta => localeMeta.code === specifiedLocale)
|
||||||
}
|
verifyLocale({ localeMeta })
|
||||||
|
|
||||||
console.log("verifying for locale " + locale)
|
|
||||||
|
|
||||||
localeFilePath = path.join(process.cwd(), 'app', '_locales', locale, 'messages.json')
|
|
||||||
try {
|
|
||||||
localeObj = JSON.parse(fs.readFileSync(localeFilePath, 'utf8'));
|
|
||||||
} catch (e) {
|
|
||||||
if(e.code == 'ENOENT') {
|
|
||||||
console.log('Locale file not found')
|
|
||||||
} else {
|
|
||||||
console.log('Error opening your locale file: ', e)
|
|
||||||
}
|
|
||||||
process.exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
englishFilePath = path.join(process.cwd(), 'app', '_locales', 'en', 'messages.json')
|
|
||||||
try {
|
|
||||||
englishObj = JSON.parse(fs.readFileSync(englishFilePath, 'utf8'));
|
|
||||||
} catch (e) {
|
|
||||||
if(e.code == 'ENOENT') {
|
|
||||||
console.log("English File not found")
|
|
||||||
} else {
|
|
||||||
console.log("Error opening english locale file: ", e)
|
|
||||||
}
|
|
||||||
process.exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('\tverifying whether all your locale strings are contained in the english one')
|
|
||||||
|
|
||||||
var counter = 0
|
|
||||||
var foundErrorA = false
|
|
||||||
var notFound = [];
|
|
||||||
Object.keys(localeObj).forEach(function(key){
|
|
||||||
if (!englishObj[key]) {
|
|
||||||
foundErrorA = true
|
|
||||||
notFound.push(key)
|
|
||||||
}
|
|
||||||
counter++
|
|
||||||
})
|
|
||||||
|
|
||||||
if (foundErrorA) {
|
|
||||||
console.log('\nThe following string(s) is(are) not found in the english locale:')
|
|
||||||
notFound.forEach(function(key) {
|
|
||||||
console.log(key)
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
console.log('\tall ' + counter +' strings declared in your locale were found in the english one')
|
console.log('Verifying all locales:\n\n')
|
||||||
}
|
localeIndex.forEach(localeMeta => {
|
||||||
|
verifyLocale({ localeMeta })
|
||||||
console.log('\n\tverifying whether your locale contains all english strings')
|
console.log('\n')
|
||||||
|
|
||||||
var counter = 0
|
|
||||||
var foundErrorB = false
|
|
||||||
var notFound = [];
|
|
||||||
Object.keys(englishObj).forEach(function(key){
|
|
||||||
if (!localeObj[key]) {
|
|
||||||
foundErrorB = true
|
|
||||||
notFound.push(key)
|
|
||||||
}
|
|
||||||
counter++
|
|
||||||
})
|
|
||||||
|
|
||||||
if (foundErrorB) {
|
|
||||||
console.log('\nThe following string(s) is(are) not found in the your locale:')
|
|
||||||
notFound.forEach(function(key) {
|
|
||||||
console.log(key)
|
|
||||||
})
|
})
|
||||||
} else {
|
|
||||||
console.log('\tall ' + counter +' english strings were found in your locale!')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!foundErrorA && !foundErrorB) {
|
|
||||||
console.log('You are good to go')
|
|
||||||
}
|
function verifyLocale({ localeMeta }) {
|
||||||
|
const localeCode = localeMeta.code
|
||||||
|
const localeName = localeMeta.name
|
||||||
|
|
||||||
|
try {
|
||||||
|
const localeFilePath = path.join(process.cwd(), 'app', '_locales', localeCode, 'messages.json')
|
||||||
|
targetLocale = JSON.parse(fs.readFileSync(localeFilePath, 'utf8'));
|
||||||
|
} catch (e) {
|
||||||
|
if (e.code == 'ENOENT') {
|
||||||
|
console.log('Locale file not found')
|
||||||
|
} else {
|
||||||
|
console.log(`Error opening your locale ("${localeCode}") file: `, e)
|
||||||
|
}
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const englishFilePath = path.join(process.cwd(), 'app', '_locales', 'en', 'messages.json')
|
||||||
|
englishLocale = JSON.parse(fs.readFileSync(englishFilePath, 'utf8'));
|
||||||
|
} catch (e) {
|
||||||
|
if(e.code == 'ENOENT') {
|
||||||
|
console.log('English File not found')
|
||||||
|
} else {
|
||||||
|
console.log('Error opening english locale file: ', e)
|
||||||
|
}
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log(' verifying whether all your locale ("${localeCode}") strings are contained in the english one')
|
||||||
|
const extraItems = compareLocalesForMissingItems({ base: targetLocale, subject: englishLocale })
|
||||||
|
// console.log('\n verifying whether your locale ("${localeCode}") contains all english strings')
|
||||||
|
const missingItems = compareLocalesForMissingItems({ base: englishLocale, subject: targetLocale })
|
||||||
|
|
||||||
|
const englishEntryCount = Object.keys(englishLocale).length
|
||||||
|
const coveragePercent = 100 * (englishEntryCount - missingItems.length) / englishEntryCount
|
||||||
|
|
||||||
|
console.log(`Status of **${localeName} (${localeCode})** ${coveragePercent.toFixed(2)}% coverage:`)
|
||||||
|
|
||||||
|
if (extraItems.length) {
|
||||||
|
console.log('\nMissing from english locale:')
|
||||||
|
extraItems.forEach(function(key) {
|
||||||
|
console.log(` - [ ] ${key}`)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// console.log(` all ${counter} strings declared in your locale ("${localeCode}") were found in the english one`)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (missingItems.length) {
|
||||||
|
console.log(`\nMissing:`)
|
||||||
|
missingItems.forEach(function(key) {
|
||||||
|
console.log(` - [ ] ${key}`)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// console.log(` all ${counter} english strings were found in your locale ("${localeCode}")!`)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!extraItems.length && !missingItems.length) {
|
||||||
|
console.log('Full coverage : )')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function compareLocalesForMissingItems({ base, subject }) {
|
||||||
|
return Object.keys(base).filter((key) => !subject[key])
|
||||||
|
}
|
||||||
|
@ -6,9 +6,12 @@ The MetaMask browser extension supports new translations added in the form of ne
|
|||||||
|
|
||||||
## Adding a new Language
|
## Adding a new Language
|
||||||
|
|
||||||
Each supported language is represented by a folder in `app/_locales` whose name is that language's subtag ([look up a language subtag using this tool](https://r12a.github.io/app-subtags/)).
|
- Each supported language is represented by a folder in `app/_locales` whose name is that language's subtag (example: `app/_locales/es/`). (look up a language subtag using the [r12a "Find" tool](https://r12a.github.io/app-subtags/) or this [wikipedia list](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes)).
|
||||||
|
- Inside that folder there should be a `messages.json`.
|
||||||
|
- An easy way to start your translation is to first **make a copy** of `app/_locales/en/messages.json` (the english translation), and then **translate the `message` key** for each in-app message.
|
||||||
|
- **The `description` key** is just to add context for what the translation is about, it **does not need to be translated**.
|
||||||
|
- Add the language to the [locales index](https://github.com/MetaMask/metamask-extension/blob/master/app/_locales/index.json) `app/_locales/index.json`
|
||||||
|
|
||||||
Inside that folder there should be a `messages.json` file that follows the specified format. An easy way to start your translation is to first duplicate `app/_locales/en/messages.json` (the english translation), and then update the `message` key for each in-app message.
|
|
||||||
|
|
||||||
That's it! When MetaMask is loaded on a computer with that language set as the system language, they will see your translation instead of the default one.
|
That's it! When MetaMask is loaded on a computer with that language set as the system language, they will see your translation instead of the default one.
|
||||||
|
|
||||||
@ -20,7 +23,7 @@ To automatically see if you are missing any phrases to translate, we have a scri
|
|||||||
node development/verify-locale-strings.js $YOUR_LOCALE
|
node development/verify-locale-strings.js $YOUR_LOCALE
|
||||||
```
|
```
|
||||||
|
|
||||||
Where `$YOUR_LOCALE` is your [locale string](https://r12a.github.io/app-subtags/), i.e. the name of your language folder.
|
Where `$YOUR_LOCALE` is your locale string (example: `es`), i.e. the name of your language folder.
|
||||||
|
|
||||||
To verify that your translation works in the app, you will need to [build a local copy](https://github.com/MetaMask/metamask-extension#building-locally) of MetaMask. You will need to change your browser language, your operating system language, and restart your browser (sorry it's so much work!).
|
To verify that your translation works in the app, you will need to [build a local copy](https://github.com/MetaMask/metamask-extension#building-locally) of MetaMask. You will need to change your browser language, your operating system language, and restart your browser (sorry it's so much work!).
|
||||||
|
|
||||||
|
47
package-lock.json
generated
47
package-lock.json
generated
@ -7148,12 +7148,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
|
||||||
"integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
|
"integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
|
||||||
},
|
},
|
||||||
"fork-stream": {
|
|
||||||
"version": "0.0.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/fork-stream/-/fork-stream-0.0.4.tgz",
|
|
||||||
"integrity": "sha1-24Sfznf2cIpfjzhq5TOgkHtUrnA=",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"form-data": {
|
"form-data": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz",
|
||||||
@ -8683,17 +8677,6 @@
|
|||||||
"gulp-util": "3.0.8"
|
"gulp-util": "3.0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"gulp-if": {
|
|
||||||
"version": "2.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/gulp-if/-/gulp-if-2.0.2.tgz",
|
|
||||||
"integrity": "sha1-pJe351cwBQQcqivIt92jyARE1ik=",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"gulp-match": "1.0.3",
|
|
||||||
"ternary-stream": "2.0.1",
|
|
||||||
"through2": "2.0.3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"gulp-json-editor": {
|
"gulp-json-editor": {
|
||||||
"version": "2.2.1",
|
"version": "2.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/gulp-json-editor/-/gulp-json-editor-2.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/gulp-json-editor/-/gulp-json-editor-2.2.1.tgz",
|
||||||
@ -8845,15 +8828,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"gulp-match": {
|
|
||||||
"version": "1.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/gulp-match/-/gulp-match-1.0.3.tgz",
|
|
||||||
"integrity": "sha1-kcfA1/Kb7NZgbVfYCn+Hdqh6uo4=",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"minimatch": "3.0.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"gulp-replace": {
|
"gulp-replace": {
|
||||||
"version": "0.6.1",
|
"version": "0.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/gulp-replace/-/gulp-replace-0.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/gulp-replace/-/gulp-replace-0.6.1.tgz",
|
||||||
@ -13247,15 +13221,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
||||||
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
|
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
|
||||||
},
|
},
|
||||||
"merge-stream": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz",
|
|
||||||
"integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"readable-stream": "2.3.3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"merkle-patricia-tree": {
|
"merkle-patricia-tree": {
|
||||||
"version": "2.3.0",
|
"version": "2.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.0.tgz",
|
||||||
@ -20753,18 +20718,6 @@
|
|||||||
"inherits": "2.0.3"
|
"inherits": "2.0.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ternary-stream": {
|
|
||||||
"version": "2.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/ternary-stream/-/ternary-stream-2.0.1.tgz",
|
|
||||||
"integrity": "sha1-Bk5Im0tb9gumpre8fy9cJ07Pgmk=",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"duplexify": "3.5.1",
|
|
||||||
"fork-stream": "0.0.4",
|
|
||||||
"merge-stream": "1.0.1",
|
|
||||||
"through2": "2.0.3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"testem": {
|
"testem": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/testem/-/testem-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/testem/-/testem-2.0.0.tgz",
|
||||||
|
Loading…
Reference in New Issue
Block a user