From ac51cfb497c660fb9d5bce0c792c0fce00d78bdb Mon Sep 17 00:00:00 2001 From: "Brian R. Bondy" Date: Fri, 7 Sep 2018 22:50:02 -0400 Subject: [PATCH] Merge pull request #990 from brave/theme-copy only copy theme resources when they actually change --- lib/build.js | 31 ++---------- lib/createDist.js | 5 +- lib/util.js | 119 +++++++++++++++++++++++++++++++++++--------- scripts/commands.js | 2 - 4 files changed, 100 insertions(+), 57 deletions(-) diff --git a/lib/build.js b/lib/build.js index 190b37608638..9640f5eab9bf 100644 --- a/lib/build.js +++ b/lib/build.js @@ -18,19 +18,8 @@ const touchOverriddenFiles = () => { return true } - const walkSync = (dir, filelist = []) => { - fs.readdirSync(dir).forEach(file => { - if (fs.statSync(path.join(dir, file)).isDirectory()) { - filelist = walkSync(path.join(dir, file), filelist) - } else if (applyFileFilter(file)) { - filelist = filelist.concat(path.join(dir, file)) - } - }) - return filelist - } - const chromiumSrcDir = path.join(config.srcDir, 'brave', 'chromium_src') - var sourceFiles = walkSync(chromiumSrcDir) + var sourceFiles = util.walkSync(chromiumSrcDir, applyFileFilter) // Touch original files by updating mtime. const chromiumSrcDirLen = chromiumSrcDir.length @@ -63,19 +52,8 @@ const touchOverriddenVectorIconFiles = () => { return true } - const walkSync = (dir, filelist = []) => { - fs.readdirSync(dir).forEach(file => { - if (fs.statSync(path.join(dir, file)).isDirectory()) { - filelist = walkSync(path.join(dir, file), filelist) - } else if (applyFileFilter(file)) { - filelist = filelist.concat(path.join(dir, file)) - } - }) - return filelist - } - const braveVectorIconsDir = path.join(config.srcDir, 'brave', 'vector_icons') - var braveVectorIconFiles = walkSync(braveVectorIconsDir) + var braveVectorIconFiles = util.walkSync(braveVectorIconsDir, applyFileFilter) // Touch original files by updating mtime. const braveVectorIconsDirLen = braveVectorIconsDir.length @@ -116,10 +94,7 @@ const build = (buildConfig = config.defaultBuildConfig, options) => { touchOverriddenFiles() touchOverriddenVectorIconFiles() - - if (!options.no_branding_update) { - util.updateBranding() - } + util.updateBranding() util.buildTarget() } diff --git a/lib/createDist.js b/lib/createDist.js index 79ce622d2645..6fd8d81ce918 100644 --- a/lib/createDist.js +++ b/lib/createDist.js @@ -7,10 +7,7 @@ const createDist = (buildConfig = config.defaultBuildConfig, options) => { config.buildConfig = buildConfig config.update(options) - if (!options.no_branding_update) { - util.updateBranding() - } - + util.updateBranding() fs.removeSync(path.join(config.outputDir, 'dist')) config.buildTarget = 'create_dist' util.buildTarget() diff --git a/lib/util.js b/lib/util.js index c82a0b7d7f8f..6e2abfc9d5fe 100644 --- a/lib/util.js +++ b/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 crypto = require('crypto') const autoGeneratedBraveToChromiumMapping = Object.assign({}, require('./l10nUtil').autoGeneratedBraveToChromiumMapping) const runGClient = (args, options = {}) => { @@ -54,6 +55,26 @@ const util = { fs.writeFileSync(config.defaultGClientFile, out) }, + calculateFileChecksum: (filename) => { + // adapted from https://github.com/roryrjb/md5-file + const BUFFER_SIZE = 8192 + const fd = fs.openSync(filename, 'r') + const buffer = Buffer.alloc(BUFFER_SIZE) + const md5 = crypto.createHash('md5') + + try { + let bytesRead + do { + bytesRead = fs.readSync(fd, buffer, 0, BUFFER_SIZE) + md5.update(buffer.slice(0, bytesRead)) + } while (bytesRead === BUFFER_SIZE) + } finally { + fs.closeSync(fd) + } + + return md5.digest('hex') + }, + updateBranding: () => { console.log('update branding...') const chromeComponentsDir = path.join(config.srcDir, 'components') @@ -66,47 +87,88 @@ 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') - // 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') + let fileMap = {} + fileMap[path.join(braveAppDir, 'brave_strings.grd')] = path.join(chromeAppDir, 'brave_strings.grd') + fileMap[path.join(braveAppDir, 'settings_brave_strings.grdp')] = path.join(chromeAppDir, 'settings_brave_strings.grdp') + fileMap[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')) + fileMap[path.join(braveAppDir, 'resources')] = path.join(chromeAppDir, 'resources') + fileMap[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')) + fileMap[path.join(braveAppDir, 'theme', 'brave')] = path.join(chromeAppDir, 'theme', 'brave') + fileMap[path.join(braveAppDir, 'theme', 'default_100_percent', 'brave')] = path.join(chromeAppDir, 'theme', 'default_100_percent', 'brave') + fileMap[path.join(braveAppDir, 'theme', 'default_200_percent', 'brave')] = path.join(chromeAppDir, 'theme', 'default_200_percent', 'brave') // By overwriting, we don't need to modify some grd files. - fs.copySync(path.join(braveAppDir, 'theme', 'brave'), path.join(chromeAppDir, 'theme', 'chromium')) - fs.copySync(path.join(braveAppDir, 'theme', 'default_100_percent', 'brave'), path.join(chromeAppDir, 'theme', 'default_100_percent', 'chromium')) - fs.copySync(path.join(braveAppDir, 'theme', 'default_200_percent', 'brave'), path.join(chromeAppDir, 'theme', 'default_200_percent', 'chromium')) - 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')) - fs.copySync(path.join(braveResourcesDir, 'settings', 'brave_page_visibility.js'), path.join(chromeResourcesDir, 'settings', 'brave_page_visibility.js')) - fs.copySync(path.join(braveResourcesDir, 'settings', 'brave_appearance_page'), path.join(chromeResourcesDir, 'settings', 'brave_appearance_page')) + fileMap[path.join(braveAppDir, 'theme', 'brave')] = path.join(chromeAppDir, 'theme', 'chromium') + fileMap[path.join(braveAppDir, 'theme', 'default_100_percent', 'brave')] = path.join(chromeAppDir, 'theme', 'default_100_percent', 'chromium') + fileMap[path.join(braveAppDir, 'theme', 'default_200_percent', 'brave')] = path.join(chromeAppDir, 'theme', 'default_200_percent', 'chromium') + fileMap[path.join(braveComponentsDir, 'resources', 'default_100_percent', 'brave')] = path.join(chromeComponentsDir, 'resources', 'default_100_percent', 'chromium') + fileMap[path.join(braveComponentsDir, 'resources', 'default_200_percent', 'brave')] = path.join(chromeComponentsDir, 'resources', 'default_200_percent', 'chromium') + fileMap[path.join(braveAppVectorIconsDir, 'vector_icons', 'brave')] = path.join(chromeAppDir, 'vector_icons', 'brave') + fileMap[path.join(braveResourcesDir, 'settings', 'brave_page_visibility.js')] = path.join(chromeResourcesDir, 'settings', 'brave_page_visibility.js') + fileMap[path.join(braveResourcesDir, 'settings', 'brave_appearance_page')] = path.join(chromeResourcesDir, 'settings', 'brave_appearance_page') if (process.platform === 'darwin') { // Copy 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. - fs.copySync(path.join(braveAppDir, 'theme', 'brave', 'mac', config.channel, 'app.icns'), - path.join(chromeAppDir, 'theme', 'brave', 'mac', 'app.icns')) + const iconSource = path.join(braveAppDir, 'theme', 'brave', 'mac', config.channel, 'app.icns') + const iconDest = path.join(chromeAppDir, 'theme', 'brave', 'mac', 'app.icns') + if (util.calculateFileChecksum(iconSource) != util.calculateFileChecksum(iconDest)) { + console.log('copy app icon') + fs.copySync(iconSource, iconDest) + } // Copy branding file let branding_file_name = 'BRANDING' if (config.channel) branding_file_name = branding_file_name + '.' + config.channel - fs.copySync(path.join(braveAppDir, 'theme', 'brave', branding_file_name), path.join(chromeAppDir, 'theme', 'brave', 'BRANDING')) + + const brandingSource = path.join(braveAppDir, 'theme', 'brave', branding_file_name) + const brandingDest = path.join(chromeAppDir, 'theme', 'brave', 'BRANDING') + if (util.calculateFileChecksum(brandingSource) != util.calculateFileChecksum(brandingDest)) { + console.log('copy branding file') + fs.copySync(brandingSource, brandingDest) + } + } + + for (source in fileMap) { + let sourceFiles = [] + const output = fileMap[source] + + // get all the files if source if a directory + if (fs.statSync(source).isDirectory()) { + sourceFiles = util.walkSync(source) + } else { + sourceFiles = [source] + } + + for (var i in sourceFiles) { + const sourceFile = sourceFiles[i] + let destinationFile = output + if (fs.statSync(destinationFile).isDirectory()) { + destinationFile = path.join(destinationFile, path.basename(sourceFile)) + } + + // The destination file might be newer when updating chromium so + // we check for an exact match on the timestamp. We use seconds instead + // of ms because utimesSync doesn't set the times with ms precision + if (!fs.existsSync(destinationFile) || + Math.floor(new Date(fs.statSync(sourceFile).mtimeMs).getTime() / 1000) != + Math.floor(new Date(fs.statSync(destinationFile).mtimeMs).getTime() / 1000)) { + fs.copySync(sourceFile, destinationFile) + // can't set the date in the past so update the source file + // to match the newly copied destionation file + const date = fs.statSync(destinationFile).mtime + fs.utimesSync(sourceFile, date, date) + console.log(sourceFile + ' copied to ' + destinationFile) + } + } } }, @@ -179,6 +241,17 @@ const util = { args += arg + '=' + val + ' ' } return args.replace(/"/g,'\\"') + }, + + walkSync: (dir, filter = null, filelist = []) => { + fs.readdirSync(dir).forEach(file => { + if (fs.statSync(path.join(dir, file)).isDirectory()) { + filelist = util.walkSync(path.join(dir, file), filter, filelist) + } else if (!filter || filter.call(null, file)) { + filelist = filelist.concat(path.join(dir, file)) + } + }) + return filelist } } diff --git a/scripts/commands.js b/scripts/commands.js index e5ffd1c8a729..401f0aed64f8 100644 --- a/scripts/commands.js +++ b/scripts/commands.js @@ -35,7 +35,6 @@ program .option('--official_build ', 'force official build settings') .option('--brave_google_api_key ') .option('--brave_google_api_endpoint ') - .option('--no_branding_update', 'don\'t copy BRANDING to the chrome theme dir') .option('--channel ', 'target channel to build', /^(beta|dev|nightly|release)$/i, 'release') .arguments('[build_config]') .action(build) @@ -50,7 +49,6 @@ program .option('--official_build ', 'force official build settings') .option('--brave_google_api_key ') .option('--brave_google_api_endpoint ') - .option('--no_branding_update', 'don\'t copy BRANDING to the chrome theme dir') .option('--channel ', 'target channel to build', /^(beta|dev|nightly|release)$/i, 'release') .arguments('[build_config]') .action(createDist)