diff --git a/build/commands/lib/chromiumRebaseL10n.js b/build/commands/lib/chromiumRebaseL10n.js index 50f1ff3169ea..bc3e0a5b2c9f 100644 --- a/build/commands/lib/chromiumRebaseL10n.js +++ b/build/commands/lib/chromiumRebaseL10n.js @@ -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 diff --git a/build/commands/lib/l10nUtil.js b/build/commands/lib/l10nUtil.js index 72b05a05b312..45b3e9fc324e 100644 --- a/build/commands/lib/l10nUtil.js +++ b/build/commands/lib/l10nUtil.js @@ -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 = '' - -const pageVisibility = ' \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, '\n' + autoGeneratedWarning) - .replace(' { - 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) diff --git a/build/commands/lib/pushL10n.js b/build/commands/lib/pushL10n.js index 67b6a1b6f9de..6c573c81de8f 100644 --- a/build/commands/lib/pushL10n.js +++ b/build/commands/lib/pushL10n.js @@ -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) diff --git a/build/commands/lib/util.js b/build/commands/lib/util.js index 8a660bc94cca..563d4318c1a3 100644 --- a/build/commands/lib/util.js +++ b/build/commands/lib/util.js @@ -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') @@ -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')) @@ -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')) },