Skip to content

Commit

Permalink
Mark all strings for l10n
Browse files Browse the repository at this point in the history
Fix #645
Fix #646
Fix #475

Also calls out to upload missing strings
  • Loading branch information
bbondy committed Jul 26, 2018
1 parent 990f16d commit b99afd3
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 80 deletions.
7 changes: 6 additions & 1 deletion lib/chromiumRebaseL10n.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,15 @@

const config = require('../lib/config')
const util = require('../lib/util')
const {rebaseBraveStringFilesOnChromiumL10nFiles} = require('./l10nUtil')
const {rebaseBraveStringFilesOnChromiumL10nFiles, braveAutoGeneratedPaths} = require('./l10nUtil')

const chromiumRebaseL10n = (options) => {
rebaseBraveStringFilesOnChromiumL10nFiles()
braveAutoGeneratedPaths.forEach((sourceStringPath) => {
const cmdOptions = config.defaultOptions
cmdOptions.cwd = config.projects['brave-core'].dir
util.run('python', ['script/chromium-rebase-l10n.py', '--source_string_path', sourceStringPath], cmdOptions)
})
}

module.exports = chromiumRebaseL10n
146 changes: 88 additions & 58 deletions lib/l10nUtil.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,91 +2,121 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */


/**
* This file manages the following:
* - Lists of files needed to be translated (Which is all top level GRD and JSON files)
* - All mappings for auto-generated Brave files from the associated Chromium files.
* - Top level global string replacements, such as replacing Chromium with Brave
*/

const path = require('path')
const fs = require('fs')

const srcDir = path.resolve(path.join(__dirname, '..', 'src'))

// Brave string paths
// chromium_strings.grd and any of its parts files that we track localization for in transifex
// These map to brave/app/resources/chromium_strings*.xtb
const chromiumStringsPath = path.resolve(path.join(srcDir, 'chrome', 'app', 'chromium_strings.grd'))
const braveStringsPath = path.resolve(path.join(srcDir, 'brave', 'app', 'brave_strings.grd'))
const chromiumSettingsPartPath = path.resolve(path.join(srcDir, 'chrome', 'app', 'settings_chromium_strings.grdp'))
const braveSettingsPartPath = path.resolve(path.join(srcDir, 'brave', 'app', 'settings_brave_strings.grdp'))

// component_chromium_strings.grd and any of its parts files that we track localization for in transifex
// These map to brave/app/strings/components_chromium_strings*.xtb
const chromiumComponentsStringsPath = path.resolve(path.join(srcDir, 'components', 'components_chromium_strings.grd'))
const braveComponentsStringsPath = path.resolve(path.join(srcDir, 'brave', 'app', 'components_brave_strings.grd'))
const braveExtensionMessagesPath = path.resolve(path.join(srcDir, 'brave', 'vendor', 'brave-extension', 'app', '_locales', 'en_US', 'messages.json'))
const braveSpecificGeneratedResourcesPath = path.resolve(path.join(srcDir, 'brave', 'app', 'brave_generated_resources.grd'))
const braveComponentsResourcesPath = path.resolve(path.join(srcDir, 'brave', 'components', 'resources', 'brave_components_resources.grd'))

// generated_resources.grd and any of its parts files that we track localization for in transifex
// There is also chromeos_strings.grdp but we don't need to track it here
// These map to brave/app/resources/generated_resoruces*.xtb
const chromiumGeneratedResourcesPath = path.resolve(path.join(srcDir, 'chrome', 'app', 'generated_resources.grd'))
const braveGeneratedResourcesPath = path.resolve(path.join(srcDir, 'brave', 'app', 'generated_resources.grd'))
const chromiumBookmarksPartPath = path.resolve(path.join(srcDir, 'chrome', 'app', 'bookmarks_strings.grdp'))
const braveBookmarksPartPath = path.resolve(path.join(srcDir, 'brave', 'app', 'bookmarks_strings.grdp'))
const chromiumMediaRouterPartPath = path.resolve(path.join(srcDir, 'chrome', 'app', 'media_router_strings.grdp'))
const braveMediaRouterPartPath = path.resolve(path.join(srcDir, 'brave', 'app', 'media_router_strings.grdp'))
const chromiumSettingsStringsPartPath = path.resolve(path.join(srcDir, 'chrome', 'app', 'settings_strings.grdp'))
const braveSettingsStringsPartPath = path.resolve(path.join(srcDir, 'brave', 'app', 'settings_strings.grdp'))
const chromiumMdExtensionsPartPath = path.resolve(path.join(srcDir, 'chrome', 'app', 'md_extensions_strings.grdp'))
const braveMdExtensionsPartPath = path.resolve(path.join(srcDir, 'brave', 'app', 'md_extensions_strings.grdp'))
const chromiumPrintingStringsPartPath = path.resolve(path.join(srcDir, 'chrome', 'app', 'printing_strings.grdp'))
const bravePrintingStringsPartPath = path.resolve(path.join(srcDir, 'brave', 'app', 'printing_strings.grdp'))

// extensions_resources.grd and any of its parts files that we track localization for in transifex
// There are no XTB files for this.
const chromiumExtensionsResourcesPath = path.resolve(path.join(srcDir, 'chrome', 'browser', 'resources', 'md_extensions', 'extensions_resources.grd'))
const braveExtensionsResourcesPath = path.resolve(path.join(srcDir, 'brave', 'browser', 'resources', 'md_extensions', 'extensions_resources.grd'))

// settings_resources.grd and any of its parts files that we track localization for in transifex
// There are no XTB files for this.
const chromiumSettingsResourcesPath = path.resolve(path.join(srcDir, 'chrome', 'browser', 'resources', 'settings', 'settings_resources.grd'))
const braveSettingsResourcesPath = path.resolve(path.join(srcDir, 'brave', 'browser', 'resources', 'settings', 'settings_resources.grd'))
const braveBrowserResourcesPath = path.resolve(path.join(srcDir, 'brave', 'browser', 'browser_resources.grd'))

// Chromium string paths
const chromiumStringsPath = path.resolve(path.join(srcDir, 'chrome', 'app', 'chromium_strings.grd'))
const chroimumSettingsPartPath = path.resolve(path.join(srcDir, 'chrome', 'app', 'settings_chromium_strings.grdp'))
const chromiumComponentsStringsPath = path.resolve(path.join(srcDir, 'components', 'components_chromium_strings.grd'))
// browser_resources.grd and any of its parts files that we track localization for in transifex
// We currently do not need to track media_router_resources.grdp
// There are no XTB files for this.
const chromiumBrowserResourcesPath = path.resolve(path.join(srcDir, 'chrome', 'browser', 'browser_resources.grd'))
const braveBrowserResourcesPath = path.resolve(path.join(srcDir, 'brave', 'browser', 'browser_resources.grd'))

const chromiumGeneratedResourcesPath = path.resolve(path.join(srcDir, 'chrome', 'app', 'generated_resources.grd'))
const chromiumBookmarksPartPath = path.resolve(path.join(srcDir, 'chrome', 'app', 'bookmarks_strings.grdp'))
const chromiumMediaRouterPartPath = path.resolve(path.join(srcDir, 'chrome', 'app', 'media_router_strings.grdp'))
const chromiumSettingsStringsPartPath = path.resolve(path.join(srcDir, 'chrome', 'app', 'settings_strings.grdp'))
const chromiumMdExtensionsPartPath = path.resolve(path.join(srcDir, 'chrome', 'app', 'md_extensions_strings.grdp'))
const chromePrintingStringsPartPath = path.resolve(path.join(srcDir, 'chrome', 'app', 'printing_strings.grdp'))
// The following are not generated files but still need to be tracked so they get sent to transifex
// These xtb files don't need to be copied anywhere.
// brave_generated_resources.grd maps to brave/app/resources/brave_generated_resources*.xtb,
// brave_component_resources.grd maps to brave/components/resources/strings/brave_components_resources*.xtb
// messages.json localization is handled inside of brave-extension.
const braveSpecificGeneratedResourcesPath = path.resolve(path.join(srcDir, 'brave', 'app', 'brave_generated_resources.grd'))
const braveComponentsResourcesPath = path.resolve(path.join(srcDir, 'brave', 'components', 'resources', 'brave_components_resources.grd'))
const braveExtensionMessagesPath = path.resolve(path.join(srcDir, 'brave', 'vendor', 'brave-extension', 'app', '_locales', 'en_US', 'messages.json'))

const chromiumExtensionsResourcesPath = path.resolve(path.join(srcDir, 'chrome', 'browser', 'resources', 'md_extensions', 'extensions_resources.grd'))
const chromiumSettingsResourcesPath = path.resolve(path.join(srcDir, 'chrome', 'browser', 'resources', 'settings', 'settings_resources.grd'))
const chromiumBrowserResourcesPath = path.resolve(path.join(srcDir, 'chrome', 'browser', 'browser_resources.grd'))
// When adding new grd or grd files, never add a grdp part path without a parent grd path.
// Group them with a leading and trailing newline to keep this file organized.

const autoGeneratedWarning = '<!-- This file is created by l10nUtil.js. Do not edit manually. -->'

const pageVisibility = ' <structure name="IDR_SETTINGS_PAGE_VISIBILITY_JS"\n'
const bravePageVisibility = ' <structure name="IDR_SETTINGS_BRAVE_PAGE_VISIBILITY_JS"\n' +
' file="brave_page_visibility.js"\n' +
' type="chrome_html" />\n'

module.exports.getSourceStringPaths = () => {
return [
braveStringsPath,
braveComponentsStringsPath,
braveExtensionMessagesPath,
braveSpecificGeneratedResourcesPath,
braveComponentsResourcesPath,
braveGeneratedResourcesPath,
// No strings for now, uncomment if strings are added
// path.resolve(path.join(srcDir, 'brave', 'browser', 'resources', 'brave_extension.grd')),
// path.resolve(path.join(srcDir, 'brave', 'common', 'extensions', 'api', 'brave_api_resources.grd')),
]
// Add all mappings here whether it is a GRD or a GRDP.
// Brave specific only grd and grdp files should not be added here.
const chromiumToAutoGeneratedBraveMapping = {
[chromiumStringsPath]: braveStringsPath,
[chromiumSettingsPartPath]: braveSettingsPartPath,
[chromiumComponentsStringsPath]: braveComponentsStringsPath,
[chromiumGeneratedResourcesPath]: braveGeneratedResourcesPath,
[chromiumBookmarksPartPath]: braveBookmarksPartPath,
[chromiumMediaRouterPartPath]: braveMediaRouterPartPath,
[chromiumSettingsStringsPartPath]: braveSettingsStringsPartPath,
[chromiumMdExtensionsPartPath]: braveMdExtensionsPartPath,
[chromiumPrintingStringsPartPath]: bravePrintingStringsPartPath,
[chromiumExtensionsResourcesPath]: braveExtensionsResourcesPath,
[chromiumSettingsResourcesPath]: braveSettingsResourcesPath,
[chromiumBrowserResourcesPath]: braveBrowserResourcesPath
}

// Same as with chromiumToAutoGeneratedBraveMapping but maps in the opposite direction
module.exports.autoGeneratedBraveToChromiumMapping = Object.keys(chromiumToAutoGeneratedBraveMapping)
.reduce((obj, key) => ({ ...obj, [chromiumToAutoGeneratedBraveMapping[key]]: key }), {})

// All paths which are not generated
module.exports.braveNonGeneratedPaths = [
//braveSpecificGeneratedResourcesPath, braveComponentsResourcesPath, braveExtensionMessagesPath
]
// All paths which are generated
module.exports.braveAutoGeneratedPaths = Object.values(chromiumToAutoGeneratedBraveMapping)

// Brave specific strings and Chromium mapped Brave strings will be here.
// But you only need to add the Brave specific strings manually here.
module.exports.allBravePaths = module.exports.braveNonGeneratedPaths.concat(module.exports.braveAutoGeneratedPaths)

// Get all GRD and JSON paths whether they are generatd or not
// Push and pull scripts for l10n use this.
// Transifex manages files per grd and not per grd or grdp.
// This is because only 1 xtb is created per grd per locale even if it has multiple grdp files.
module.exports.braveTopLevelPaths = module.exports.allBravePaths.filter((x) => ['grd', 'json'].includes(x.split('.').pop()))

// This simply reads Chromium files that are passed to it and replaces branding strings
// with Brave specific branding strings.
// Do not use this for filtering XML, instead use chromium-rebase-l10n.py.
// Only add idempotent replacements here (i.e. don't append replace A with AX here)
module.exports.rebaseBraveStringFilesOnChromiumL10nFiles = (path) =>
Object.entries({
[chromiumStringsPath]: braveStringsPath,
[chroimumSettingsPartPath]: braveSettingsPartPath,
[chromiumComponentsStringsPath]: braveComponentsStringsPath,
[chromiumGeneratedResourcesPath]: braveGeneratedResourcesPath,
[chromiumBookmarksPartPath]: braveBookmarksPartPath,
[chromiumMediaRouterPartPath]: braveMediaRouterPartPath,
[chromiumSettingsStringsPartPath]: braveSettingsStringsPartPath,
[chromiumMdExtensionsPartPath]: braveMdExtensionsPartPath,
[chromePrintingStringsPartPath]: bravePrintingStringsPartPath,
[chromiumExtensionsResourcesPath]: braveExtensionsResourcesPath,
[chromiumSettingsResourcesPath]: braveSettingsResourcesPath,
[chromiumBrowserResourcesPath]: braveBrowserResourcesPath
}).forEach(([sourcePath, destPath]) =>
Object.entries(chromiumToAutoGeneratedBraveMapping).forEach(([sourcePath, destPath]) =>
fs.writeFileSync(destPath,
fs.readFileSync(sourcePath, 'utf8')
.replace(/<\?xml version="1.0" encoding="utf-8"\?>/i, '<?xml version="1.0" encoding="utf-8"?>\n' + autoGeneratedWarning)
.replace('<structure name="IDR_MD_EXTENSIONS_SIDEBAR_HTML"', '<structure name="IDR_MD_EXTENSIONS_SIDEBAR_HTML" preprocess="true"')
.replace('<structure name="IDR_SETTINGS_APPEARANCE_FONTS_PAGE_HTML"', '<structure name="IDR_SETTINGS_APPEARANCE_FONTS_PAGE_HTML" preprocess="true"')
.replace('<structure name="IDR_SETTINGS_PASSWORDS_SECTION_HTML"', '<structure name="IDR_SETTINGS_PASSWORDS_SECTION_HTML" preprocess="true"')
.replace('<include name="IDR_MD_HISTORY_SIDE_BAR_HTML"', '<include name="IDR_MD_HISTORY_SIDE_BAR_HTML" flattenhtml="true"')
.replace(pageVisibility, bravePageVisibility + pageVisibility)
.replace(/settings_chromium_strings.grdp/g, 'settings_brave_strings.grdp')
.replace(/Automatically send usage statistics and crash reports to Google/g, 'Automatically send crash reports to Google')
.replace(/Automatically sends usage statistics and crash reports to Google/g, 'Automatically sends crash reports to Google')
.replace(/The Chromium Authors/g, 'Brave Software Inc')
Expand Down
4 changes: 2 additions & 2 deletions lib/pullL10n.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
const config = require('../lib/config')
const util = require('../lib/util')
const {getSourceStringPaths} = require('./l10nUtil')
const {braveTopLevelPaths} = require('./l10nUtil')

const pullL10n = (options) => {
getSourceStringPaths().forEach((sourceStringPath) => {
braveTopLevelPaths.forEach((sourceStringPath) => {
const cmdOptions = config.defaultOptions
cmdOptions.cwd = config.projects['brave-core'].dir
util.run('python', ['script/pull-l10n.py', '--source_string_path', sourceStringPath], cmdOptions)
Expand Down
6 changes: 3 additions & 3 deletions lib/pushL10n.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
const config = require('../lib/config')
const util = require('../lib/util')
const {getSourceStringPaths} = require('./l10nUtil')
const {braveTopLevelPaths} = require('./l10nUtil')

const pushL10n = (options) => {
// Get rid of local copied xtb and grd changes
const runOptions = { cwd: config.projects.chrome.dir }
let args = ['checkout', '--', '*.xtb']
util.run('git', args, runOptions)
args = ['checkout', '--', '*.grd']
args = ['checkout', '--', '*.grd*']
util.run('git', args, runOptions)

getSourceStringPaths().forEach((sourceStringPath) => {
braveTopLevelPaths.forEach((sourceStringPath) => {
const cmdOptions = config.defaultOptions
cmdOptions.cwd = config.projects['brave-core'].dir
util.run('python', ['script/push-l10n.py', '--source_string_path', sourceStringPath], cmdOptions)
Expand Down
33 changes: 17 additions & 16 deletions lib/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const path = require('path')
const spawnSync = require('child_process').spawnSync
const config = require('./config')
const fs = require('fs-extra')
const autoGeneratedBraveToChromiumMapping = Object.assign({}, require('./l10nUtil').autoGeneratedBraveToChromiumMapping)

const runGClient = (args, options = {}) => {
if (config.gClientVerbose) args.push('--verbose')
Expand Down Expand Up @@ -65,18 +66,22 @@ const util = {
const braveBrowserDir = path.join(config.projects['brave-core'].dir, 'browser')
const braveAppVectorIconsDir = path.join(config.projects['brave-core'].dir, 'vector_icons', 'chrome', 'app')

fs.copySync(path.join(braveAppDir, 'brave_strings.grd'), path.join(chromeAppDir, 'brave_strings.grd'))
fs.copySync(path.join(braveAppDir, 'settings_brave_strings.grdp'), path.join(chromeAppDir, 'settings_brave_strings.grdp'))
fs.copySync(path.join(braveAppDir, 'generated_resources.grd'), path.join(chromeAppDir, 'generated_resources.grd'))
fs.copySync(path.join(braveAppDir, 'bookmarks_strings.grdp'), path.join(chromeAppDir, 'bookmarks_strings.grdp'))
fs.copySync(path.join(braveAppDir, 'media_router_strings.grdp'), path.join(chromeAppDir, 'media_router_strings.grdp'))

fs.copySync(path.join(braveAppDir, 'settings_strings.grdp'), path.join(chromeAppDir, 'settings_strings.grdp'))
fs.copySync(path.join(braveAppDir, 'md_extensions_strings.grdp'), path.join(chromeAppDir, 'md_extensions_strings.grdp'))
fs.copySync(path.join(braveResourcesDir, 'md_extensions', 'extensions_resources.grd'), path.join(chromeResourcesDir, 'md_extensions', 'extensions_resources.grd'))
fs.copySync(path.join(braveResourcesDir, 'settings', 'settings_resources.grd'), path.join(chromeResourcesDir, 'settings', 'settings_resources.grd'))
fs.copySync(path.join(braveBrowserDir, 'browser_resources.grd'), path.join(chromeBrowserDir, 'browser_resources.grd'))
fs.copySync(path.join(braveAppDir, 'components_brave_strings.grd'), path.join(config.srcDir, 'components', 'components_brave_strings.grd'))
// The following 3 entries we map to the same name, not the chromium equivalent name for copying back
autoGeneratedBraveToChromiumMapping[path.join(braveAppDir, 'brave_strings.grd')] = path.join(chromeAppDir, 'brave_strings.grd')
autoGeneratedBraveToChromiumMapping[path.join(braveAppDir, 'settings_brave_strings.grdp')] = path.join(chromeAppDir, 'settings_brave_strings.grdp')
autoGeneratedBraveToChromiumMapping[path.join(braveAppDir, 'components_brave_strings.grd')] = path.join(config.srcDir, 'components', 'components_brave_strings.grd')

// Copy each grd back to Chromium src dir
Object.entries(autoGeneratedBraveToChromiumMapping).forEach(([bravePath, chromiumPath]) =>
fs.copySync(bravePath, chromiumPath))

// Copy xtb files for:
// brave/app/resources/chromium_strings*.xtb
// brave/app/strings/components_chromium_strings*.xtb
// brave/app/resources/generated_resoruces*.xtb
fs.copySync(path.join(braveAppDir, 'resources'), path.join(chromeAppDir, 'resources'))
fs.copySync(path.join(braveAppDir, 'strings'), path.join(chromeComponentsDir, 'strings'))

fs.copySync(path.join(braveAppDir, 'theme', 'brave'), path.join(chromeAppDir, 'theme', 'brave'))
fs.copySync(path.join(braveAppDir, 'theme', 'default_100_percent', 'brave'), path.join(chromeAppDir, 'theme', 'default_100_percent', 'brave'))
fs.copySync(path.join(braveAppDir, 'theme', 'default_200_percent', 'brave'), path.join(chromeAppDir, 'theme', 'default_200_percent', 'brave'))
Expand All @@ -87,10 +92,6 @@ const util = {
fs.copySync(path.join(braveComponentsDir, 'resources', 'default_100_percent', 'brave'), path.join(chromeComponentsDir, 'resources', 'default_100_percent', 'chromium'))
fs.copySync(path.join(braveComponentsDir, 'resources', 'default_200_percent', 'brave'), path.join(chromeComponentsDir, 'resources', 'default_200_percent', 'chromium'))
fs.copySync(path.join(braveAppVectorIconsDir, 'vector_icons', 'brave'), path.join(chromeAppDir, 'vector_icons', 'brave'))
// Copy XTB files for app/brave_strings.grd => chromium_strings.grd
fs.copySync(path.join(braveAppDir, 'resources'), path.join(chromeAppDir, 'resources'))
// Copy XTB files for brave/app/components_brave_strings.grd => components/components_chromium_strings.grd
fs.copySync(path.join(braveAppDir, 'strings'), path.join(chromeComponentsDir, 'strings'))
fs.copySync(path.join(braveResourcesDir, 'settings', 'brave_page_visibility.js'), path.join(chromeResourcesDir, 'settings', 'brave_page_visibility.js'))
},

Expand Down

0 comments on commit b99afd3

Please sign in to comment.