1#!/usr/bin/env python 2 3# NOTE: This script requires python 3. 4 5"""Script to do the first step of Abseil roll into chromium. 6""" 7 8import logging 9import os 10import re 11import subprocess 12import tempfile 13from datetime import datetime 14 15ABSL_URI = 'https://github.com/abseil/abseil-cpp.git' 16 17def _PullAbseil(abseil_dir): 18 logging.info('Updating abseil...') 19 subprocess.check_call(['git', 'clone', ABSL_URI], 20 cwd=abseil_dir) 21 22def _SyncChromium(chromium_dir): 23 logging.info('Updating chromium...') 24 subprocess.check_call(['git', 'checkout', 'main'], cwd=chromium_dir) 25 subprocess.check_call(['git', 'pull', '--rebase'], cwd=chromium_dir) 26 subprocess.check_call(['gclient', 'sync'], cwd=chromium_dir) 27 28 29def _UpdateChromiumReadme(readme_filename, abseil_dir): 30 logging.info('Updating ' + readme_filename) 31 32 stdout = subprocess.check_output(['git', 'log', '-n1', '--pretty=short'], 33 cwd=abseil_dir) 34 new_revision = re.search('commit\\s(.{40})', str(stdout)).group(1) 35 36 with open(readme_filename, 'r+') as f: 37 content = f.read() 38 prefix = 'Revision: ' 39 pos = content.find(prefix) 40 assert(pos > 0) 41 pos = pos + len(prefix) 42 old_revision = content[pos:pos+40] 43 f.seek(pos) 44 f.write(new_revision) 45 46 logging.info('Abseil old revision is ' + old_revision) 47 logging.info('Abseil new revision is ' + new_revision) 48 return old_revision[0:10] + '..' + new_revision[0:10] 49 50 51def _UpdateAbseilInChromium(abseil_dir, chromium_dir): 52 logging.info('Syncing abseil in chromium/src/third_party...') 53 exclude = [ 54 '*BUILD.gn', 55 'DIR_METADATA', 56 'README.chromium', 57 'OWNERS', 58 '.gitignore', 59 '.git', 60 '*.gni', 61 '*clang-format', 62 'patches/*', 63 'patches', 64 'absl_hardening_test.cc', 65 'roll_abseil.py', 66 'generate_def_files.py', 67 '*.def', 68 ] 69 params = ['rsync', '-aP', abseil_dir, os.path.join(chromium_dir, 'third_party'), '--delete'] 70 for e in exclude: 71 params.append('--exclude={}'.format(e)) 72 subprocess.check_call(params, cwd=chromium_dir) 73 74 75def _PatchAbseil(abseil_in_chromium_dir): 76 logging.info('Patching abseil...') 77 for patch in os.listdir(os.path.join(abseil_in_chromium_dir, 'patches')): 78 subprocess.check_call(['patch', '--strip', '1', '-i', os.path.join(abseil_in_chromium_dir, 'patches', patch)]) 79 80 os.remove(os.path.join(abseil_in_chromium_dir, 'absl', 'base', 'internal', 'thread_annotations.h')) 81 os.remove(os.path.join(abseil_in_chromium_dir, 'absl', 'base', 'internal', 'dynamic_annotations.h')) 82 83 84def _Commit(chromium_dir, hash_diff): 85 logging.info('Commit...') 86 desc="""Roll abseil_revision {0} 87 88Change Log: 89https://chromium.googlesource.com/external/github.com/abseil/abseil-cpp/+log/{0} 90Full diff: 91https://chromium.googlesource.com/external/github.com/abseil/abseil-cpp/+/{0} 92Bug: None""".format(hash_diff) 93 94 subprocess.check_call(['git', 'add', 'third_party/abseil-cpp'], cwd=chromium_dir) 95 subprocess.check_call(['git', 'commit', '-m', desc], cwd=chromium_dir) 96 97 logging.info('Upload...') 98 subprocess.check_call(['git', 'cl', 'upload', '-m', desc, '--bypass-hooks'], cwd=chromium_dir) 99 100 101def _Roll(): 102 chromium_dir = os.getcwd() 103 abseil_in_chromium_dir = os.path.join(chromium_dir, 'third_party', 'abseil-cpp') 104 _SyncChromium(chromium_dir) 105 106 branch_name = datetime.today().strftime('rolling-absl-%Y%m%d') 107 logging.info('Creating branch ' + branch_name + ' for the roll...') 108 subprocess.check_call(['git', 'checkout', '-b', branch_name], cwd=chromium_dir) 109 110 with tempfile.TemporaryDirectory() as abseil_root: 111 _PullAbseil(abseil_root) 112 abseil_dir = os.path.join(abseil_root, 'abseil-cpp') 113 _UpdateAbseilInChromium(abseil_dir, chromium_dir) 114 hash_diff = _UpdateChromiumReadme(os.path.join(abseil_in_chromium_dir, 'README.chromium'), 115 abseil_dir) 116 117 _PatchAbseil(abseil_in_chromium_dir) 118 _Commit(chromium_dir, hash_diff) 119 120 121if __name__ == '__main__': 122 logging.getLogger().setLevel(logging.INFO) 123 124 if os.getcwd().endswith('src') and os.path.exists('chrome/browser'): 125 _Roll() 126 127 logging.info("Next step is manual: Fix BUILD.gn files to match BUILD.bazel changes.") 128 logging.info("After that run generate_def_files.py. ") 129 else: 130 logging.error('Run this script from a chromium/src/ directory.') 131 132 133