* Fix Windows build when enable_brave_vpn is false When VPN is disabled (e.g. Origin builds), copy chrome's resource allowlist instead of trying to merge with wireguard resources. * create_dist Origin fixes
527 lines
14 KiB
JavaScript
527 lines
14 KiB
JavaScript
// Copyright (c) 2025 The Brave Authors. All rights reserved.
|
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
|
|
const path = require('path')
|
|
const config = require('./config')
|
|
const fs = require('fs-extra')
|
|
const l10nUtil = require('./l10nUtil')
|
|
const util = require('./util')
|
|
const Log = require('./logging')
|
|
|
|
exports.update = () => {
|
|
Log.progressStart('update branding')
|
|
const chromeComponentsDir = path.join(config.srcDir, 'components')
|
|
const braveComponentsDir = path.join(config.braveCoreDir, 'components')
|
|
const chromeAppDir = path.join(config.srcDir, 'chrome', 'app')
|
|
const braveAppDir = path.join(config.braveCoreDir, 'app')
|
|
const braveChromiumResources = path.join(
|
|
config.braveCoreDir,
|
|
'build',
|
|
'chromium',
|
|
'resources',
|
|
)
|
|
const braveAppVectorIconsDir = path.join(config.braveCoreDir, 'components')
|
|
const chromeAndroidJavaStringsTranslationsDir = path.join(
|
|
config.srcDir,
|
|
'chrome',
|
|
'browser',
|
|
'ui',
|
|
'android',
|
|
'strings',
|
|
'translations',
|
|
)
|
|
const braveAndroidJavaStringsTranslationsDir = path.join(
|
|
config.braveCoreDir,
|
|
'browser',
|
|
'ui',
|
|
'android',
|
|
'strings',
|
|
'translations',
|
|
)
|
|
const chromeAndroidTabUiJavaStringsTranslationsDir = path.join(
|
|
config.srcDir,
|
|
'chrome',
|
|
'android',
|
|
'features',
|
|
'tab_ui',
|
|
'java',
|
|
'strings',
|
|
'translations',
|
|
)
|
|
const braveAndroidTabUiJavaStringsTranslationsDir = path.join(
|
|
config.braveCoreDir,
|
|
'android',
|
|
'features',
|
|
'tab_ui',
|
|
'java',
|
|
'strings',
|
|
'translations',
|
|
)
|
|
|
|
let fileMap = new Set()
|
|
const autoGeneratedBraveToChromiumMapping = Object.assign(
|
|
{},
|
|
l10nUtil.getAutoGeneratedBraveToChromiumMapping(),
|
|
)
|
|
// Map branded string files to chromium directories
|
|
for (const branding of ['brave', 'brave_origin']) {
|
|
autoGeneratedBraveToChromiumMapping[
|
|
path.join(braveAppDir, `${branding}_strings.grd`)
|
|
] = path.join(chromeAppDir, `${branding}_strings.grd`)
|
|
autoGeneratedBraveToChromiumMapping[
|
|
path.join(braveComponentsDir, `components_${branding}_strings.grd`)
|
|
] = path.join(chromeComponentsDir, `components_${branding}_strings.grd`)
|
|
}
|
|
// Shared grdp files (only need brave versions, brave_origin includes them)
|
|
autoGeneratedBraveToChromiumMapping[
|
|
path.join(braveAppDir, 'settings_brave_strings.grdp')
|
|
] = path.join(chromeAppDir, 'settings_brave_strings.grdp')
|
|
|
|
Object.entries(autoGeneratedBraveToChromiumMapping).forEach((mapping) =>
|
|
fileMap.add(mapping),
|
|
)
|
|
|
|
// Copy xtb files for:
|
|
// brave/app/resources/chromium_strings*.xtb
|
|
// brave/app/resources/generated_resoruces*.xtb
|
|
// brave/components/strings/components_chromium_strings*.xtb
|
|
// brave/browser/ui/android/strings/translations/android_chrome_strings*.xtb
|
|
// brave/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings*.xtb
|
|
fileMap.add([
|
|
path.join(braveAppDir, 'resources'),
|
|
path.join(chromeAppDir, 'resources'),
|
|
])
|
|
fileMap.add([
|
|
path.join(braveComponentsDir, 'strings'),
|
|
path.join(chromeComponentsDir, 'strings'),
|
|
])
|
|
fileMap.add([
|
|
braveAndroidJavaStringsTranslationsDir,
|
|
chromeAndroidJavaStringsTranslationsDir,
|
|
])
|
|
fileMap.add([
|
|
braveAndroidTabUiJavaStringsTranslationsDir,
|
|
chromeAndroidTabUiJavaStringsTranslationsDir,
|
|
])
|
|
// By overwriting, we don't need to modify some grd files.
|
|
for (const branding of ['brave', 'brave_origin']) {
|
|
fileMap.add([
|
|
path.join(braveAppDir, 'theme', branding),
|
|
path.join(chromeAppDir, 'theme', branding),
|
|
])
|
|
for (const scale of ['default_100_percent', 'default_200_percent']) {
|
|
fileMap.add([
|
|
path.join(braveAppDir, 'theme', scale, branding),
|
|
path.join(chromeAppDir, 'theme', scale, branding),
|
|
])
|
|
}
|
|
}
|
|
fileMap.add([path.join(braveChromiumResources), path.join(config.srcDir)])
|
|
// Copy product_logo for version UI (about:version page).
|
|
// product_logo_name_48.png is renamed to product_logo.png during copy.
|
|
// Use brave_origin logos when is_brave_origin_branded is true.
|
|
const productLogoSource = config.isBraveOriginBranded
|
|
? 'brave_origin'
|
|
: 'brave'
|
|
for (const scale of ['default_100_percent', 'default_200_percent']) {
|
|
fileMap.add([
|
|
path.join(
|
|
braveAppDir,
|
|
'theme',
|
|
scale,
|
|
productLogoSource,
|
|
'product_logo_name_48.png',
|
|
),
|
|
path.join(
|
|
chromeComponentsDir,
|
|
'resources',
|
|
scale,
|
|
'chromium',
|
|
'product_logo.png',
|
|
),
|
|
])
|
|
fileMap.add([
|
|
path.join(
|
|
braveAppDir,
|
|
'theme',
|
|
scale,
|
|
productLogoSource,
|
|
'product_logo_white.png',
|
|
),
|
|
path.join(
|
|
chromeComponentsDir,
|
|
'resources',
|
|
scale,
|
|
'chromium',
|
|
'product_logo_white.png',
|
|
),
|
|
])
|
|
}
|
|
for (const branding of ['brave', 'brave_origin']) {
|
|
fileMap.add([
|
|
path.join(braveAppVectorIconsDir, 'vector_icons', branding),
|
|
path.join(chromeComponentsDir, 'vector_icons', branding),
|
|
])
|
|
|
|
// Copy to make our ${branding_path_product}_behaviors.cc
|
|
fileMap.add([
|
|
path.join(
|
|
config.braveCoreDir,
|
|
'chromium_src',
|
|
'chrome',
|
|
'installer',
|
|
'setup',
|
|
`${branding}_behaviors.cc`,
|
|
),
|
|
path.join(
|
|
config.srcDir,
|
|
'chrome',
|
|
'installer',
|
|
'setup',
|
|
`${branding}_behaviors.cc`,
|
|
),
|
|
])
|
|
}
|
|
// Replace webui CSS to use our fonts.
|
|
fileMap.add([
|
|
path.join(
|
|
config.braveCoreDir,
|
|
'ui',
|
|
'webui',
|
|
'resources',
|
|
'css',
|
|
'text_defaults_md.css',
|
|
),
|
|
path.join(
|
|
config.srcDir,
|
|
'ui',
|
|
'webui',
|
|
'resources',
|
|
'css',
|
|
'text_defaults_md.css',
|
|
),
|
|
])
|
|
// Replace chrome dark logo with channel specific brave logo.
|
|
fileMap.add([
|
|
path.join(
|
|
config.braveCoreDir,
|
|
'node_modules',
|
|
'@brave',
|
|
'leo',
|
|
'icons',
|
|
config.getBraveLogoIconName(),
|
|
),
|
|
path.join(
|
|
config.srcDir,
|
|
'ui',
|
|
'webui',
|
|
'resources',
|
|
'images',
|
|
'chrome_logo_dark.svg',
|
|
),
|
|
])
|
|
// Replace webui bookmark svg icon.
|
|
fileMap.add([
|
|
path.join(
|
|
config.braveCoreDir,
|
|
'node_modules',
|
|
'@brave',
|
|
'leo',
|
|
'icons',
|
|
'browser-bookmark-normal.svg',
|
|
),
|
|
path.join(
|
|
config.srcDir,
|
|
'ui',
|
|
'webui',
|
|
'resources',
|
|
'images',
|
|
'icon_bookmark.svg',
|
|
),
|
|
])
|
|
|
|
let explicitSourceFiles = new Set()
|
|
if (config.targetOS === 'mac') {
|
|
// Set proper branding file name based on channel.
|
|
let brandingFileName = 'BRANDING'
|
|
if (config.channel) {
|
|
brandingFileName = brandingFileName + '.' + config.channel
|
|
}
|
|
|
|
for (const branding of ['brave', 'brave_origin']) {
|
|
// Set proper mac app icon for channel to chrome/app/theme/mac/app.icns.
|
|
// Each channel's app icons are stored in
|
|
// brave/app/theme/$channel/app.icns.
|
|
// With this copying, we don't need to modify chrome/BUILD.gn for this.
|
|
const iconSource = path.join(
|
|
braveAppDir,
|
|
'theme',
|
|
branding,
|
|
'mac',
|
|
config.channel,
|
|
'app.icns',
|
|
)
|
|
const iconDest = path.join(
|
|
chromeAppDir,
|
|
'theme',
|
|
branding,
|
|
'mac',
|
|
'app.icns',
|
|
)
|
|
explicitSourceFiles[iconDest] = iconSource
|
|
|
|
// Set proper mac app asset catalog for channel to
|
|
// chrome/app/theme/mac/Assets.car. Each channel's resource catalog is
|
|
// stored in brave/app/theme/$channel/Assets.car. With this copying, we
|
|
// don't need to modify chrome/BUILD.gn for this.
|
|
const assetCatalogSource = path.join(
|
|
braveAppDir,
|
|
'theme',
|
|
branding,
|
|
'mac',
|
|
config.channel,
|
|
'Assets.car',
|
|
)
|
|
const assetCatalogDest = path.join(
|
|
chromeAppDir,
|
|
'theme',
|
|
branding,
|
|
'mac',
|
|
'Assets.car',
|
|
)
|
|
explicitSourceFiles[assetCatalogDest] = assetCatalogSource
|
|
|
|
// Set proper branding file.
|
|
const brandingSource = path.join(
|
|
braveAppDir,
|
|
'theme',
|
|
branding,
|
|
brandingFileName,
|
|
)
|
|
const brandingDest = path.join(
|
|
chromeAppDir,
|
|
'theme',
|
|
branding,
|
|
'BRANDING',
|
|
)
|
|
explicitSourceFiles[brandingDest] = brandingSource
|
|
}
|
|
}
|
|
|
|
for (const [source, output] of fileMap) {
|
|
if (!fs.existsSync(source)) {
|
|
console.warn(
|
|
`Warning: The following file-system entry was not found for copying contents to a chromium destination: ${source}. Consider removing the entry from the file-map, or investigating whether the correct source code reference is checked out.`,
|
|
)
|
|
continue
|
|
}
|
|
|
|
let sourceFiles = []
|
|
|
|
// get all the files if source if a directory
|
|
if (fs.statSync(source).isDirectory()) {
|
|
sourceFiles = util.walkSync(source)
|
|
} else {
|
|
sourceFiles = [source]
|
|
}
|
|
|
|
for (let sourceFile of sourceFiles) {
|
|
if (path.basename(sourceFile) === 'README.md') {
|
|
continue
|
|
}
|
|
const destinationFile = path.join(
|
|
output,
|
|
path.relative(source, sourceFile),
|
|
)
|
|
sourceFile = explicitSourceFiles[destinationFile] || sourceFile
|
|
if (
|
|
!fs.existsSync(destinationFile)
|
|
|| util.calculateFileChecksum(sourceFile)
|
|
!== util.calculateFileChecksum(destinationFile)
|
|
) {
|
|
fs.copySync(sourceFile, destinationFile)
|
|
console.log(sourceFile + ' copied to ' + destinationFile)
|
|
}
|
|
}
|
|
}
|
|
|
|
if (config.targetOS === 'android') {
|
|
let braveOverwrittenFiles = new Set()
|
|
const removeUnlistedAndroidResources = (braveOverwrittenFiles) => {
|
|
const suspectedDir = path.join(
|
|
config.srcDir,
|
|
'chrome',
|
|
'android',
|
|
'java',
|
|
'res',
|
|
)
|
|
|
|
let untrackedChromiumFiles = util
|
|
.runGit(
|
|
suspectedDir,
|
|
['ls-files', '--others', '--exclude-standard'],
|
|
true,
|
|
)
|
|
.split('\n')
|
|
let untrackedChromiumPaths = []
|
|
for (const untrackedChromiumFile of untrackedChromiumFiles) {
|
|
untrackedChromiumPath = path.join(suspectedDir, untrackedChromiumFile)
|
|
|
|
if (!fs.statSync(untrackedChromiumPath).isDirectory()) {
|
|
untrackedChromiumPaths.push(untrackedChromiumPath)
|
|
}
|
|
}
|
|
|
|
const isChildOf = (child, parent) => {
|
|
const relative = path.relative(parent, child)
|
|
return (
|
|
relative && !relative.startsWith('..') && !path.isAbsolute(relative)
|
|
)
|
|
}
|
|
|
|
for (const untrackedChromiumPath of untrackedChromiumPaths) {
|
|
if (
|
|
isChildOf(untrackedChromiumPath, suspectedDir)
|
|
&& !braveOverwrittenFiles.has(untrackedChromiumPath)
|
|
) {
|
|
fs.removeSync(untrackedChromiumPath)
|
|
console.log(`Deleted not listed file: ${untrackedChromiumPath}`)
|
|
}
|
|
}
|
|
}
|
|
|
|
let androidIconSet = ''
|
|
if (config.channel === 'development') {
|
|
androidIconSet = 'res_brave_default'
|
|
} else if (config.channel === '') {
|
|
androidIconSet = 'res_brave'
|
|
} else if (config.channel === 'beta') {
|
|
androidIconSet = 'res_brave_beta'
|
|
} else if (config.channel === 'dev') {
|
|
androidIconSet = 'res_brave_dev'
|
|
} else if (config.channel === 'nightly') {
|
|
androidIconSet = 'res_brave_nightly'
|
|
}
|
|
|
|
const androidResSource = path.join(
|
|
config.braveCoreDir,
|
|
'android',
|
|
'java',
|
|
'res',
|
|
)
|
|
const androidResDest = path.join(
|
|
config.srcDir,
|
|
'chrome',
|
|
'android',
|
|
'java',
|
|
'res',
|
|
)
|
|
const androidFeaturesTabUiResSource = path.join(
|
|
config.braveCoreDir,
|
|
'android',
|
|
'features',
|
|
'tab_ui',
|
|
'java',
|
|
'res',
|
|
)
|
|
const androidFeaturesTabUiDest = path.join(
|
|
config.srcDir,
|
|
'chrome',
|
|
'android',
|
|
'features',
|
|
'tab_ui',
|
|
'java',
|
|
'res',
|
|
)
|
|
const androidDownloadInternalResSource = path.join(
|
|
config.braveCoreDir,
|
|
'browser',
|
|
'download',
|
|
'internal',
|
|
'android',
|
|
'java',
|
|
'res',
|
|
)
|
|
const androidDownloadInternalResDest = path.join(
|
|
config.srcDir,
|
|
'chrome',
|
|
'browser',
|
|
'download',
|
|
'internal',
|
|
'android',
|
|
'java',
|
|
'res',
|
|
)
|
|
const androidIconSource = path.join(
|
|
braveAppDir,
|
|
'theme',
|
|
'brave',
|
|
'android',
|
|
androidIconSet,
|
|
)
|
|
const androidIconDest = path.join(
|
|
config.srcDir,
|
|
'chrome',
|
|
'android',
|
|
'java',
|
|
'res_chromium',
|
|
)
|
|
const androidIconBaseSource = path.join(
|
|
braveAppDir,
|
|
'theme',
|
|
'brave',
|
|
'android',
|
|
androidIconSet + '_base',
|
|
)
|
|
const androidIconBaseDest = path.join(
|
|
config.srcDir,
|
|
'chrome',
|
|
'android',
|
|
'java',
|
|
'res_chromium_base',
|
|
)
|
|
|
|
// Mapping for copying Brave's Android resource into chromium folder.
|
|
const copyAndroidResourceMapping = {
|
|
[androidResSource]: [androidResDest],
|
|
[androidFeaturesTabUiResSource]: [androidFeaturesTabUiDest],
|
|
[androidDownloadInternalResSource]: [androidDownloadInternalResDest],
|
|
[androidIconSource]: [androidIconDest],
|
|
[androidIconBaseSource]: [androidIconBaseDest],
|
|
}
|
|
|
|
console.log('copy Android app icons and app resources')
|
|
Object.entries(copyAndroidResourceMapping).map(
|
|
([sourcePath, destPaths]) => {
|
|
let androidSourceFiles = []
|
|
if (fs.statSync(sourcePath).isDirectory()) {
|
|
androidSourceFiles = util.walkSync(sourcePath)
|
|
} else {
|
|
androidSourceFiles = [sourcePath]
|
|
}
|
|
|
|
for (const destPath of destPaths) {
|
|
for (const androidSourceFile of androidSourceFiles) {
|
|
let destinationFile = path.join(
|
|
destPath,
|
|
path.relative(sourcePath, androidSourceFile),
|
|
)
|
|
if (
|
|
!fs.existsSync(destinationFile)
|
|
|| util.calculateFileChecksum(androidSourceFile)
|
|
!== util.calculateFileChecksum(destinationFile)
|
|
) {
|
|
fs.copySync(androidSourceFile, destinationFile)
|
|
}
|
|
braveOverwrittenFiles.add(destinationFile)
|
|
}
|
|
}
|
|
},
|
|
)
|
|
removeUnlistedAndroidResources(braveOverwrittenFiles)
|
|
}
|
|
Log.progressFinish('update branding')
|
|
}
|