From 70a321634c84de99ceed977592f020169cbd2e5a Mon Sep 17 00:00:00 2001 From: David Sanders Date: Sat, 11 Apr 2026 00:46:52 -0700 Subject: [PATCH] build: don't use //third_party/depot_tools in gn build scripts (#50922) build: don't use //third_party/depot_tools in gn build scripts (#50858) --- script/gn-check.js | 9 +++---- script/lib/util.py | 40 +++++++++++++++++++++++++------ script/lib/utils.js | 48 +++++++++++++++++++++++++++++++++++++ script/run-clang-tidy.ts | 51 +--------------------------------------- script/run-gn-format.py | 7 +++--- 5 files changed, 88 insertions(+), 67 deletions(-) diff --git a/script/gn-check.js b/script/gn-check.js index 13776019a6..c984f6b4dc 100644 --- a/script/gn-check.js +++ b/script/gn-check.js @@ -11,10 +11,9 @@ const path = require('node:path'); const args = minimist(process.argv.slice(2), { string: ['outDir'] }); -const { getOutDir } = require('./lib/utils'); +const { getDepotToolsEnv, getOutDir } = require('./lib/utils'); const SOURCE_ROOT = path.normalize(path.dirname(__dirname)); -const DEPOT_TOOLS = path.resolve(SOURCE_ROOT, '..', 'third_party', 'depot_tools'); const OUT_DIR = getOutDir({ outDir: args.outDir }); if (!OUT_DIR) { @@ -22,12 +21,10 @@ if (!OUT_DIR) { } const env = { + ...getDepotToolsEnv(), CHROMIUM_BUILDTOOLS_PATH: path.resolve(SOURCE_ROOT, '..', 'buildtools'), - DEPOT_TOOLS_WIN_TOOLCHAIN: '0', - ...process.env + DEPOT_TOOLS_WIN_TOOLCHAIN: '0' }; -// Users may not have depot_tools in PATH. -env.PATH = `${env.PATH}${path.delimiter}${DEPOT_TOOLS}`; const gnCheckDirs = [ '//electron:electron_lib', diff --git a/script/lib/util.py b/script/lib/util.py index 040a144c44..d073bdbedd 100644 --- a/script/lib/util.py +++ b/script/lib/util.py @@ -205,11 +205,37 @@ def get_buildtools_executable(name): path += '.exe' return path -def get_depot_tools_executable(name): - buildtools = os.path.realpath( - os.path.join(ELECTRON_DIR, '..', 'third_party', 'depot_tools')) +def get_depot_tools_env(): + def find_depot_tools_on_path(): + cmd = 'where' if sys.platform == 'win32' else 'which' + try: + subprocess.check_call([cmd, 'gclient']) + return os.environ.copy() + except subprocess.CalledProcessError: + return None - path = os.path.join(buildtools, name) - if sys.platform == 'win32': - path += '.bat' - return path + def check_for_build_tools(): + try: + output = subprocess.check_output( + 'electron-build-tools show env --json', + shell=True, stderr=subprocess.DEVNULL + ) + env = os.environ.copy() + env.update(json.loads(output.decode().strip())) + return env + except subprocess.CalledProcessError: + return None + + depot_tools_env = check_for_build_tools() + if depot_tools_env is None: + depot_tools_env = find_depot_tools_on_path() + + if depot_tools_env is None: + raise RuntimeError("Couldn't find depot_tools, ensure it's on your PATH") + + if 'CHROMIUM_BUILDTOOLS_PATH' not in depot_tools_env: + raise RuntimeError( + 'CHROMIUM_BUILDTOOLS_PATH environment variable must be set' + ) + + return depot_tools_env diff --git a/script/lib/utils.js b/script/lib/utils.js index 7e469dc9d0..894854b776 100644 --- a/script/lib/utils.js +++ b/script/lib/utils.js @@ -162,11 +162,59 @@ function compareVersions (v1, v2) { return 0; } +function getDepotToolsEnv () { + let depotToolsEnv; + + const findDepotToolsOnPath = () => { + const result = childProcess.spawnSync( + os.platform() === 'win32' ? 'where' : 'which', + ['gclient'] + ); + + if (result.status === 0) { + return process.env; + } + }; + + const checkForBuildTools = () => { + const result = childProcess.spawnSync( + 'electron-build-tools', + ['show', 'env', '--json'], + { shell: true } + ); + + if (result.status === 0) { + return { + ...process.env, + ...JSON.parse(result.stdout.toString().trim()) + }; + } + }; + + try { + depotToolsEnv = checkForBuildTools(); + if (!depotToolsEnv) depotToolsEnv = findDepotToolsOnPath(); + } catch {} + + if (!depotToolsEnv) { + throw new Error("Couldn't find depot_tools, ensure it's on your PATH"); + } + + if (!('CHROMIUM_BUILDTOOLS_PATH' in depotToolsEnv)) { + throw new Error( + 'CHROMIUM_BUILDTOOLS_PATH environment variable must be set' + ); + } + + return depotToolsEnv; +} + module.exports = { chunkFilenames, compareVersions, findMatchingFiles, getCurrentBranch, + getDepotToolsEnv, getElectronExec, getOutDir, getAbsoluteElectronExec, diff --git a/script/run-clang-tidy.ts b/script/run-clang-tidy.ts index ab3ad9efe8..6bbb345dca 100644 --- a/script/run-clang-tidy.ts +++ b/script/run-clang-tidy.ts @@ -6,10 +6,9 @@ import { streamArray as streamJsonStreamArray } from 'stream-json/streamers/Stre import * as childProcess from 'node:child_process'; import * as fs from 'node:fs'; -import * as os from 'node:os'; import * as path from 'node:path'; -import { chunkFilenames, findMatchingFiles } from './lib/utils'; +import { chunkFilenames, findMatchingFiles, getDepotToolsEnv } from './lib/utils'; const SOURCE_ROOT = path.normalize(path.dirname(__dirname)); const LLVM_BIN = path.resolve( @@ -20,7 +19,6 @@ const LLVM_BIN = path.resolve( 'Release+Asserts', 'bin' ); -const PLATFORM = os.platform(); type SpawnAsyncResult = { stdout: string; @@ -63,53 +61,6 @@ async function spawnAsync ( }); } -function getDepotToolsEnv (): NodeJS.ProcessEnv { - let depotToolsEnv; - - const findDepotToolsOnPath = () => { - const result = childProcess.spawnSync( - PLATFORM === 'win32' ? 'where' : 'which', - ['gclient'] - ); - - if (result.status === 0) { - return process.env; - } - }; - - const checkForBuildTools = () => { - const result = childProcess.spawnSync( - 'electron-build-tools', - ['show', 'env', '--json'], - { shell: true } - ); - - if (result.status === 0) { - return { - ...process.env, - ...JSON.parse(result.stdout.toString().trim()) - }; - } - }; - - try { - depotToolsEnv = findDepotToolsOnPath(); - if (!depotToolsEnv) depotToolsEnv = checkForBuildTools(); - } catch {} - - if (!depotToolsEnv) { - throw new Error("Couldn't find depot_tools, ensure it's on your PATH"); - } - - if (!('CHROMIUM_BUILDTOOLS_PATH' in depotToolsEnv)) { - throw new Error( - 'CHROMIUM_BUILDTOOLS_PATH environment variable must be set' - ); - } - - return depotToolsEnv; -} - async function runClangTidy ( outDir: string, filenames: string[], diff --git a/script/run-gn-format.py b/script/run-gn-format.py index 1a8a2ebc16..9f16d6946c 100644 --- a/script/run-gn-format.py +++ b/script/run-gn-format.py @@ -2,23 +2,22 @@ import os import subprocess import sys -from lib.util import get_depot_tools_executable +from lib.util import get_depot_tools_env SOURCE_ROOT = os.path.dirname(os.path.dirname(__file__)) # Helper to run gn format on multiple files # (gn only formats a single file at a time) def main(): - new_env = os.environ.copy() + new_env = get_depot_tools_env() new_env['DEPOT_TOOLS_WIN_TOOLCHAIN'] = '0' new_env['CHROMIUM_BUILDTOOLS_PATH'] = os.path.realpath( os.path.join(SOURCE_ROOT, '..', 'buildtools') ) - gn_path = get_depot_tools_executable('gn') for gn_file in sys.argv[1:]: subprocess.check_call( - [gn_path, 'format', gn_file], + ['gn', 'format', gn_file], env=new_env )