REF: script to detect unused locale keys

This commit is contained in:
Overtorment 2022-09-30 20:15:10 +01:00 committed by overtorment
parent 0abe23b36a
commit 36d23919bf
3 changed files with 83 additions and 36 deletions

View file

@ -10,8 +10,6 @@
"of": "{number} of {total}",
"ok": "OK",
"storage_is_encrypted": "Your storage is encrypted. Password is required to decrypt it.",
"allow": "Allow",
"dont_allow": "Dont Allow",
"yes": "Yes",
"no": "No",
"save": "Save",
@ -20,12 +18,7 @@
"wallet_key": "Wallet key",
"invalid_animated_qr_code_fragment" : "Invalid animated QRCode fragment. Please try again.",
"file_saved": "File {filePath} has been saved in your {destination}.",
"file_save_title": "Save File",
"file_save_location": "Select where to save {filePath}",
"downloads_folder": "Downloads Folder",
"external_storage": "External Storage",
"discard_changes": "Discard changes?",
"discard_changes_detail": "You have unsaved changes. Are you sure to discard them and leave the screen?"
"downloads_folder": "Downloads Folder"
},
"alert": {
"default": "Alert"
@ -61,7 +54,6 @@
"force_close_channel": "Force close channel?",
"expired": "Expired",
"node_alias": "Node alias",
"expiredLow": "Expired",
"expiresIn": "Expires in {time} minutes",
"payButton": "Pay",
"placeholder": "Invoice",
@ -69,12 +61,6 @@
"funding_amount_placeholder": "Funding amount, for example 0.001",
"opening_channnel_for_from":"Opening channel for wallet {forWalletLabel}, by funding from {fromWalletLabel}",
"are_you_sure_open_channel": "Are you sure you want to open this channel?",
"are_you_sure_exit_without_new_channel": "Are you sure you want to exit without opening a channel?",
"public": "Public",
"public_description": "Visible on the network: It can be a routing node and earn fees.",
"private": "Private",
"private_description": "Invisible on the network: It will preserve the privacy of your payments.",
"local_reserve": "Local reserve",
"potentialFee": "Potential Fee: {fee}",
"remote_host": "Remote host",
"refill": "Refill",
@ -92,7 +78,6 @@
"additional_info": "Additional Information",
"for": "For:",
"lightning_invoice": "Lightning Invoice",
"has_been_paid": "This invoice has been paid.",
"open_direct_channel": "Open direct channel with this node:",
"please_pay_between_and": "Please pay between {min} and {max}",
"please_pay": "Please pay",
@ -120,7 +105,6 @@
"ok_lnd": "OK, I have saved it",
"text": "Please take a moment to write down this mnemonic phrase on a piece of paper.\nIts your backup and you can use it to recover the wallet.",
"text_lnd": "Please save this wallet backup. It allows you to restore the wallet in case of loss.",
"text_lnd2": "This wallet is hosted by BlueWallet.",
"title": "Your wallet has been created"
},
"receive": {
@ -214,7 +198,6 @@
"psbt_tx_open": "Open Signed Transaction",
"psbt_tx_scan": "Scan Signed Transaction",
"qr_error_no_qrcode": "We were unable to find a QR Code in the selected image. Make sure the image contains only a QR Code and no additional content such as text, or buttons.",
"qr_error_no_wallet": "The selected file doesnt contain a wallet that can be imported.",
"reset_amount": "Reset Amount",
"reset_amount_confirm": "Would you like to reset the amount?",
"success_done": "Done",
@ -251,7 +234,6 @@
"default_wallets": "View All Wallets",
"electrum_connected": "Connected",
"electrum_connected_not": "Not Connected",
"electrum_connnected_not_description": "An active Electrum connection is required to import a wallet. You can verify if a connection is established by going to the Network section in Settings.",
"electrum_error_connect": "Cant connect to the provided Electrum server",
"lndhub_uri": "E.g., {example}",
"electrum_host": "E.g., {example}",
@ -279,7 +261,6 @@
"tor_unsupported": "Tor connections are not supported.",
"encrypt_decrypt": "Decrypt Storage",
"encrypt_decrypt_q": "Are you sure you want to decrypt your storage? This will allow your wallets to be accessed without a password.",
"encrypt_del_uninstall": "Delete if BlueWallet is uninstalled",
"encrypt_enc_and_pass": "Encrypted and Password Protected",
"encrypt_title": "Security",
"encrypt_tstorage": "Storage",
@ -312,7 +293,6 @@
"plausible_deniability": "Plausible Deniability",
"privacy": "Privacy",
"privacy_read_clipboard": "Read Clipboard",
"privacy_read_clipboard_alert": "BlueWallet will display shortcuts for handling an invoice or address found in your clipboard.",
"privacy_system_settings": "System Settings",
"privacy_quickactions": "Wallet Shortcuts",
"privacy_quickactions_explanation": "Touch and hold the BlueWallet app icon on your Home Screen to quickly view your wallets balance.",
@ -363,7 +343,6 @@
"details_show_in_block_explorer": "View in Block Explorer",
"details_title": "Transaction",
"details_to": "Output",
"details_transaction_details": "Transaction Details",
"enable_offline_signing": "This wallet is not being used in conjunction with an offline signing. Would you wish to enable it now?",
"list_conf": "Conf: {number}",
"pending": "Pending",
@ -396,7 +375,6 @@
"add_lndhub": "Connect to your LNDHub",
"add_lndhub_error": "The provided node address is an invalid LNDHub node.",
"add_lndhub_placeholder": "Your Node Address",
"add_or": "or",
"add_placeholder": "my first wallet",
"add_title": "Add Wallet",
"add_wallet_name": "Name",
@ -416,9 +394,6 @@
"details_display": "Display in Wallets List",
"details_export_backup": "Export/Backup",
"details_master_fingerprint": "Master Fingerprint",
"details_ms_l": "{m} of {n} legacy (p2sh)",
"details_ms_ns": "{m} of {n} native segwit (p2wsh)",
"details_ms_ws": "{m} of {n} wrapped segwit (p2sh-p2wsh)",
"details_multisig_type": "multisig",
"details_no_cancel": "No, cancel",
"details_save": "Save",
@ -461,8 +436,6 @@
"list_empty_txs1_lightning": "Lightning wallet should be used for your daily transactions. Fees are unfairly cheap and the speed is blazing fast.",
"list_empty_txs2": "Start with your wallet.",
"list_empty_txs2_lightning": "\nTo start using it, tap on Manage Funds and topup your balance.",
"list_header": "A wallet represents a pair of keys: one private and one you can share to receive coins.",
"list_import_problem": "There was a problem importing this wallet.",
"list_latest_transaction": "Latest Transaction",
"list_ln_browser": "LApp Browser",
"list_long_choose": "Choose Photo",
@ -475,7 +448,6 @@
"reorder_title": "Re-order Wallets",
"reorder_instructions": "Tap and hold a wallet to drag it across the list.",
"please_continue_scanning": "Please continue scanning.",
"scan_error": "Scan Error",
"select_no_bitcoin": "There are currently no Bitcoin wallets available.",
"select_no_bitcoin_exp": "A Bitcoin wallet is required to refill Lightning wallets. Please create or import one.",
"select_wallet": "Select Wallet",
@ -509,7 +481,6 @@
"cosign_this_transaction": "Co-sign this transaction?",
"lets_start": "Lets start",
"create": "Create",
"provide_key": "Provide key",
"native_segwit_title": "Best practice",
"wrapped_segwit_title": "Best compatibility",
"legacy_title": "Legacy",
@ -526,7 +497,6 @@
"quorum_header": "Quorum",
"of": "of",
"wallet_type": "Wallet Type",
"view_key": "View",
"invalid_mnemonics": "This mnemonic phrase doesnt seem to be valid.",
"invalid_cosigner": "Invalid cosigner data",
"not_a_multisignature_xpub": "This is not an XPUB from a multisignature wallet!",
@ -534,14 +504,11 @@
"create_new_key": "Create New",
"scan_or_open_file": "Scan or open file",
"i_have_mnemonics": "I have a seed for this key.",
"please_write_down_mnemonics": "Please write down this mnemonic phrase on paper. Dont worry, you can write it down later.",
"i_wrote_it_down": "OK, I wrote it down.",
"type_your_mnemonics": "Insert a seed to import your existing Vault key.",
"this_is_cosigners_xpub": "This is the cosigners XPUB—ready to be imported into another wallet. It is safe to share it.",
"wallet_key_created": "Your Vault key was created. Take a moment to safely backup your mnemonic seed.",
"are_you_sure_seed_will_be_lost": "Are you sure? Your mnemonic seed will be lost if you dont have a backup.",
"forget_this_seed": "Forget this seed and use the XPUB instead.",
"invalid_fingerprint": "Fingerprint for this seed doesnt match this cosigners fingerprint.",
"view_edit_cosigners": "View/Edit Cosigners",
"this_cosigner_is_already_imported": "This cosigner is already imported.",
"export_signed_psbt": "Export Signed PSBT",
@ -594,7 +561,6 @@
"sign_title": "Sign/Verify Message",
"sign_help": "Here you can create or verify a cryptographic signature based on a Bitcoin address.",
"sign_sign": "Sign",
"sign_sign_submit": "Sign and Submit",
"sign_verify": "Verify",
"sign_signature_correct": "Verification successful!",
"sign_signature_incorrect": "Verification failed!",

View file

@ -65,7 +65,7 @@
"e2e:release-build": "detox build -c android.release",
"e2e:release-test": "detox test -c android.release --record-videos all --record-logs all --take-screenshots all --headless -d 200000",
"tslint": "tsc",
"lint": "eslint --ext .js,.ts,.tsx '*.@(js|ts|tsx)' screen 'blue_modules/*.@(js|ts|tsx)' class models loc tests components && npm run tslint",
"lint": "eslint --ext .js,.ts,.tsx '*.@(js|ts|tsx)' screen 'blue_modules/*.@(js|ts|tsx)' class models loc tests components && npm run tslint && node scripts/find-unused-loc.js",
"lint:fix": "npm run lint -- --fix",
"lint:quickfix": "git status --porcelain | grep -v '\\.json' | grep -E '\\.js|\\.ts' --color=never | awk '{print $2}' | xargs eslint --fix; exit 0",
"unit": "jest -b -i tests/unit/*",

View file

@ -0,0 +1,81 @@
const fs = require('fs');
const path = require('path');
const mainLocFile = './loc/en.json';
const dirsToInterate = ['components', 'screen', 'blue_modules', 'class'];
const addFiles = ['BlueComponents.js', 'App.js', 'BlueApp.js'];
const allowedLocPrefixes = ['loc.lnurl_auth', 'loc.units'];
const allLocKeysHashmap = {}; // loc key -> used or not
const getAllFiles = function (dirPath, arrayOfFiles) {
const files = fs.readdirSync(dirPath);
arrayOfFiles = arrayOfFiles || [];
files.forEach(function (file) {
if (fs.statSync(dirPath + '/' + file).isDirectory()) {
arrayOfFiles = getAllFiles(dirPath + '/' + file, arrayOfFiles);
} else {
arrayOfFiles.push(path.resolve(path.join(dirPath, '/', file)));
}
});
return arrayOfFiles;
};
const allDirFiles = [];
for (const dir of dirsToInterate) {
allDirFiles.push(...getAllFiles(dir));
}
for (const filename of addFiles) {
allDirFiles.push(path.resolve(filename));
}
allDirFiles.push(path.resolve('App.js'));
// got all source files
function objKeysRecursive(obj, depth = []) {
for (const k in obj) {
if (typeof obj[k] === 'object' && obj[k] !== null) {
objKeysRecursive(obj[k], depth.concat(k));
} else {
allLocKeysHashmap['loc.' + depth.join('.') + '.' + k] = false; // false means unused
}
}
}
objKeysRecursive(JSON.parse(fs.readFileSync(mainLocFile).toString('utf8')));
// got all loc keys.
// finally, iterating all source files, readign them and looking for unused loc keys
// iterating all files
for (const filepath of allDirFiles) {
const contents = fs.readFileSync(filepath);
// opened a file. iterating all loc keys
for (const key of Object.keys(allLocKeysHashmap)) {
if (contents.includes(key)) {
// opened file uses this loc key. marking it as used
allLocKeysHashmap[key] = true;
}
}
}
// done! now printing results:
let exitCode = 0;
for (const key of Object.keys(allLocKeysHashmap)) {
let allow = false;
for (const allowedKey of allowedLocPrefixes) {
if (key.startsWith(allowedKey)) allow = true;
}
if (allLocKeysHashmap[key] === false && !allow) {
console.log('Unused loc key: ' + key);
exitCode = 1;
}
}
process.exit(exitCode);