1*8975f5c5SAndroid Build Coastguard Worker#!/usr/bin/env python3 2*8975f5c5SAndroid Build Coastguard Worker# Copyright 2019 The ANGLE project authors. All Rights Reserved. 3*8975f5c5SAndroid Build Coastguard Worker# 4*8975f5c5SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license 5*8975f5c5SAndroid Build Coastguard Worker# that can be found in the LICENSE file in the root of the source 6*8975f5c5SAndroid Build Coastguard Worker# tree. An additional intellectual property rights grant can be found 7*8975f5c5SAndroid Build Coastguard Worker# in the file PATENTS. All contributing project authors may 8*8975f5c5SAndroid Build Coastguard Worker# be found in the AUTHORS file in the root of the source tree. 9*8975f5c5SAndroid Build Coastguard Worker 10*8975f5c5SAndroid Build Coastguard Worker# This is a modified copy of the script in 11*8975f5c5SAndroid Build Coastguard Worker# https://webrtc.googlesource.com/src/+/main/tools_webrtc/autoroller/roll_deps.py 12*8975f5c5SAndroid Build Coastguard Worker# customized for ANGLE. 13*8975f5c5SAndroid Build Coastguard Worker"""Script to automatically roll Chromium dependencies in the ANGLE DEPS file.""" 14*8975f5c5SAndroid Build Coastguard Worker 15*8975f5c5SAndroid Build Coastguard Workerimport argparse 16*8975f5c5SAndroid Build Coastguard Workerimport base64 17*8975f5c5SAndroid Build Coastguard Workerimport collections 18*8975f5c5SAndroid Build Coastguard Workerimport logging 19*8975f5c5SAndroid Build Coastguard Workerimport os 20*8975f5c5SAndroid Build Coastguard Workerimport platform 21*8975f5c5SAndroid Build Coastguard Workerimport re 22*8975f5c5SAndroid Build Coastguard Workerimport subprocess 23*8975f5c5SAndroid Build Coastguard Workerimport sys 24*8975f5c5SAndroid Build Coastguard Workerimport urllib.request 25*8975f5c5SAndroid Build Coastguard Worker 26*8975f5c5SAndroid Build Coastguard Worker 27*8975f5c5SAndroid Build Coastguard Workerdef FindSrcDirPath(): 28*8975f5c5SAndroid Build Coastguard Worker """Returns the abs path to the root dir of the project.""" 29*8975f5c5SAndroid Build Coastguard Worker # Special cased for ANGLE. 30*8975f5c5SAndroid Build Coastguard Worker return os.path.dirname(os.path.abspath(os.path.join(__file__, '..'))) 31*8975f5c5SAndroid Build Coastguard Worker 32*8975f5c5SAndroid Build Coastguard WorkerANGLE_CHROMIUM_DEPS = [ 33*8975f5c5SAndroid Build Coastguard Worker 'build', 34*8975f5c5SAndroid Build Coastguard Worker 'buildtools', 35*8975f5c5SAndroid Build Coastguard Worker 'buildtools/linux64', 36*8975f5c5SAndroid Build Coastguard Worker 'buildtools/mac', 37*8975f5c5SAndroid Build Coastguard Worker 'buildtools/reclient', 38*8975f5c5SAndroid Build Coastguard Worker 'buildtools/win', 39*8975f5c5SAndroid Build Coastguard Worker 'testing', 40*8975f5c5SAndroid Build Coastguard Worker 'third_party/abseil-cpp', 41*8975f5c5SAndroid Build Coastguard Worker 'third_party/android_build_tools', 42*8975f5c5SAndroid Build Coastguard Worker 'third_party/android_build_tools/aapt2/cipd', 43*8975f5c5SAndroid Build Coastguard Worker 'third_party/android_build_tools/art', 44*8975f5c5SAndroid Build Coastguard Worker 'third_party/android_build_tools/bundletool', 45*8975f5c5SAndroid Build Coastguard Worker 'third_party/android_build_tools/error_prone/cipd', 46*8975f5c5SAndroid Build Coastguard Worker 'third_party/android_build_tools/error_prone_javac/cipd', 47*8975f5c5SAndroid Build Coastguard Worker 'third_party/android_build_tools/lint/cipd', 48*8975f5c5SAndroid Build Coastguard Worker 'third_party/android_build_tools/manifest_merger/cipd', 49*8975f5c5SAndroid Build Coastguard Worker 'third_party/android_deps', 50*8975f5c5SAndroid Build Coastguard Worker 'third_party/android_platform', 51*8975f5c5SAndroid Build Coastguard Worker 'third_party/android_sdk', 52*8975f5c5SAndroid Build Coastguard Worker 'third_party/android_sdk/public', 53*8975f5c5SAndroid Build Coastguard Worker 'third_party/android_system_sdk/cipd', 54*8975f5c5SAndroid Build Coastguard Worker 'third_party/android_toolchain/ndk', 55*8975f5c5SAndroid Build Coastguard Worker 'third_party/bazel', 56*8975f5c5SAndroid Build Coastguard Worker 'third_party/catapult', 57*8975f5c5SAndroid Build Coastguard Worker 'third_party/clang-format/script', 58*8975f5c5SAndroid Build Coastguard Worker 'third_party/colorama/src', 59*8975f5c5SAndroid Build Coastguard Worker 'third_party/cpu_features/src', 60*8975f5c5SAndroid Build Coastguard Worker 'third_party/depot_tools', 61*8975f5c5SAndroid Build Coastguard Worker 'third_party/flatbuffers/src', 62*8975f5c5SAndroid Build Coastguard Worker 'third_party/fuchsia-sdk/sdk', 63*8975f5c5SAndroid Build Coastguard Worker 'third_party/ijar', 64*8975f5c5SAndroid Build Coastguard Worker 'third_party/jdk', 65*8975f5c5SAndroid Build Coastguard Worker 'third_party/jdk/extras', 66*8975f5c5SAndroid Build Coastguard Worker 'third_party/jinja2', 67*8975f5c5SAndroid Build Coastguard Worker 'third_party/kotlin_stdlib', 68*8975f5c5SAndroid Build Coastguard Worker 'third_party/libc++/src', 69*8975f5c5SAndroid Build Coastguard Worker 'third_party/libc++abi/src', 70*8975f5c5SAndroid Build Coastguard Worker 'third_party/libdrm/src', 71*8975f5c5SAndroid Build Coastguard Worker 'third_party/libjpeg_turbo', 72*8975f5c5SAndroid Build Coastguard Worker 'third_party/libunwind/src', 73*8975f5c5SAndroid Build Coastguard Worker 'third_party/llvm-libc/src', 74*8975f5c5SAndroid Build Coastguard Worker 'third_party/markupsafe', 75*8975f5c5SAndroid Build Coastguard Worker 'third_party/nasm', 76*8975f5c5SAndroid Build Coastguard Worker 'third_party/ninja', 77*8975f5c5SAndroid Build Coastguard Worker 'third_party/proguard', 78*8975f5c5SAndroid Build Coastguard Worker 'third_party/protobuf', 79*8975f5c5SAndroid Build Coastguard Worker 'third_party/Python-Markdown', 80*8975f5c5SAndroid Build Coastguard Worker 'third_party/qemu-linux-x64', 81*8975f5c5SAndroid Build Coastguard Worker 'third_party/qemu-mac-x64', 82*8975f5c5SAndroid Build Coastguard Worker 'third_party/r8/cipd', 83*8975f5c5SAndroid Build Coastguard Worker 'third_party/r8/d8/cipd', 84*8975f5c5SAndroid Build Coastguard Worker 'third_party/requests/src', 85*8975f5c5SAndroid Build Coastguard Worker 'third_party/rust', 86*8975f5c5SAndroid Build Coastguard Worker 'third_party/siso/cipd', 87*8975f5c5SAndroid Build Coastguard Worker 'third_party/six', 88*8975f5c5SAndroid Build Coastguard Worker 'third_party/turbine/cipd', 89*8975f5c5SAndroid Build Coastguard Worker 'third_party/zlib', 90*8975f5c5SAndroid Build Coastguard Worker 'tools/android', 91*8975f5c5SAndroid Build Coastguard Worker 'tools/clang', 92*8975f5c5SAndroid Build Coastguard Worker 'tools/clang/dsymutil', 93*8975f5c5SAndroid Build Coastguard Worker 'tools/luci-go', 94*8975f5c5SAndroid Build Coastguard Worker 'tools/mb', 95*8975f5c5SAndroid Build Coastguard Worker 'tools/md_browser', 96*8975f5c5SAndroid Build Coastguard Worker 'tools/memory', 97*8975f5c5SAndroid Build Coastguard Worker 'tools/perf', 98*8975f5c5SAndroid Build Coastguard Worker 'tools/protoc_wrapper', 99*8975f5c5SAndroid Build Coastguard Worker 'tools/python', 100*8975f5c5SAndroid Build Coastguard Worker 'tools/rust', 101*8975f5c5SAndroid Build Coastguard Worker 'tools/skia_goldctl/linux', 102*8975f5c5SAndroid Build Coastguard Worker 'tools/skia_goldctl/mac_amd64', 103*8975f5c5SAndroid Build Coastguard Worker 'tools/skia_goldctl/mac_arm64', 104*8975f5c5SAndroid Build Coastguard Worker 'tools/skia_goldctl/win', 105*8975f5c5SAndroid Build Coastguard Worker 'tools/valgrind', 106*8975f5c5SAndroid Build Coastguard Worker] 107*8975f5c5SAndroid Build Coastguard Worker 108*8975f5c5SAndroid Build Coastguard WorkerANGLE_URL = 'https://chromium.googlesource.com/angle/angle' 109*8975f5c5SAndroid Build Coastguard WorkerCHROMIUM_SRC_URL = 'https://chromium.googlesource.com/chromium/src' 110*8975f5c5SAndroid Build Coastguard WorkerCHROMIUM_COMMIT_TEMPLATE = CHROMIUM_SRC_URL + '/+/%s' 111*8975f5c5SAndroid Build Coastguard WorkerCHROMIUM_LOG_TEMPLATE = CHROMIUM_SRC_URL + '/+log/%s' 112*8975f5c5SAndroid Build Coastguard WorkerCHROMIUM_FILE_TEMPLATE = CHROMIUM_SRC_URL + '/+/%s/%s' 113*8975f5c5SAndroid Build Coastguard Worker 114*8975f5c5SAndroid Build Coastguard WorkerCOMMIT_POSITION_RE = re.compile('^Cr-Commit-Position: .*#([0-9]+).*$') 115*8975f5c5SAndroid Build Coastguard WorkerCLANG_REVISION_RE = re.compile(r'^CLANG_REVISION = \'([-0-9a-z]+)\'') 116*8975f5c5SAndroid Build Coastguard WorkerROLL_BRANCH_NAME = 'roll_chromium_revision' 117*8975f5c5SAndroid Build Coastguard Worker 118*8975f5c5SAndroid Build Coastguard WorkerSCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) 119*8975f5c5SAndroid Build Coastguard WorkerCHECKOUT_SRC_DIR = FindSrcDirPath() 120*8975f5c5SAndroid Build Coastguard WorkerCHECKOUT_ROOT_DIR = CHECKOUT_SRC_DIR 121*8975f5c5SAndroid Build Coastguard Worker 122*8975f5c5SAndroid Build Coastguard Worker# Copied from tools/android/roll/android_deps/.../BuildConfigGenerator.groovy. 123*8975f5c5SAndroid Build Coastguard WorkerANDROID_DEPS_START = r'=== ANDROID_DEPS Generated Code Start ===' 124*8975f5c5SAndroid Build Coastguard WorkerANDROID_DEPS_END = r'=== ANDROID_DEPS Generated Code End ===' 125*8975f5c5SAndroid Build Coastguard Worker# Location of automically gathered android deps. 126*8975f5c5SAndroid Build Coastguard WorkerANDROID_DEPS_PATH = 'src/third_party/android_deps/' 127*8975f5c5SAndroid Build Coastguard Worker 128*8975f5c5SAndroid Build Coastguard WorkerNOTIFY_EMAIL = '[email protected]' 129*8975f5c5SAndroid Build Coastguard Worker 130*8975f5c5SAndroid Build Coastguard WorkerCLANG_TOOLS_URL = 'https://chromium.googlesource.com/chromium/src/tools/clang' 131*8975f5c5SAndroid Build Coastguard WorkerCLANG_FILE_TEMPLATE = CLANG_TOOLS_URL + '/+/%s/%s' 132*8975f5c5SAndroid Build Coastguard Worker 133*8975f5c5SAndroid Build Coastguard WorkerCLANG_TOOLS_PATH = 'tools/clang' 134*8975f5c5SAndroid Build Coastguard WorkerCLANG_UPDATE_SCRIPT_URL_PATH = 'scripts/update.py' 135*8975f5c5SAndroid Build Coastguard WorkerCLANG_UPDATE_SCRIPT_LOCAL_PATH = os.path.join(CHECKOUT_SRC_DIR, 'tools', 'clang', 'scripts', 136*8975f5c5SAndroid Build Coastguard Worker 'update.py') 137*8975f5c5SAndroid Build Coastguard Worker 138*8975f5c5SAndroid Build Coastguard WorkerDepsEntry = collections.namedtuple('DepsEntry', 'path url revision') 139*8975f5c5SAndroid Build Coastguard WorkerChangedDep = collections.namedtuple('ChangedDep', 'path url current_rev new_rev') 140*8975f5c5SAndroid Build Coastguard WorkerClangChange = collections.namedtuple('ClangChange', 'mirror_change clang_change') 141*8975f5c5SAndroid Build Coastguard WorkerCipdDepsEntry = collections.namedtuple('CipdDepsEntry', 'path packages') 142*8975f5c5SAndroid Build Coastguard WorkerChangedCipdPackage = collections.namedtuple('ChangedCipdPackage', 143*8975f5c5SAndroid Build Coastguard Worker 'path package current_version new_version') 144*8975f5c5SAndroid Build Coastguard Worker 145*8975f5c5SAndroid Build Coastguard WorkerChromiumRevisionUpdate = collections.namedtuple('ChromiumRevisionUpdate', ('current_chromium_rev ' 146*8975f5c5SAndroid Build Coastguard Worker 'new_chromium_rev ')) 147*8975f5c5SAndroid Build Coastguard Worker 148*8975f5c5SAndroid Build Coastguard Worker 149*8975f5c5SAndroid Build Coastguard Workerdef AddDepotToolsToPath(): 150*8975f5c5SAndroid Build Coastguard Worker sys.path.append(os.path.join(CHECKOUT_SRC_DIR, 'build')) 151*8975f5c5SAndroid Build Coastguard Worker import find_depot_tools 152*8975f5c5SAndroid Build Coastguard Worker find_depot_tools.add_depot_tools_to_path() 153*8975f5c5SAndroid Build Coastguard Worker 154*8975f5c5SAndroid Build Coastguard Worker 155*8975f5c5SAndroid Build Coastguard Workerclass RollError(Exception): 156*8975f5c5SAndroid Build Coastguard Worker pass 157*8975f5c5SAndroid Build Coastguard Worker 158*8975f5c5SAndroid Build Coastguard Worker 159*8975f5c5SAndroid Build Coastguard Workerdef StrExpansion(): 160*8975f5c5SAndroid Build Coastguard Worker return lambda str_value: str_value 161*8975f5c5SAndroid Build Coastguard Worker 162*8975f5c5SAndroid Build Coastguard Worker 163*8975f5c5SAndroid Build Coastguard Workerdef VarLookup(local_scope): 164*8975f5c5SAndroid Build Coastguard Worker return lambda var_name: local_scope['vars'][var_name] 165*8975f5c5SAndroid Build Coastguard Worker 166*8975f5c5SAndroid Build Coastguard Worker 167*8975f5c5SAndroid Build Coastguard Workerdef ParseDepsDict(deps_content): 168*8975f5c5SAndroid Build Coastguard Worker local_scope = {} 169*8975f5c5SAndroid Build Coastguard Worker global_scope = { 170*8975f5c5SAndroid Build Coastguard Worker 'Str': StrExpansion(), 171*8975f5c5SAndroid Build Coastguard Worker 'Var': VarLookup(local_scope), 172*8975f5c5SAndroid Build Coastguard Worker 'deps_os': {}, 173*8975f5c5SAndroid Build Coastguard Worker } 174*8975f5c5SAndroid Build Coastguard Worker exec (deps_content, global_scope, local_scope) 175*8975f5c5SAndroid Build Coastguard Worker return local_scope 176*8975f5c5SAndroid Build Coastguard Worker 177*8975f5c5SAndroid Build Coastguard Worker 178*8975f5c5SAndroid Build Coastguard Workerdef ParseLocalDepsFile(filename): 179*8975f5c5SAndroid Build Coastguard Worker with open(filename, 'rb') as f: 180*8975f5c5SAndroid Build Coastguard Worker deps_content = f.read() 181*8975f5c5SAndroid Build Coastguard Worker return ParseDepsDict(deps_content) 182*8975f5c5SAndroid Build Coastguard Worker 183*8975f5c5SAndroid Build Coastguard Worker 184*8975f5c5SAndroid Build Coastguard Workerdef ParseCommitPosition(commit_message): 185*8975f5c5SAndroid Build Coastguard Worker for line in reversed(commit_message.splitlines()): 186*8975f5c5SAndroid Build Coastguard Worker m = COMMIT_POSITION_RE.match(line.strip()) 187*8975f5c5SAndroid Build Coastguard Worker if m: 188*8975f5c5SAndroid Build Coastguard Worker return int(m.group(1)) 189*8975f5c5SAndroid Build Coastguard Worker logging.error('Failed to parse commit position id from:\n%s\n', commit_message) 190*8975f5c5SAndroid Build Coastguard Worker sys.exit(-1) 191*8975f5c5SAndroid Build Coastguard Worker 192*8975f5c5SAndroid Build Coastguard Worker 193*8975f5c5SAndroid Build Coastguard Workerdef _RunCommand(command, working_dir=None, ignore_exit_code=False, extra_env=None, 194*8975f5c5SAndroid Build Coastguard Worker input_data=None): 195*8975f5c5SAndroid Build Coastguard Worker """Runs a command and returns the output from that command. 196*8975f5c5SAndroid Build Coastguard Worker 197*8975f5c5SAndroid Build Coastguard Worker If the command fails (exit code != 0), the function will exit the process. 198*8975f5c5SAndroid Build Coastguard Worker 199*8975f5c5SAndroid Build Coastguard Worker Returns: 200*8975f5c5SAndroid Build Coastguard Worker A tuple containing the stdout and stderr outputs as strings. 201*8975f5c5SAndroid Build Coastguard Worker """ 202*8975f5c5SAndroid Build Coastguard Worker working_dir = working_dir or CHECKOUT_SRC_DIR 203*8975f5c5SAndroid Build Coastguard Worker logging.debug('CMD: %s CWD: %s', ' '.join(command), working_dir) 204*8975f5c5SAndroid Build Coastguard Worker env = os.environ.copy() 205*8975f5c5SAndroid Build Coastguard Worker if extra_env: 206*8975f5c5SAndroid Build Coastguard Worker assert all(isinstance(value, str) for value in extra_env.values()) 207*8975f5c5SAndroid Build Coastguard Worker logging.debug('extra env: %s', extra_env) 208*8975f5c5SAndroid Build Coastguard Worker env.update(extra_env) 209*8975f5c5SAndroid Build Coastguard Worker p = subprocess.Popen( 210*8975f5c5SAndroid Build Coastguard Worker command, 211*8975f5c5SAndroid Build Coastguard Worker stdin=subprocess.PIPE, 212*8975f5c5SAndroid Build Coastguard Worker stdout=subprocess.PIPE, 213*8975f5c5SAndroid Build Coastguard Worker stderr=subprocess.PIPE, 214*8975f5c5SAndroid Build Coastguard Worker env=env, 215*8975f5c5SAndroid Build Coastguard Worker cwd=working_dir, 216*8975f5c5SAndroid Build Coastguard Worker universal_newlines=True) 217*8975f5c5SAndroid Build Coastguard Worker std_output, err_output = p.communicate(input_data) 218*8975f5c5SAndroid Build Coastguard Worker p.stdout.close() 219*8975f5c5SAndroid Build Coastguard Worker p.stderr.close() 220*8975f5c5SAndroid Build Coastguard Worker if not ignore_exit_code and p.returncode != 0: 221*8975f5c5SAndroid Build Coastguard Worker logging.error('Command failed: %s\n' 222*8975f5c5SAndroid Build Coastguard Worker 'stdout:\n%s\n' 223*8975f5c5SAndroid Build Coastguard Worker 'stderr:\n%s\n', ' '.join(command), std_output, err_output) 224*8975f5c5SAndroid Build Coastguard Worker sys.exit(p.returncode) 225*8975f5c5SAndroid Build Coastguard Worker return std_output, err_output 226*8975f5c5SAndroid Build Coastguard Worker 227*8975f5c5SAndroid Build Coastguard Worker 228*8975f5c5SAndroid Build Coastguard Workerdef _GetBranches(): 229*8975f5c5SAndroid Build Coastguard Worker """Returns a tuple of active,branches. 230*8975f5c5SAndroid Build Coastguard Worker 231*8975f5c5SAndroid Build Coastguard Worker The 'active' is the name of the currently active branch and 'branches' is a 232*8975f5c5SAndroid Build Coastguard Worker list of all branches. 233*8975f5c5SAndroid Build Coastguard Worker """ 234*8975f5c5SAndroid Build Coastguard Worker lines = _RunCommand(['git', 'branch'])[0].split('\n') 235*8975f5c5SAndroid Build Coastguard Worker branches = [] 236*8975f5c5SAndroid Build Coastguard Worker active = '' 237*8975f5c5SAndroid Build Coastguard Worker for line in lines: 238*8975f5c5SAndroid Build Coastguard Worker if '*' in line: 239*8975f5c5SAndroid Build Coastguard Worker # The assumption is that the first char will always be the '*'. 240*8975f5c5SAndroid Build Coastguard Worker active = line[1:].strip() 241*8975f5c5SAndroid Build Coastguard Worker branches.append(active) 242*8975f5c5SAndroid Build Coastguard Worker else: 243*8975f5c5SAndroid Build Coastguard Worker branch = line.strip() 244*8975f5c5SAndroid Build Coastguard Worker if branch: 245*8975f5c5SAndroid Build Coastguard Worker branches.append(branch) 246*8975f5c5SAndroid Build Coastguard Worker return active, branches 247*8975f5c5SAndroid Build Coastguard Worker 248*8975f5c5SAndroid Build Coastguard Worker 249*8975f5c5SAndroid Build Coastguard Workerdef _ReadGitilesContent(url): 250*8975f5c5SAndroid Build Coastguard Worker # Download and decode BASE64 content until 251*8975f5c5SAndroid Build Coastguard Worker # https://code.google.com/p/gitiles/issues/detail?id=7 is fixed. 252*8975f5c5SAndroid Build Coastguard Worker logging.debug('Reading gitiles URL %s' % url) 253*8975f5c5SAndroid Build Coastguard Worker base64_content = ReadUrlContent(url + '?format=TEXT') 254*8975f5c5SAndroid Build Coastguard Worker return base64.b64decode(base64_content[0]).decode('utf-8') 255*8975f5c5SAndroid Build Coastguard Worker 256*8975f5c5SAndroid Build Coastguard Worker 257*8975f5c5SAndroid Build Coastguard Workerdef ReadRemoteCrFile(path_below_src, revision): 258*8975f5c5SAndroid Build Coastguard Worker """Reads a remote Chromium file of a specific revision. Returns a string.""" 259*8975f5c5SAndroid Build Coastguard Worker return _ReadGitilesContent(CHROMIUM_FILE_TEMPLATE % (revision, path_below_src)) 260*8975f5c5SAndroid Build Coastguard Worker 261*8975f5c5SAndroid Build Coastguard Worker 262*8975f5c5SAndroid Build Coastguard Workerdef ReadRemoteCrCommit(revision): 263*8975f5c5SAndroid Build Coastguard Worker """Reads a remote Chromium commit message. Returns a string.""" 264*8975f5c5SAndroid Build Coastguard Worker return _ReadGitilesContent(CHROMIUM_COMMIT_TEMPLATE % revision) 265*8975f5c5SAndroid Build Coastguard Worker 266*8975f5c5SAndroid Build Coastguard Worker 267*8975f5c5SAndroid Build Coastguard Workerdef ReadRemoteClangFile(path_below_src, revision): 268*8975f5c5SAndroid Build Coastguard Worker """Reads a remote Clang file of a specific revision. Returns a string.""" 269*8975f5c5SAndroid Build Coastguard Worker return _ReadGitilesContent(CLANG_FILE_TEMPLATE % (revision, path_below_src)) 270*8975f5c5SAndroid Build Coastguard Worker 271*8975f5c5SAndroid Build Coastguard Worker 272*8975f5c5SAndroid Build Coastguard Workerdef ReadUrlContent(url): 273*8975f5c5SAndroid Build Coastguard Worker """Connect to a remote host and read the contents. Returns a list of lines.""" 274*8975f5c5SAndroid Build Coastguard Worker conn = urllib.request.urlopen(url) 275*8975f5c5SAndroid Build Coastguard Worker try: 276*8975f5c5SAndroid Build Coastguard Worker return conn.readlines() 277*8975f5c5SAndroid Build Coastguard Worker except IOError as e: 278*8975f5c5SAndroid Build Coastguard Worker logging.exception('Error connecting to %s. Error: %s', url, e) 279*8975f5c5SAndroid Build Coastguard Worker raise 280*8975f5c5SAndroid Build Coastguard Worker finally: 281*8975f5c5SAndroid Build Coastguard Worker conn.close() 282*8975f5c5SAndroid Build Coastguard Worker 283*8975f5c5SAndroid Build Coastguard Worker 284*8975f5c5SAndroid Build Coastguard Workerdef GetMatchingDepsEntries(depsentry_dict, dir_path): 285*8975f5c5SAndroid Build Coastguard Worker """Gets all deps entries matching the provided path. 286*8975f5c5SAndroid Build Coastguard Worker 287*8975f5c5SAndroid Build Coastguard Worker This list may contain more than one DepsEntry object. 288*8975f5c5SAndroid Build Coastguard Worker Example: dir_path='src/testing' would give results containing both 289*8975f5c5SAndroid Build Coastguard Worker 'src/testing/gtest' and 'src/testing/gmock' deps entries for Chromium's DEPS. 290*8975f5c5SAndroid Build Coastguard Worker Example 2: dir_path='src/build' should return 'src/build' but not 291*8975f5c5SAndroid Build Coastguard Worker 'src/buildtools'. 292*8975f5c5SAndroid Build Coastguard Worker 293*8975f5c5SAndroid Build Coastguard Worker Returns: 294*8975f5c5SAndroid Build Coastguard Worker A list of DepsEntry objects. 295*8975f5c5SAndroid Build Coastguard Worker """ 296*8975f5c5SAndroid Build Coastguard Worker result = [] 297*8975f5c5SAndroid Build Coastguard Worker for path, depsentry in depsentry_dict.items(): 298*8975f5c5SAndroid Build Coastguard Worker if path == dir_path: 299*8975f5c5SAndroid Build Coastguard Worker result.append(depsentry) 300*8975f5c5SAndroid Build Coastguard Worker else: 301*8975f5c5SAndroid Build Coastguard Worker parts = path.split('/') 302*8975f5c5SAndroid Build Coastguard Worker if all(part == parts[i] for i, part in enumerate(dir_path.split('/'))): 303*8975f5c5SAndroid Build Coastguard Worker result.append(depsentry) 304*8975f5c5SAndroid Build Coastguard Worker return result 305*8975f5c5SAndroid Build Coastguard Worker 306*8975f5c5SAndroid Build Coastguard Worker 307*8975f5c5SAndroid Build Coastguard Workerdef BuildDepsentryDict(deps_dict): 308*8975f5c5SAndroid Build Coastguard Worker """Builds a dict of paths to DepsEntry objects from a raw parsed deps dict.""" 309*8975f5c5SAndroid Build Coastguard Worker result = {} 310*8975f5c5SAndroid Build Coastguard Worker 311*8975f5c5SAndroid Build Coastguard Worker def AddDepsEntries(deps_subdict): 312*8975f5c5SAndroid Build Coastguard Worker for path, dep in deps_subdict.items(): 313*8975f5c5SAndroid Build Coastguard Worker if path in result: 314*8975f5c5SAndroid Build Coastguard Worker continue 315*8975f5c5SAndroid Build Coastguard Worker if not isinstance(dep, dict): 316*8975f5c5SAndroid Build Coastguard Worker dep = {'url': dep} 317*8975f5c5SAndroid Build Coastguard Worker if dep.get('dep_type') == 'cipd': 318*8975f5c5SAndroid Build Coastguard Worker result[path] = CipdDepsEntry(path, dep['packages']) 319*8975f5c5SAndroid Build Coastguard Worker elif dep.get('dep_type') == 'gcs': 320*8975f5c5SAndroid Build Coastguard Worker # Ignore GCS deps - there aren't any that we want to sync yet 321*8975f5c5SAndroid Build Coastguard Worker continue 322*8975f5c5SAndroid Build Coastguard Worker else: 323*8975f5c5SAndroid Build Coastguard Worker if '@' not in dep['url']: 324*8975f5c5SAndroid Build Coastguard Worker continue 325*8975f5c5SAndroid Build Coastguard Worker url, revision = dep['url'].split('@') 326*8975f5c5SAndroid Build Coastguard Worker result[path] = DepsEntry(path, url, revision) 327*8975f5c5SAndroid Build Coastguard Worker 328*8975f5c5SAndroid Build Coastguard Worker AddDepsEntries(deps_dict['deps']) 329*8975f5c5SAndroid Build Coastguard Worker for deps_os in ['win', 'mac', 'unix', 'android', 'ios', 'unix']: 330*8975f5c5SAndroid Build Coastguard Worker AddDepsEntries(deps_dict.get('deps_os', {}).get(deps_os, {})) 331*8975f5c5SAndroid Build Coastguard Worker return result 332*8975f5c5SAndroid Build Coastguard Worker 333*8975f5c5SAndroid Build Coastguard Worker 334*8975f5c5SAndroid Build Coastguard Workerdef _FindChangedCipdPackages(path, old_pkgs, new_pkgs): 335*8975f5c5SAndroid Build Coastguard Worker pkgs_equal = ({p['package'] for p in old_pkgs} == {p['package'] for p in new_pkgs}) 336*8975f5c5SAndroid Build Coastguard Worker assert pkgs_equal, ('Old: %s\n New: %s.\nYou need to do a manual roll ' 337*8975f5c5SAndroid Build Coastguard Worker 'and remove/add entries in DEPS so the old and new ' 338*8975f5c5SAndroid Build Coastguard Worker 'list match.' % (old_pkgs, new_pkgs)) 339*8975f5c5SAndroid Build Coastguard Worker for old_pkg in old_pkgs: 340*8975f5c5SAndroid Build Coastguard Worker for new_pkg in new_pkgs: 341*8975f5c5SAndroid Build Coastguard Worker old_version = old_pkg['version'] 342*8975f5c5SAndroid Build Coastguard Worker new_version = new_pkg['version'] 343*8975f5c5SAndroid Build Coastguard Worker if (old_pkg['package'] == new_pkg['package'] and old_version != new_version): 344*8975f5c5SAndroid Build Coastguard Worker logging.debug('Roll dependency %s to %s', path, new_version) 345*8975f5c5SAndroid Build Coastguard Worker yield ChangedCipdPackage(path, old_pkg['package'], old_version, new_version) 346*8975f5c5SAndroid Build Coastguard Worker 347*8975f5c5SAndroid Build Coastguard Worker 348*8975f5c5SAndroid Build Coastguard Workerdef _FindNewDeps(old, new): 349*8975f5c5SAndroid Build Coastguard Worker """ Gather dependencies only in |new| and return corresponding paths. """ 350*8975f5c5SAndroid Build Coastguard Worker old_entries = set(BuildDepsentryDict(old)) 351*8975f5c5SAndroid Build Coastguard Worker new_entries = set(BuildDepsentryDict(new)) 352*8975f5c5SAndroid Build Coastguard Worker return [path for path in new_entries - old_entries if path in ANGLE_CHROMIUM_DEPS] 353*8975f5c5SAndroid Build Coastguard Worker 354*8975f5c5SAndroid Build Coastguard Worker 355*8975f5c5SAndroid Build Coastguard Workerdef CalculateChangedDeps(angle_deps, new_cr_deps): 356*8975f5c5SAndroid Build Coastguard Worker """ 357*8975f5c5SAndroid Build Coastguard Worker Calculate changed deps entries based on entries defined in the ANGLE DEPS 358*8975f5c5SAndroid Build Coastguard Worker file: 359*8975f5c5SAndroid Build Coastguard Worker - If a shared dependency with the Chromium DEPS file: roll it to the same 360*8975f5c5SAndroid Build Coastguard Worker revision as Chromium (i.e. entry in the new_cr_deps dict) 361*8975f5c5SAndroid Build Coastguard Worker - If it's a Chromium sub-directory, roll it to the HEAD revision (notice 362*8975f5c5SAndroid Build Coastguard Worker this means it may be ahead of the chromium_revision, but generally these 363*8975f5c5SAndroid Build Coastguard Worker should be close). 364*8975f5c5SAndroid Build Coastguard Worker - If it's another DEPS entry (not shared with Chromium), roll it to HEAD 365*8975f5c5SAndroid Build Coastguard Worker unless it's configured to be skipped. 366*8975f5c5SAndroid Build Coastguard Worker 367*8975f5c5SAndroid Build Coastguard Worker Returns: 368*8975f5c5SAndroid Build Coastguard Worker A list of ChangedDep objects representing the changed deps. 369*8975f5c5SAndroid Build Coastguard Worker """ 370*8975f5c5SAndroid Build Coastguard Worker 371*8975f5c5SAndroid Build Coastguard Worker def ChromeURL(angle_deps_entry): 372*8975f5c5SAndroid Build Coastguard Worker # Perform variable substitutions. 373*8975f5c5SAndroid Build Coastguard Worker # This is a hack to get around the unsupported way this script parses DEPS. 374*8975f5c5SAndroid Build Coastguard Worker # A better fix would be to use the gclient APIs to query and update DEPS. 375*8975f5c5SAndroid Build Coastguard Worker # However this is complicated by how this script downloads DEPS remotely. 376*8975f5c5SAndroid Build Coastguard Worker return angle_deps_entry.url.replace('{chromium_git}', 'https://chromium.googlesource.com') 377*8975f5c5SAndroid Build Coastguard Worker 378*8975f5c5SAndroid Build Coastguard Worker result = [] 379*8975f5c5SAndroid Build Coastguard Worker angle_entries = BuildDepsentryDict(angle_deps) 380*8975f5c5SAndroid Build Coastguard Worker new_cr_entries = BuildDepsentryDict(new_cr_deps) 381*8975f5c5SAndroid Build Coastguard Worker for path, angle_deps_entry in angle_entries.items(): 382*8975f5c5SAndroid Build Coastguard Worker if path not in ANGLE_CHROMIUM_DEPS: 383*8975f5c5SAndroid Build Coastguard Worker continue 384*8975f5c5SAndroid Build Coastguard Worker 385*8975f5c5SAndroid Build Coastguard Worker # All ANGLE Chromium dependencies are located in src/. 386*8975f5c5SAndroid Build Coastguard Worker chrome_path = 'src/%s' % path 387*8975f5c5SAndroid Build Coastguard Worker cr_deps_entry = new_cr_entries.get(chrome_path) 388*8975f5c5SAndroid Build Coastguard Worker 389*8975f5c5SAndroid Build Coastguard Worker if cr_deps_entry: 390*8975f5c5SAndroid Build Coastguard Worker assert type(cr_deps_entry) is type(angle_deps_entry) 391*8975f5c5SAndroid Build Coastguard Worker 392*8975f5c5SAndroid Build Coastguard Worker if isinstance(cr_deps_entry, CipdDepsEntry): 393*8975f5c5SAndroid Build Coastguard Worker result.extend( 394*8975f5c5SAndroid Build Coastguard Worker _FindChangedCipdPackages(path, angle_deps_entry.packages, 395*8975f5c5SAndroid Build Coastguard Worker cr_deps_entry.packages)) 396*8975f5c5SAndroid Build Coastguard Worker continue 397*8975f5c5SAndroid Build Coastguard Worker 398*8975f5c5SAndroid Build Coastguard Worker # Use the revision from Chromium's DEPS file. 399*8975f5c5SAndroid Build Coastguard Worker new_rev = cr_deps_entry.revision 400*8975f5c5SAndroid Build Coastguard Worker assert ChromeURL(angle_deps_entry) == cr_deps_entry.url, ( 401*8975f5c5SAndroid Build Coastguard Worker 'ANGLE DEPS entry %s has a different URL (%s) than Chromium (%s).' % 402*8975f5c5SAndroid Build Coastguard Worker (path, ChromeURL(angle_deps_entry), cr_deps_entry.url)) 403*8975f5c5SAndroid Build Coastguard Worker else: 404*8975f5c5SAndroid Build Coastguard Worker if isinstance(angle_deps_entry, DepsEntry): 405*8975f5c5SAndroid Build Coastguard Worker # Use the HEAD of the deps repo. 406*8975f5c5SAndroid Build Coastguard Worker stdout, _ = _RunCommand(['git', 'ls-remote', ChromeURL(angle_deps_entry), 'HEAD']) 407*8975f5c5SAndroid Build Coastguard Worker new_rev = stdout.strip().split('\t')[0] 408*8975f5c5SAndroid Build Coastguard Worker else: 409*8975f5c5SAndroid Build Coastguard Worker # The dependency has been removed from chromium. 410*8975f5c5SAndroid Build Coastguard Worker # This is handled by FindRemovedDeps. 411*8975f5c5SAndroid Build Coastguard Worker continue 412*8975f5c5SAndroid Build Coastguard Worker 413*8975f5c5SAndroid Build Coastguard Worker # Check if an update is necessary. 414*8975f5c5SAndroid Build Coastguard Worker if angle_deps_entry.revision != new_rev: 415*8975f5c5SAndroid Build Coastguard Worker logging.debug('Roll dependency %s to %s', path, new_rev) 416*8975f5c5SAndroid Build Coastguard Worker result.append( 417*8975f5c5SAndroid Build Coastguard Worker ChangedDep(path, ChromeURL(angle_deps_entry), angle_deps_entry.revision, new_rev)) 418*8975f5c5SAndroid Build Coastguard Worker return sorted(result) 419*8975f5c5SAndroid Build Coastguard Worker 420*8975f5c5SAndroid Build Coastguard Worker 421*8975f5c5SAndroid Build Coastguard Workerdef CalculateChangedClang(changed_deps, autoroll): 422*8975f5c5SAndroid Build Coastguard Worker mirror_change = [change for change in changed_deps if change.path == CLANG_TOOLS_PATH] 423*8975f5c5SAndroid Build Coastguard Worker if not mirror_change: 424*8975f5c5SAndroid Build Coastguard Worker return None 425*8975f5c5SAndroid Build Coastguard Worker 426*8975f5c5SAndroid Build Coastguard Worker mirror_change = mirror_change[0] 427*8975f5c5SAndroid Build Coastguard Worker 428*8975f5c5SAndroid Build Coastguard Worker def GetClangRev(lines): 429*8975f5c5SAndroid Build Coastguard Worker for line in lines: 430*8975f5c5SAndroid Build Coastguard Worker match = CLANG_REVISION_RE.match(line) 431*8975f5c5SAndroid Build Coastguard Worker if match: 432*8975f5c5SAndroid Build Coastguard Worker return match.group(1) 433*8975f5c5SAndroid Build Coastguard Worker raise RollError('Could not parse Clang revision!') 434*8975f5c5SAndroid Build Coastguard Worker 435*8975f5c5SAndroid Build Coastguard Worker old_clang_update_py = ReadRemoteClangFile(CLANG_UPDATE_SCRIPT_URL_PATH, 436*8975f5c5SAndroid Build Coastguard Worker mirror_change.current_rev).splitlines() 437*8975f5c5SAndroid Build Coastguard Worker old_clang_rev = GetClangRev(old_clang_update_py) 438*8975f5c5SAndroid Build Coastguard Worker logging.debug('Found old clang rev: %s' % old_clang_rev) 439*8975f5c5SAndroid Build Coastguard Worker 440*8975f5c5SAndroid Build Coastguard Worker new_clang_update_py = ReadRemoteClangFile(CLANG_UPDATE_SCRIPT_URL_PATH, 441*8975f5c5SAndroid Build Coastguard Worker mirror_change.new_rev).splitlines() 442*8975f5c5SAndroid Build Coastguard Worker new_clang_rev = GetClangRev(new_clang_update_py) 443*8975f5c5SAndroid Build Coastguard Worker logging.debug('Found new clang rev: %s' % new_clang_rev) 444*8975f5c5SAndroid Build Coastguard Worker clang_change = ChangedDep(CLANG_UPDATE_SCRIPT_LOCAL_PATH, None, old_clang_rev, new_clang_rev) 445*8975f5c5SAndroid Build Coastguard Worker return ClangChange(mirror_change, clang_change) 446*8975f5c5SAndroid Build Coastguard Worker 447*8975f5c5SAndroid Build Coastguard Worker 448*8975f5c5SAndroid Build Coastguard Workerdef GenerateCommitMessage( 449*8975f5c5SAndroid Build Coastguard Worker rev_update, 450*8975f5c5SAndroid Build Coastguard Worker current_commit_pos, 451*8975f5c5SAndroid Build Coastguard Worker new_commit_pos, 452*8975f5c5SAndroid Build Coastguard Worker changed_deps_list, 453*8975f5c5SAndroid Build Coastguard Worker autoroll, 454*8975f5c5SAndroid Build Coastguard Worker clang_change, 455*8975f5c5SAndroid Build Coastguard Worker): 456*8975f5c5SAndroid Build Coastguard Worker current_cr_rev = rev_update.current_chromium_rev[0:10] 457*8975f5c5SAndroid Build Coastguard Worker new_cr_rev = rev_update.new_chromium_rev[0:10] 458*8975f5c5SAndroid Build Coastguard Worker rev_interval = '%s..%s' % (current_cr_rev, new_cr_rev) 459*8975f5c5SAndroid Build Coastguard Worker git_number_interval = '%s:%s' % (current_commit_pos, new_commit_pos) 460*8975f5c5SAndroid Build Coastguard Worker 461*8975f5c5SAndroid Build Coastguard Worker commit_msg = [] 462*8975f5c5SAndroid Build Coastguard Worker # Autoroll already adds chromium_revision changes to commit message 463*8975f5c5SAndroid Build Coastguard Worker if not autoroll: 464*8975f5c5SAndroid Build Coastguard Worker commit_msg.extend([ 465*8975f5c5SAndroid Build Coastguard Worker 'Roll chromium_revision %s (%s)\n' % (rev_interval, git_number_interval), 466*8975f5c5SAndroid Build Coastguard Worker 'Change log: %s' % (CHROMIUM_LOG_TEMPLATE % rev_interval), 467*8975f5c5SAndroid Build Coastguard Worker 'Full diff: %s\n' % (CHROMIUM_COMMIT_TEMPLATE % rev_interval) 468*8975f5c5SAndroid Build Coastguard Worker ]) 469*8975f5c5SAndroid Build Coastguard Worker 470*8975f5c5SAndroid Build Coastguard Worker def Section(adjective, deps): 471*8975f5c5SAndroid Build Coastguard Worker noun = 'dependency' if len(deps) == 1 else 'dependencies' 472*8975f5c5SAndroid Build Coastguard Worker commit_msg.append('%s %s' % (adjective, noun)) 473*8975f5c5SAndroid Build Coastguard Worker 474*8975f5c5SAndroid Build Coastguard Worker tbr_authors = '' 475*8975f5c5SAndroid Build Coastguard Worker if changed_deps_list: 476*8975f5c5SAndroid Build Coastguard Worker Section('Changed', changed_deps_list) 477*8975f5c5SAndroid Build Coastguard Worker 478*8975f5c5SAndroid Build Coastguard Worker for c in changed_deps_list: 479*8975f5c5SAndroid Build Coastguard Worker if isinstance(c, ChangedCipdPackage): 480*8975f5c5SAndroid Build Coastguard Worker commit_msg.append('* %s: %s..%s' % (c.path, c.current_version, c.new_version)) 481*8975f5c5SAndroid Build Coastguard Worker else: 482*8975f5c5SAndroid Build Coastguard Worker commit_msg.append('* %s: %s/+log/%s..%s' % 483*8975f5c5SAndroid Build Coastguard Worker (c.path, c.url, c.current_rev[0:10], c.new_rev[0:10])) 484*8975f5c5SAndroid Build Coastguard Worker 485*8975f5c5SAndroid Build Coastguard Worker if changed_deps_list: 486*8975f5c5SAndroid Build Coastguard Worker # rev_interval is empty for autoroll, since we are starting from a state 487*8975f5c5SAndroid Build Coastguard Worker # in which chromium_revision is already modified in DEPS 488*8975f5c5SAndroid Build Coastguard Worker if not autoroll: 489*8975f5c5SAndroid Build Coastguard Worker change_url = CHROMIUM_FILE_TEMPLATE % (rev_interval, 'DEPS') 490*8975f5c5SAndroid Build Coastguard Worker commit_msg.append('DEPS diff: %s\n' % change_url) 491*8975f5c5SAndroid Build Coastguard Worker else: 492*8975f5c5SAndroid Build Coastguard Worker commit_msg.append('No dependencies changed.') 493*8975f5c5SAndroid Build Coastguard Worker 494*8975f5c5SAndroid Build Coastguard Worker c = clang_change 495*8975f5c5SAndroid Build Coastguard Worker if (c and (c.clang_change.current_rev != c.clang_change.new_rev)): 496*8975f5c5SAndroid Build Coastguard Worker commit_msg.append('Clang version changed %s:%s' % 497*8975f5c5SAndroid Build Coastguard Worker (c.clang_change.current_rev, c.clang_change.new_rev)) 498*8975f5c5SAndroid Build Coastguard Worker 499*8975f5c5SAndroid Build Coastguard Worker rev_clang = rev_interval = '%s..%s' % (c.mirror_change.current_rev, 500*8975f5c5SAndroid Build Coastguard Worker c.mirror_change.new_rev) 501*8975f5c5SAndroid Build Coastguard Worker change_url = CLANG_FILE_TEMPLATE % (rev_clang, CLANG_UPDATE_SCRIPT_URL_PATH) 502*8975f5c5SAndroid Build Coastguard Worker commit_msg.append('Details: %s\n' % change_url) 503*8975f5c5SAndroid Build Coastguard Worker else: 504*8975f5c5SAndroid Build Coastguard Worker commit_msg.append('No update to Clang.\n') 505*8975f5c5SAndroid Build Coastguard Worker 506*8975f5c5SAndroid Build Coastguard Worker # Autoroll takes care of BUG and TBR in commit message 507*8975f5c5SAndroid Build Coastguard Worker if not autoroll: 508*8975f5c5SAndroid Build Coastguard Worker # TBR needs to be non-empty for Gerrit to process it. 509*8975f5c5SAndroid Build Coastguard Worker git_author = _RunCommand(['git', 'config', 'user.email'], 510*8975f5c5SAndroid Build Coastguard Worker working_dir=CHECKOUT_SRC_DIR)[0].splitlines()[0] 511*8975f5c5SAndroid Build Coastguard Worker tbr_authors = git_author + ',' + tbr_authors 512*8975f5c5SAndroid Build Coastguard Worker 513*8975f5c5SAndroid Build Coastguard Worker commit_msg.append('TBR=%s' % tbr_authors) 514*8975f5c5SAndroid Build Coastguard Worker commit_msg.append('BUG=None') 515*8975f5c5SAndroid Build Coastguard Worker 516*8975f5c5SAndroid Build Coastguard Worker return '\n'.join(commit_msg) 517*8975f5c5SAndroid Build Coastguard Worker 518*8975f5c5SAndroid Build Coastguard Worker 519*8975f5c5SAndroid Build Coastguard Workerdef UpdateDepsFile(deps_filename, rev_update, changed_deps, new_cr_content, autoroll): 520*8975f5c5SAndroid Build Coastguard Worker """Update the DEPS file with the new revision.""" 521*8975f5c5SAndroid Build Coastguard Worker 522*8975f5c5SAndroid Build Coastguard Worker with open(deps_filename, 'rb') as deps_file: 523*8975f5c5SAndroid Build Coastguard Worker deps_content = deps_file.read().decode('utf-8') 524*8975f5c5SAndroid Build Coastguard Worker # Autoroll takes care of updating 'chromium_revision', thus we don't need to. 525*8975f5c5SAndroid Build Coastguard Worker if not autoroll: 526*8975f5c5SAndroid Build Coastguard Worker # Update the chromium_revision variable. 527*8975f5c5SAndroid Build Coastguard Worker deps_content = deps_content.replace(rev_update.current_chromium_rev, 528*8975f5c5SAndroid Build Coastguard Worker rev_update.new_chromium_rev) 529*8975f5c5SAndroid Build Coastguard Worker 530*8975f5c5SAndroid Build Coastguard Worker # Add and remove dependencies. For now: only generated android deps. 531*8975f5c5SAndroid Build Coastguard Worker # Since gclient cannot add or remove deps, we rely on the fact that 532*8975f5c5SAndroid Build Coastguard Worker # these android deps are located in one place to copy/paste. 533*8975f5c5SAndroid Build Coastguard Worker deps_re = re.compile(ANDROID_DEPS_START + '.*' + ANDROID_DEPS_END, re.DOTALL) 534*8975f5c5SAndroid Build Coastguard Worker new_deps = deps_re.search(new_cr_content) 535*8975f5c5SAndroid Build Coastguard Worker old_deps = deps_re.search(deps_content) 536*8975f5c5SAndroid Build Coastguard Worker if not new_deps or not old_deps: 537*8975f5c5SAndroid Build Coastguard Worker faulty = 'Chromium' if not new_deps else 'ANGLE' 538*8975f5c5SAndroid Build Coastguard Worker raise RollError('Was expecting to find "%s" and "%s"\n' 539*8975f5c5SAndroid Build Coastguard Worker 'in %s DEPS' % (ANDROID_DEPS_START, ANDROID_DEPS_END, faulty)) 540*8975f5c5SAndroid Build Coastguard Worker 541*8975f5c5SAndroid Build Coastguard Worker replacement = new_deps.group(0).replace('src/third_party/android_deps', 542*8975f5c5SAndroid Build Coastguard Worker 'third_party/android_deps') 543*8975f5c5SAndroid Build Coastguard Worker replacement = replacement.replace('checkout_android', 544*8975f5c5SAndroid Build Coastguard Worker 'checkout_android and not build_with_chromium') 545*8975f5c5SAndroid Build Coastguard Worker 546*8975f5c5SAndroid Build Coastguard Worker deps_content = deps_re.sub(replacement, deps_content) 547*8975f5c5SAndroid Build Coastguard Worker 548*8975f5c5SAndroid Build Coastguard Worker with open(deps_filename, 'wb') as deps_file: 549*8975f5c5SAndroid Build Coastguard Worker deps_file.write(deps_content.encode('utf-8')) 550*8975f5c5SAndroid Build Coastguard Worker 551*8975f5c5SAndroid Build Coastguard Worker # Update each individual DEPS entry. 552*8975f5c5SAndroid Build Coastguard Worker for dep in changed_deps: 553*8975f5c5SAndroid Build Coastguard Worker # We don't sync deps on autoroller, so ignore missing local deps 554*8975f5c5SAndroid Build Coastguard Worker if not autoroll: 555*8975f5c5SAndroid Build Coastguard Worker local_dep_dir = os.path.join(CHECKOUT_ROOT_DIR, dep.path) 556*8975f5c5SAndroid Build Coastguard Worker if not os.path.isdir(local_dep_dir): 557*8975f5c5SAndroid Build Coastguard Worker raise RollError('Cannot find local directory %s. Either run\n' 558*8975f5c5SAndroid Build Coastguard Worker 'gclient sync --deps=all\n' 559*8975f5c5SAndroid Build Coastguard Worker 'or make sure the .gclient file for your solution contains all ' 560*8975f5c5SAndroid Build Coastguard Worker 'platforms in the target_os list, i.e.\n' 561*8975f5c5SAndroid Build Coastguard Worker 'target_os = ["android", "unix", "mac", "ios", "win"];\n' 562*8975f5c5SAndroid Build Coastguard Worker 'Then run "gclient sync" again.' % local_dep_dir) 563*8975f5c5SAndroid Build Coastguard Worker if isinstance(dep, ChangedCipdPackage): 564*8975f5c5SAndroid Build Coastguard Worker package = dep.package.format() # Eliminate double curly brackets 565*8975f5c5SAndroid Build Coastguard Worker update = '%s:%s@%s' % (dep.path, package, dep.new_version) 566*8975f5c5SAndroid Build Coastguard Worker else: 567*8975f5c5SAndroid Build Coastguard Worker update = '%s@%s' % (dep.path, dep.new_rev) 568*8975f5c5SAndroid Build Coastguard Worker gclient_cmd = 'gclient' 569*8975f5c5SAndroid Build Coastguard Worker if platform.system() == 'Windows': 570*8975f5c5SAndroid Build Coastguard Worker gclient_cmd += '.bat' 571*8975f5c5SAndroid Build Coastguard Worker _RunCommand([gclient_cmd, 'setdep', '--revision', update], working_dir=CHECKOUT_SRC_DIR) 572*8975f5c5SAndroid Build Coastguard Worker 573*8975f5c5SAndroid Build Coastguard Worker 574*8975f5c5SAndroid Build Coastguard Workerdef _IsTreeClean(): 575*8975f5c5SAndroid Build Coastguard Worker stdout, _ = _RunCommand(['git', 'status', '--porcelain']) 576*8975f5c5SAndroid Build Coastguard Worker if len(stdout) == 0: 577*8975f5c5SAndroid Build Coastguard Worker return True 578*8975f5c5SAndroid Build Coastguard Worker 579*8975f5c5SAndroid Build Coastguard Worker logging.error('Dirty/unversioned files:\n%s', stdout) 580*8975f5c5SAndroid Build Coastguard Worker return False 581*8975f5c5SAndroid Build Coastguard Worker 582*8975f5c5SAndroid Build Coastguard Worker 583*8975f5c5SAndroid Build Coastguard Workerdef _EnsureUpdatedMainBranch(dry_run): 584*8975f5c5SAndroid Build Coastguard Worker current_branch = _RunCommand(['git', 'rev-parse', '--abbrev-ref', 'HEAD'])[0].splitlines()[0] 585*8975f5c5SAndroid Build Coastguard Worker if current_branch != 'main': 586*8975f5c5SAndroid Build Coastguard Worker logging.error('Please checkout the main branch and re-run this script.') 587*8975f5c5SAndroid Build Coastguard Worker if not dry_run: 588*8975f5c5SAndroid Build Coastguard Worker sys.exit(-1) 589*8975f5c5SAndroid Build Coastguard Worker 590*8975f5c5SAndroid Build Coastguard Worker logging.info('Updating main branch...') 591*8975f5c5SAndroid Build Coastguard Worker _RunCommand(['git', 'pull']) 592*8975f5c5SAndroid Build Coastguard Worker 593*8975f5c5SAndroid Build Coastguard Worker 594*8975f5c5SAndroid Build Coastguard Workerdef _CreateRollBranch(dry_run): 595*8975f5c5SAndroid Build Coastguard Worker logging.info('Creating roll branch: %s', ROLL_BRANCH_NAME) 596*8975f5c5SAndroid Build Coastguard Worker if not dry_run: 597*8975f5c5SAndroid Build Coastguard Worker _RunCommand(['git', 'checkout', '-b', ROLL_BRANCH_NAME]) 598*8975f5c5SAndroid Build Coastguard Worker 599*8975f5c5SAndroid Build Coastguard Worker 600*8975f5c5SAndroid Build Coastguard Workerdef _RemovePreviousRollBranch(dry_run): 601*8975f5c5SAndroid Build Coastguard Worker active_branch, branches = _GetBranches() 602*8975f5c5SAndroid Build Coastguard Worker if active_branch == ROLL_BRANCH_NAME: 603*8975f5c5SAndroid Build Coastguard Worker active_branch = 'main' 604*8975f5c5SAndroid Build Coastguard Worker if ROLL_BRANCH_NAME in branches: 605*8975f5c5SAndroid Build Coastguard Worker logging.info('Removing previous roll branch (%s)', ROLL_BRANCH_NAME) 606*8975f5c5SAndroid Build Coastguard Worker if not dry_run: 607*8975f5c5SAndroid Build Coastguard Worker _RunCommand(['git', 'checkout', active_branch]) 608*8975f5c5SAndroid Build Coastguard Worker _RunCommand(['git', 'branch', '-D', ROLL_BRANCH_NAME]) 609*8975f5c5SAndroid Build Coastguard Worker 610*8975f5c5SAndroid Build Coastguard Worker 611*8975f5c5SAndroid Build Coastguard Workerdef _LocalCommit(commit_msg, dry_run): 612*8975f5c5SAndroid Build Coastguard Worker logging.info('Committing changes locally.') 613*8975f5c5SAndroid Build Coastguard Worker if not dry_run: 614*8975f5c5SAndroid Build Coastguard Worker _RunCommand(['git', 'add', '--update', '.']) 615*8975f5c5SAndroid Build Coastguard Worker _RunCommand(['git', 'commit', '-m', commit_msg]) 616*8975f5c5SAndroid Build Coastguard Worker 617*8975f5c5SAndroid Build Coastguard Worker 618*8975f5c5SAndroid Build Coastguard Workerdef _LocalCommitAmend(commit_msg, dry_run): 619*8975f5c5SAndroid Build Coastguard Worker logging.info('Amending changes to local commit.') 620*8975f5c5SAndroid Build Coastguard Worker if not dry_run: 621*8975f5c5SAndroid Build Coastguard Worker old_commit_msg = _RunCommand(['git', 'log', '-1', '--pretty=%B'])[0].strip() 622*8975f5c5SAndroid Build Coastguard Worker logging.debug('Existing commit message:\n%s\n', old_commit_msg) 623*8975f5c5SAndroid Build Coastguard Worker 624*8975f5c5SAndroid Build Coastguard Worker bug_index = old_commit_msg.rfind('Bug:') 625*8975f5c5SAndroid Build Coastguard Worker if bug_index == -1: 626*8975f5c5SAndroid Build Coastguard Worker logging.error('"Bug:" not found in commit message.') 627*8975f5c5SAndroid Build Coastguard Worker if not dry_run: 628*8975f5c5SAndroid Build Coastguard Worker sys.exit(-1) 629*8975f5c5SAndroid Build Coastguard Worker new_commit_msg = old_commit_msg[:bug_index] + commit_msg + '\n' + old_commit_msg[bug_index:] 630*8975f5c5SAndroid Build Coastguard Worker 631*8975f5c5SAndroid Build Coastguard Worker _RunCommand(['git', 'commit', '-a', '--amend', '-m', new_commit_msg]) 632*8975f5c5SAndroid Build Coastguard Worker 633*8975f5c5SAndroid Build Coastguard Worker 634*8975f5c5SAndroid Build Coastguard Workerdef ChooseCQMode(skip_cq, cq_over, current_commit_pos, new_commit_pos): 635*8975f5c5SAndroid Build Coastguard Worker if skip_cq: 636*8975f5c5SAndroid Build Coastguard Worker return 0 637*8975f5c5SAndroid Build Coastguard Worker if (new_commit_pos - current_commit_pos) < cq_over: 638*8975f5c5SAndroid Build Coastguard Worker return 1 639*8975f5c5SAndroid Build Coastguard Worker return 2 640*8975f5c5SAndroid Build Coastguard Worker 641*8975f5c5SAndroid Build Coastguard Worker 642*8975f5c5SAndroid Build Coastguard Workerdef _UploadCL(commit_queue_mode): 643*8975f5c5SAndroid Build Coastguard Worker """Upload the committed changes as a changelist to Gerrit. 644*8975f5c5SAndroid Build Coastguard Worker 645*8975f5c5SAndroid Build Coastguard Worker commit_queue_mode: 646*8975f5c5SAndroid Build Coastguard Worker - 2: Submit to commit queue. 647*8975f5c5SAndroid Build Coastguard Worker - 1: Run trybots but do not submit to CQ. 648*8975f5c5SAndroid Build Coastguard Worker - 0: Skip CQ, upload only. 649*8975f5c5SAndroid Build Coastguard Worker """ 650*8975f5c5SAndroid Build Coastguard Worker cmd = ['git', 'cl', 'upload', '--force', '--bypass-hooks', '--send-mail'] 651*8975f5c5SAndroid Build Coastguard Worker cmd.extend(['--cc', NOTIFY_EMAIL]) 652*8975f5c5SAndroid Build Coastguard Worker if commit_queue_mode >= 2: 653*8975f5c5SAndroid Build Coastguard Worker logging.info('Sending the CL to the CQ...') 654*8975f5c5SAndroid Build Coastguard Worker cmd.extend(['--use-commit-queue']) 655*8975f5c5SAndroid Build Coastguard Worker elif commit_queue_mode >= 1: 656*8975f5c5SAndroid Build Coastguard Worker logging.info('Starting CQ dry run...') 657*8975f5c5SAndroid Build Coastguard Worker cmd.extend(['--cq-dry-run']) 658*8975f5c5SAndroid Build Coastguard Worker extra_env = { 659*8975f5c5SAndroid Build Coastguard Worker 'EDITOR': 'true', 660*8975f5c5SAndroid Build Coastguard Worker 'SKIP_GCE_AUTH_FOR_GIT': '1', 661*8975f5c5SAndroid Build Coastguard Worker } 662*8975f5c5SAndroid Build Coastguard Worker stdout, stderr = _RunCommand(cmd, extra_env=extra_env) 663*8975f5c5SAndroid Build Coastguard Worker logging.debug('Output from "git cl upload":\nstdout:\n%s\n\nstderr:\n%s', stdout, stderr) 664*8975f5c5SAndroid Build Coastguard Worker 665*8975f5c5SAndroid Build Coastguard Worker 666*8975f5c5SAndroid Build Coastguard Workerdef GetRollRevisionRanges(opts, angle_deps): 667*8975f5c5SAndroid Build Coastguard Worker current_cr_rev = angle_deps['vars']['chromium_revision'] 668*8975f5c5SAndroid Build Coastguard Worker new_cr_rev = opts.revision 669*8975f5c5SAndroid Build Coastguard Worker if not new_cr_rev: 670*8975f5c5SAndroid Build Coastguard Worker stdout, _ = _RunCommand(['git', 'ls-remote', CHROMIUM_SRC_URL, 'HEAD']) 671*8975f5c5SAndroid Build Coastguard Worker head_rev = stdout.strip().split('\t')[0] 672*8975f5c5SAndroid Build Coastguard Worker logging.info('No revision specified. Using HEAD: %s', head_rev) 673*8975f5c5SAndroid Build Coastguard Worker new_cr_rev = head_rev 674*8975f5c5SAndroid Build Coastguard Worker 675*8975f5c5SAndroid Build Coastguard Worker return ChromiumRevisionUpdate(current_cr_rev, new_cr_rev) 676*8975f5c5SAndroid Build Coastguard Worker 677*8975f5c5SAndroid Build Coastguard Worker 678*8975f5c5SAndroid Build Coastguard Workerdef main(): 679*8975f5c5SAndroid Build Coastguard Worker p = argparse.ArgumentParser() 680*8975f5c5SAndroid Build Coastguard Worker p.add_argument( 681*8975f5c5SAndroid Build Coastguard Worker '--clean', 682*8975f5c5SAndroid Build Coastguard Worker action='store_true', 683*8975f5c5SAndroid Build Coastguard Worker default=False, 684*8975f5c5SAndroid Build Coastguard Worker help='Removes any previous local roll branch.') 685*8975f5c5SAndroid Build Coastguard Worker p.add_argument( 686*8975f5c5SAndroid Build Coastguard Worker '-r', 687*8975f5c5SAndroid Build Coastguard Worker '--revision', 688*8975f5c5SAndroid Build Coastguard Worker help=('Chromium Git revision to roll to. Defaults to the ' 689*8975f5c5SAndroid Build Coastguard Worker 'Chromium HEAD revision if omitted.')) 690*8975f5c5SAndroid Build Coastguard Worker p.add_argument( 691*8975f5c5SAndroid Build Coastguard Worker '--dry-run', 692*8975f5c5SAndroid Build Coastguard Worker action='store_true', 693*8975f5c5SAndroid Build Coastguard Worker default=False, 694*8975f5c5SAndroid Build Coastguard Worker help=('Calculate changes and modify DEPS, but don\'t create ' 695*8975f5c5SAndroid Build Coastguard Worker 'any local branch, commit, upload CL or send any ' 696*8975f5c5SAndroid Build Coastguard Worker 'tryjobs.')) 697*8975f5c5SAndroid Build Coastguard Worker p.add_argument( 698*8975f5c5SAndroid Build Coastguard Worker '-i', 699*8975f5c5SAndroid Build Coastguard Worker '--ignore-unclean-workdir', 700*8975f5c5SAndroid Build Coastguard Worker action='store_true', 701*8975f5c5SAndroid Build Coastguard Worker default=False, 702*8975f5c5SAndroid Build Coastguard Worker help=('Ignore if the current branch is not main or if there ' 703*8975f5c5SAndroid Build Coastguard Worker 'are uncommitted changes (default: %(default)s).')) 704*8975f5c5SAndroid Build Coastguard Worker grp = p.add_mutually_exclusive_group() 705*8975f5c5SAndroid Build Coastguard Worker grp.add_argument( 706*8975f5c5SAndroid Build Coastguard Worker '--skip-cq', 707*8975f5c5SAndroid Build Coastguard Worker action='store_true', 708*8975f5c5SAndroid Build Coastguard Worker default=False, 709*8975f5c5SAndroid Build Coastguard Worker help='Skip sending the CL to the CQ (default: %(default)s)') 710*8975f5c5SAndroid Build Coastguard Worker grp.add_argument( 711*8975f5c5SAndroid Build Coastguard Worker '--cq-over', 712*8975f5c5SAndroid Build Coastguard Worker type=int, 713*8975f5c5SAndroid Build Coastguard Worker default=1, 714*8975f5c5SAndroid Build Coastguard Worker help=('Commit queue dry run if the revision difference ' 715*8975f5c5SAndroid Build Coastguard Worker 'is below this number (default: %(default)s)')) 716*8975f5c5SAndroid Build Coastguard Worker grp.add_argument( 717*8975f5c5SAndroid Build Coastguard Worker '--autoroll', 718*8975f5c5SAndroid Build Coastguard Worker action='store_true', 719*8975f5c5SAndroid Build Coastguard Worker default=False, 720*8975f5c5SAndroid Build Coastguard Worker help='Autoroller mode - amend existing commit, ' 721*8975f5c5SAndroid Build Coastguard Worker 'do not create nor upload a CL (default: %(default)s)') 722*8975f5c5SAndroid Build Coastguard Worker p.add_argument( 723*8975f5c5SAndroid Build Coastguard Worker '-v', 724*8975f5c5SAndroid Build Coastguard Worker '--verbose', 725*8975f5c5SAndroid Build Coastguard Worker action='store_true', 726*8975f5c5SAndroid Build Coastguard Worker default=False, 727*8975f5c5SAndroid Build Coastguard Worker help='Be extra verbose in printing of log messages.') 728*8975f5c5SAndroid Build Coastguard Worker opts = p.parse_args() 729*8975f5c5SAndroid Build Coastguard Worker 730*8975f5c5SAndroid Build Coastguard Worker if opts.verbose: 731*8975f5c5SAndroid Build Coastguard Worker logging.basicConfig(level=logging.DEBUG) 732*8975f5c5SAndroid Build Coastguard Worker else: 733*8975f5c5SAndroid Build Coastguard Worker logging.basicConfig(level=logging.INFO) 734*8975f5c5SAndroid Build Coastguard Worker 735*8975f5c5SAndroid Build Coastguard Worker # We don't have locally sync'ed deps on autoroller, 736*8975f5c5SAndroid Build Coastguard Worker # so trust it to have depot_tools in path 737*8975f5c5SAndroid Build Coastguard Worker if not opts.autoroll: 738*8975f5c5SAndroid Build Coastguard Worker AddDepotToolsToPath() 739*8975f5c5SAndroid Build Coastguard Worker 740*8975f5c5SAndroid Build Coastguard Worker if not opts.ignore_unclean_workdir and not _IsTreeClean(): 741*8975f5c5SAndroid Build Coastguard Worker logging.error('Please clean your local checkout first.') 742*8975f5c5SAndroid Build Coastguard Worker return 1 743*8975f5c5SAndroid Build Coastguard Worker 744*8975f5c5SAndroid Build Coastguard Worker if opts.clean: 745*8975f5c5SAndroid Build Coastguard Worker _RemovePreviousRollBranch(opts.dry_run) 746*8975f5c5SAndroid Build Coastguard Worker 747*8975f5c5SAndroid Build Coastguard Worker if not opts.ignore_unclean_workdir: 748*8975f5c5SAndroid Build Coastguard Worker _EnsureUpdatedMainBranch(opts.dry_run) 749*8975f5c5SAndroid Build Coastguard Worker 750*8975f5c5SAndroid Build Coastguard Worker deps_filename = os.path.join(CHECKOUT_SRC_DIR, 'DEPS') 751*8975f5c5SAndroid Build Coastguard Worker angle_deps = ParseLocalDepsFile(deps_filename) 752*8975f5c5SAndroid Build Coastguard Worker 753*8975f5c5SAndroid Build Coastguard Worker rev_update = GetRollRevisionRanges(opts, angle_deps) 754*8975f5c5SAndroid Build Coastguard Worker 755*8975f5c5SAndroid Build Coastguard Worker current_commit_pos = ParseCommitPosition(ReadRemoteCrCommit(rev_update.current_chromium_rev)) 756*8975f5c5SAndroid Build Coastguard Worker new_commit_pos = ParseCommitPosition(ReadRemoteCrCommit(rev_update.new_chromium_rev)) 757*8975f5c5SAndroid Build Coastguard Worker 758*8975f5c5SAndroid Build Coastguard Worker new_cr_content = ReadRemoteCrFile('DEPS', rev_update.new_chromium_rev) 759*8975f5c5SAndroid Build Coastguard Worker new_cr_deps = ParseDepsDict(new_cr_content) 760*8975f5c5SAndroid Build Coastguard Worker changed_deps = CalculateChangedDeps(angle_deps, new_cr_deps) 761*8975f5c5SAndroid Build Coastguard Worker clang_change = CalculateChangedClang(changed_deps, opts.autoroll) 762*8975f5c5SAndroid Build Coastguard Worker commit_msg = GenerateCommitMessage(rev_update, current_commit_pos, new_commit_pos, 763*8975f5c5SAndroid Build Coastguard Worker changed_deps, opts.autoroll, clang_change) 764*8975f5c5SAndroid Build Coastguard Worker logging.debug('Commit message:\n%s', commit_msg) 765*8975f5c5SAndroid Build Coastguard Worker 766*8975f5c5SAndroid Build Coastguard Worker # We are updating a commit that autoroll has created, using existing branch 767*8975f5c5SAndroid Build Coastguard Worker if not opts.autoroll: 768*8975f5c5SAndroid Build Coastguard Worker _CreateRollBranch(opts.dry_run) 769*8975f5c5SAndroid Build Coastguard Worker 770*8975f5c5SAndroid Build Coastguard Worker if not opts.dry_run: 771*8975f5c5SAndroid Build Coastguard Worker UpdateDepsFile(deps_filename, rev_update, changed_deps, new_cr_content, opts.autoroll) 772*8975f5c5SAndroid Build Coastguard Worker 773*8975f5c5SAndroid Build Coastguard Worker if opts.autoroll: 774*8975f5c5SAndroid Build Coastguard Worker _LocalCommitAmend(commit_msg, opts.dry_run) 775*8975f5c5SAndroid Build Coastguard Worker else: 776*8975f5c5SAndroid Build Coastguard Worker if _IsTreeClean(): 777*8975f5c5SAndroid Build Coastguard Worker logging.info("No DEPS changes detected, skipping CL creation.") 778*8975f5c5SAndroid Build Coastguard Worker else: 779*8975f5c5SAndroid Build Coastguard Worker _LocalCommit(commit_msg, opts.dry_run) 780*8975f5c5SAndroid Build Coastguard Worker commit_queue_mode = ChooseCQMode(opts.skip_cq, opts.cq_over, current_commit_pos, 781*8975f5c5SAndroid Build Coastguard Worker new_commit_pos) 782*8975f5c5SAndroid Build Coastguard Worker logging.info('Uploading CL...') 783*8975f5c5SAndroid Build Coastguard Worker if not opts.dry_run: 784*8975f5c5SAndroid Build Coastguard Worker _UploadCL(commit_queue_mode) 785*8975f5c5SAndroid Build Coastguard Worker return 0 786*8975f5c5SAndroid Build Coastguard Worker 787*8975f5c5SAndroid Build Coastguard Worker 788*8975f5c5SAndroid Build Coastguard Workerif __name__ == '__main__': 789*8975f5c5SAndroid Build Coastguard Worker sys.exit(main()) 790