| OLD | NEW |
| 1 #!/usr/bin/python2 | 1 #!/usr/bin/python2 |
| 2 | 2 |
| 3 # Copyright 2014 Google Inc. | 3 # Copyright 2014 Google Inc. |
| 4 # | 4 # |
| 5 # Use of this source code is governed by a BSD-style license that can be | 5 # Use of this source code is governed by a BSD-style license that can be |
| 6 # found in the LICENSE file. | 6 # found in the LICENSE file. |
| 7 | 7 |
| 8 """Skia's Chromium DEPS roll script. | 8 """Skia's Chromium DEPS roll script. |
| 9 | 9 |
| 10 This script: | 10 This script: |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 | 21 |
| 22 Usage: | 22 Usage: |
| 23 %prog -c CHROMIUM_PATH -r REVISION [OPTIONAL_OPTIONS] | 23 %prog -c CHROMIUM_PATH -r REVISION [OPTIONAL_OPTIONS] |
| 24 """ | 24 """ |
| 25 | 25 |
| 26 | 26 |
| 27 import optparse | 27 import optparse |
| 28 import os | 28 import os |
| 29 import re | 29 import re |
| 30 import shutil | 30 import shutil |
| 31 import subprocess | |
| 32 import sys | 31 import sys |
| 33 import tempfile | 32 import tempfile |
| 34 | 33 |
| 35 import git_utils | 34 import fix_pythonpath # pylint: disable=W0611 |
| 36 import misc_utils | 35 from common.py.utils import git_utils |
| 36 from common.py.utils import misc |
| 37 from common.py.utils import shell_utils |
| 37 | 38 |
| 38 | 39 |
| 39 DEFAULT_BOTS_LIST = [ | 40 DEFAULT_BOTS_LIST = [ |
| 40 'android_clang_dbg', | 41 'android_clang_dbg', |
| 41 'android_dbg', | 42 'android_dbg', |
| 42 'android_rel', | 43 'android_rel', |
| 43 'cros_daisy', | 44 'cros_daisy', |
| 44 'linux', | 45 'linux', |
| 45 'linux_asan', | 46 'linux_asan', |
| 46 'linux_chromeos', | 47 'linux_chromeos', |
| 47 'linux_chromeos_asan', | 48 'linux_chromeos_asan', |
| 48 'linux_chromium_gn_dbg', | 49 'linux_chromium_gn_dbg', |
| 49 'linux_gpu', | 50 'linux_gpu', |
| 50 'linux_layout', | 51 'linux_layout', |
| 51 'linux_layout_rel', | 52 'linux_layout_rel', |
| 52 'mac', | 53 'mac', |
| 53 'mac_asan', | 54 'mac_asan', |
| 54 'mac_gpu', | 55 'mac_gpu', |
| 55 'mac_layout', | 56 'mac_layout', |
| 56 'mac_layout_rel', | 57 'mac_layout_rel', |
| 57 'win', | 58 'win', |
| 58 'win_gpu', | 59 'win_gpu', |
| 59 'win_layout', | 60 'win_layout', |
| 60 'win_layout_rel', | 61 'win_layout_rel', |
| 61 ] | 62 ] |
| 62 | 63 |
| 64 REGEXP_SKIA_REVISION = ( |
| 65 r'^ "skia_revision": "(?P<revision>[0-9a-fA-F]{2,40})",$') |
| 66 |
| 63 | 67 |
| 64 class DepsRollConfig(object): | 68 class DepsRollConfig(object): |
| 65 """Contains configuration options for this module. | 69 """Contains configuration options for this module. |
| 66 | 70 |
| 67 Attributes: | 71 Attributes: |
| 68 git: (string) The git executable. | |
| 69 chromium_path: (string) path to a local chromium git repository. | 72 chromium_path: (string) path to a local chromium git repository. |
| 70 save_branches: (boolean) iff false, delete temporary branches. | 73 save_branches: (boolean) iff false, delete temporary branches. |
| 71 verbose: (boolean) iff false, suppress the output from git-cl. | 74 verbose: (boolean) iff false, suppress the output from git-cl. |
| 72 search_depth: (int) how far back to look for the revision. | 75 skip_cl_upload: (boolean) |
| 73 skia_url: (string) Skia's git repository. | 76 cl_bot_list: (list of strings) |
| 74 self.skip_cl_upload: (boolean) | |
| 75 self.cl_bot_list: (list of strings) | |
| 76 """ | 77 """ |
| 77 | 78 |
| 78 # pylint: disable=I0011,R0903,R0902 | 79 # pylint: disable=I0011,R0903,R0902 |
| 79 def __init__(self, options=None): | 80 def __init__(self, options=None): |
| 80 self.skia_url = 'https://skia.googlesource.com/skia.git' | |
| 81 self.revision_format = ( | |
| 82 'git-svn-id: http://skia.googlecode.com/svn/trunk@%d ') | |
| 83 | |
| 84 self.git = git_utils.git_executable() | |
| 85 | |
| 86 if not options: | 81 if not options: |
| 87 options = DepsRollConfig.GetOptionParser() | 82 options = DepsRollConfig.GetOptionParser() |
| 88 # pylint: disable=I0011,E1103 | 83 # pylint: disable=I0011,E1103 |
| 89 self.verbose = options.verbose | 84 self.verbose = options.verbose |
| 90 self.vsp = misc_utils.VerboseSubprocess(self.verbose) | |
| 91 self.save_branches = not options.delete_branches | 85 self.save_branches = not options.delete_branches |
| 92 self.search_depth = options.search_depth | |
| 93 self.chromium_path = options.chromium_path | 86 self.chromium_path = options.chromium_path |
| 94 self.skip_cl_upload = options.skip_cl_upload | 87 self.skip_cl_upload = options.skip_cl_upload |
| 95 # Split and remove empty strigns from the bot list. | 88 # Split and remove empty strigns from the bot list. |
| 96 self.cl_bot_list = [bot for bot in options.bots.split(',') if bot] | 89 self.cl_bot_list = [bot for bot in options.bots.split(',') if bot] |
| 97 self.skia_git_checkout_path = options.skia_git_path | |
| 98 self.default_branch_name = 'autogenerated_deps_roll_branch' | 90 self.default_branch_name = 'autogenerated_deps_roll_branch' |
| 99 self.reviewers_list = ','.join([ | 91 self.reviewers_list = ','.join([ |
| 100 # 'rmistry@google.com', | 92 # 'rmistry@google.com', |
| 101 # 'reed@google.com', | 93 # 'reed@google.com', |
| 102 # 'bsalomon@google.com', | 94 # 'bsalomon@google.com', |
| 103 # 'robertphillips@google.com', | 95 # 'robertphillips@google.com', |
| 104 ]) | 96 ]) |
| 105 self.cc_list = ','.join([ | 97 self.cc_list = ','.join([ |
| 106 # 'skia-team@google.com', | 98 # 'skia-team@google.com', |
| 107 ]) | 99 ]) |
| (...skipping 10 matching lines...) Expand all Loading... |
| 118 """ | 110 """ |
| 119 option_parser = optparse.OptionParser(usage=__doc__) | 111 option_parser = optparse.OptionParser(usage=__doc__) |
| 120 # Anyone using this script on a regular basis should set the | 112 # Anyone using this script on a regular basis should set the |
| 121 # CHROMIUM_CHECKOUT_PATH environment variable. | 113 # CHROMIUM_CHECKOUT_PATH environment variable. |
| 122 option_parser.add_option( | 114 option_parser.add_option( |
| 123 '-c', '--chromium_path', help='Path to local Chromium Git' | 115 '-c', '--chromium_path', help='Path to local Chromium Git' |
| 124 ' repository checkout, defaults to CHROMIUM_CHECKOUT_PATH' | 116 ' repository checkout, defaults to CHROMIUM_CHECKOUT_PATH' |
| 125 ' if that environment variable is set.', | 117 ' if that environment variable is set.', |
| 126 default=os.environ.get('CHROMIUM_CHECKOUT_PATH')) | 118 default=os.environ.get('CHROMIUM_CHECKOUT_PATH')) |
| 127 option_parser.add_option( | 119 option_parser.add_option( |
| 128 '-r', '--revision', type='int', default=None, | 120 '-r', '--revision', default=None, |
| 129 help='The Skia SVN revision number, defaults to top of tree.') | 121 help='The Skia Git commit hash.') |
| 130 option_parser.add_option( | |
| 131 '-g', '--git_hash', default=None, | |
| 132 help='A partial Skia Git hash. Do not set this and revision.') | |
| 133 | 122 |
| 134 # Anyone using this script on a regular basis should set the | |
| 135 # SKIA_GIT_CHECKOUT_PATH environment variable. | |
| 136 option_parser.add_option( | |
| 137 '', '--skia_git_path', | |
| 138 help='Path of a pure-git Skia repository checkout. If empty,' | |
| 139 ' a temporary will be cloned. Defaults to SKIA_GIT_CHECKOUT' | |
| 140 '_PATH, if that environment variable is set.', | |
| 141 default=os.environ.get('SKIA_GIT_CHECKOUT_PATH')) | |
| 142 option_parser.add_option( | |
| 143 '', '--search_depth', type='int', default=100, | |
| 144 help='How far back to look for the revision.') | |
| 145 option_parser.add_option( | 123 option_parser.add_option( |
| 146 '', '--delete_branches', help='Delete the temporary branches', | 124 '', '--delete_branches', help='Delete the temporary branches', |
| 147 action='store_true', dest='delete_branches', default=False) | 125 action='store_true', dest='delete_branches', default=False) |
| 148 option_parser.add_option( | 126 option_parser.add_option( |
| 149 '', '--verbose', help='Do not suppress the output from `git cl`.', | 127 '', '--verbose', help='Do not suppress the output from `git cl`.', |
| 150 action='store_true', dest='verbose', default=False) | 128 action='store_true', dest='verbose', default=False) |
| 151 option_parser.add_option( | 129 option_parser.add_option( |
| 152 '', '--skip_cl_upload', help='Skip the cl upload step; useful' | 130 '', '--skip_cl_upload', help='Skip the cl upload step; useful' |
| 153 ' for testing.', | 131 ' for testing.', |
| 154 action='store_true', default=False) | 132 action='store_true', default=False) |
| 155 | 133 |
| 156 default_bots_help = ( | 134 default_bots_help = ( |
| 157 'Comma-separated list of bots, defaults to a list of %d bots.' | 135 'Comma-separated list of bots, defaults to a list of %d bots.' |
| 158 ' To skip `git cl try`, set this to an empty string.' | 136 ' To skip `git cl try`, set this to an empty string.' |
| 159 % len(DEFAULT_BOTS_LIST)) | 137 % len(DEFAULT_BOTS_LIST)) |
| 160 default_bots = ','.join(DEFAULT_BOTS_LIST) | 138 default_bots = ','.join(DEFAULT_BOTS_LIST) |
| 161 option_parser.add_option( | 139 option_parser.add_option( |
| 162 '', '--bots', help=default_bots_help, default=default_bots) | 140 '', '--bots', help=default_bots_help, default=default_bots) |
| 163 | 141 |
| 164 return option_parser | 142 return option_parser |
| 165 | 143 |
| 166 | 144 |
| 167 class DepsRollError(Exception): | 145 class DepsRollError(Exception): |
| 168 """Exceptions specific to this module.""" | 146 """Exceptions specific to this module.""" |
| 169 pass | 147 pass |
| 170 | 148 |
| 171 | 149 |
| 172 def get_svn_revision(config, commit): | 150 def change_skia_deps(revision, depspath): |
| 173 """Works in both git and git-svn. returns a string.""" | 151 """Update the DEPS file. |
| 174 svn_format = ( | |
| 175 '(git-svn-id: [^@ ]+@|SVN changes up to revision |' | |
| 176 'LKGR w/ DEPS up to revision )(?P<return>[0-9]+)') | |
| 177 svn_revision = misc_utils.ReSearch.search_within_output( | |
| 178 config.verbose, svn_format, None, | |
| 179 [config.git, 'log', '-n', '1', '--format=format:%B', commit]) | |
| 180 if not svn_revision: | |
| 181 raise DepsRollError( | |
| 182 'Revision number missing from Chromium origin/master.') | |
| 183 return int(svn_revision) | |
| 184 | 152 |
| 185 | 153 Modify the skia_revision entry in the given DEPS file. |
| 186 class SkiaGitCheckout(object): | |
| 187 """Class to create a temporary skia git checkout, if necessary. | |
| 188 """ | |
| 189 # pylint: disable=I0011,R0903 | |
| 190 | |
| 191 def __init__(self, config, depth): | |
| 192 self._config = config | |
| 193 self._depth = depth | |
| 194 self._use_temp = None | |
| 195 self._original_cwd = None | |
| 196 | |
| 197 def __enter__(self): | |
| 198 config = self._config | |
| 199 git = config.git | |
| 200 skia_dir = None | |
| 201 self._original_cwd = os.getcwd() | |
| 202 if config.skia_git_checkout_path: | |
| 203 if config.skia_git_checkout_path != os.curdir: | |
| 204 skia_dir = config.skia_git_checkout_path | |
| 205 ## Update origin/master if needed. | |
| 206 if self._config.verbose: | |
| 207 print '~~$', 'cd', skia_dir | |
| 208 os.chdir(skia_dir) | |
| 209 config.vsp.check_call([git, 'fetch', '-q', 'origin']) | |
| 210 self._use_temp = None | |
| 211 else: | |
| 212 skia_dir = tempfile.mkdtemp(prefix='git_skia_tmp_') | |
| 213 self._use_temp = skia_dir | |
| 214 try: | |
| 215 os.chdir(skia_dir) | |
| 216 config.vsp.check_call( | |
| 217 [git, 'clone', '-q', '--depth=%d' % self._depth, | |
| 218 '--single-branch', config.skia_url, '.']) | |
| 219 except (OSError, subprocess.CalledProcessError) as error: | |
| 220 shutil.rmtree(skia_dir) | |
| 221 raise error | |
| 222 | |
| 223 def __exit__(self, etype, value, traceback): | |
| 224 if self._config.skia_git_checkout_path != os.curdir: | |
| 225 if self._config.verbose: | |
| 226 print '~~$', 'cd', self._original_cwd | |
| 227 os.chdir(self._original_cwd) | |
| 228 if self._use_temp: | |
| 229 shutil.rmtree(self._use_temp) | |
| 230 | |
| 231 | |
| 232 def revision_and_hash(config): | |
| 233 """Finds revision number and git hash of origin/master in the Skia tree. | |
| 234 | 154 |
| 235 Args: | 155 Args: |
| 236 config: (roll_deps.DepsRollConfig) object containing options. | 156 revision: (string) Skia commit hash. |
| 237 | |
| 238 Returns: | |
| 239 A tuple (revision, hash) | |
| 240 revision: (int) SVN revision number. | |
| 241 git_hash: (string) full Git commit hash. | |
| 242 | |
| 243 Raises: | |
| 244 roll_deps.DepsRollError: if the revision can't be found. | |
| 245 OSError: failed to execute git or git-cl. | |
| 246 subprocess.CalledProcessError: git returned unexpected status. | |
| 247 """ | |
| 248 with SkiaGitCheckout(config, 1): | |
| 249 revision = get_svn_revision(config, 'origin/master') | |
| 250 git_hash = config.vsp.strip_output( | |
| 251 [config.git, 'show-ref', 'origin/master', '--hash']) | |
| 252 if not git_hash: | |
| 253 raise DepsRollError('Git hash can not be found.') | |
| 254 return revision, git_hash | |
| 255 | |
| 256 | |
| 257 def revision_and_hash_from_revision(config, revision): | |
| 258 """Finds revision number and git hash of a commit in the Skia tree. | |
| 259 | |
| 260 Args: | |
| 261 config: (roll_deps.DepsRollConfig) object containing options. | |
| 262 revision: (int) SVN revision number. | |
| 263 | |
| 264 Returns: | |
| 265 A tuple (revision, hash) | |
| 266 revision: (int) SVN revision number. | |
| 267 git_hash: (string) full Git commit hash. | |
| 268 | |
| 269 Raises: | |
| 270 roll_deps.DepsRollError: if the revision can't be found. | |
| 271 OSError: failed to execute git or git-cl. | |
| 272 subprocess.CalledProcessError: git returned unexpected status. | |
| 273 """ | |
| 274 with SkiaGitCheckout(config, config.search_depth): | |
| 275 revision_regex = config.revision_format % revision | |
| 276 git_hash = config.vsp.strip_output( | |
| 277 [config.git, 'log', '--grep', revision_regex, | |
| 278 '--format=format:%H', 'origin/master']) | |
| 279 if not git_hash: | |
| 280 raise DepsRollError('Git hash can not be found.') | |
| 281 return revision, git_hash | |
| 282 | |
| 283 | |
| 284 def revision_and_hash_from_partial(config, partial_hash): | |
| 285 """Returns the SVN revision number and full git hash. | |
| 286 | |
| 287 Args: | |
| 288 config: (roll_deps.DepsRollConfig) object containing options. | |
| 289 partial_hash: (string) Partial git commit hash. | |
| 290 | |
| 291 Returns: | |
| 292 A tuple (revision, hash) | |
| 293 revision: (int) SVN revision number. | |
| 294 git_hash: (string) full Git commit hash. | |
| 295 | |
| 296 Raises: | |
| 297 roll_deps.DepsRollError: if the revision can't be found. | |
| 298 OSError: failed to execute git or git-cl. | |
| 299 subprocess.CalledProcessError: git returned unexpected status. | |
| 300 """ | |
| 301 with SkiaGitCheckout(config, config.search_depth): | |
| 302 git_hash = config.vsp.strip_output( | |
| 303 ['git', 'log', '-n', '1', '--format=format:%H', partial_hash]) | |
| 304 if not git_hash: | |
| 305 raise DepsRollError('Partial Git hash can not be found.') | |
| 306 revision = get_svn_revision(config, git_hash) | |
| 307 return revision, git_hash | |
| 308 | |
| 309 | |
| 310 def change_skia_deps(revision, git_hash, depspath): | |
| 311 """Update the DEPS file. | |
| 312 | |
| 313 Modify the skia_revision and skia_hash entries in the given DEPS file. | |
| 314 | |
| 315 Args: | |
| 316 revision: (int) Skia SVN revision. | |
| 317 git_hash: (string) Skia Git hash. | |
| 318 depspath: (string) path to DEPS file. | 157 depspath: (string) path to DEPS file. |
| 319 """ | 158 """ |
| 320 temp_file = tempfile.NamedTemporaryFile(delete=False, | 159 temp_file = tempfile.NamedTemporaryFile(delete=False, |
| 321 prefix='skia_DEPS_ROLL_tmp_') | 160 prefix='skia_DEPS_ROLL_tmp_') |
| 322 try: | 161 try: |
| 323 deps_regex_rev = re.compile('"skia_revision": "[0-9]*",') | 162 deps_regex_rev = re.compile(REGEXP_SKIA_REVISION) |
| 324 deps_regex_hash = re.compile('"skia_hash": "[0-9a-f]*",') | 163 deps_regex_rev_repl = ' "skia_revision": "%s",' % revision |
| 325 | |
| 326 deps_regex_rev_repl = '"skia_revision": "%d",' % revision | |
| 327 deps_regex_hash_repl = '"skia_hash": "%s",' % git_hash | |
| 328 | 164 |
| 329 with open(depspath, 'r') as input_stream: | 165 with open(depspath, 'r') as input_stream: |
| 330 for line in input_stream: | 166 for line in input_stream: |
| 331 line = deps_regex_rev.sub(deps_regex_rev_repl, line) | 167 line = deps_regex_rev.sub(deps_regex_rev_repl, line) |
| 332 line = deps_regex_hash.sub(deps_regex_hash_repl, line) | |
| 333 temp_file.write(line) | 168 temp_file.write(line) |
| 334 finally: | 169 finally: |
| 335 temp_file.close() | 170 temp_file.close() |
| 336 shutil.move(temp_file.name, depspath) | 171 shutil.move(temp_file.name, depspath) |
| 337 | 172 |
| 338 | 173 |
| 339 def git_cl_uploader(config, message, file_list): | 174 def submit_tries(bots_to_run, dry_run=False): |
| 340 """Create a commit in the current git branch; upload via git-cl. | 175 """Submit try requests for the current branch on the given bots. |
| 341 | |
| 342 Assumes that you are already on the branch you want to be on. | |
| 343 | 176 |
| 344 Args: | 177 Args: |
| 345 config: (roll_deps.DepsRollConfig) object containing options. | 178 bots_to_run: (list of strings) bots to request. |
| 346 message: (string) the commit message, can be multiline. | 179 dry_run: (bool) whether to actually submit the try request. |
| 347 file_list: (list of strings) list of filenames to pass to `git add`. | 180 """ |
| 181 git_try = [ |
| 182 git_utils.GIT, 'cl', 'try', '-m', 'tryserver.chromium'] |
| 183 git_try.extend([arg for bot in bots_to_run for arg in ('-b', bot)]) |
| 348 | 184 |
| 349 Returns: | 185 if dry_run: |
| 350 The output of `git cl issue`, if not config.skip_cl_upload, else ''. | |
| 351 """ | |
| 352 | |
| 353 git, vsp = config.git, config.vsp | |
| 354 svn_info = str(get_svn_revision(config, 'HEAD')) | |
| 355 | |
| 356 for filename in file_list: | |
| 357 assert os.path.exists(filename) | |
| 358 vsp.check_call([git, 'add', filename]) | |
| 359 | |
| 360 vsp.check_call([git, 'commit', '-q', '-m', message]) | |
| 361 | |
| 362 git_cl = [git, 'cl', 'upload', '-f', | |
| 363 '--bypass-hooks', '--bypass-watchlists'] | |
| 364 if config.cc_list: | |
| 365 git_cl.append('--cc=%s' % config.cc_list) | |
| 366 if config.reviewers_list: | |
| 367 git_cl.append('--reviewers=%s' % config.reviewers_list) | |
| 368 | |
| 369 git_try = [ | |
| 370 git, 'cl', 'try', '-m', 'tryserver.chromium', '--revision', svn_info] | |
| 371 git_try.extend([arg for bot in config.cl_bot_list for arg in ('-b', bot)]) | |
| 372 | |
| 373 branch_name = git_utils.git_branch_name(vsp.verbose) | |
| 374 | |
| 375 if config.skip_cl_upload: | |
| 376 space = ' ' | 186 space = ' ' |
| 377 print 'You should call:' | 187 print 'You should call:' |
| 378 print '%scd %s' % (space, os.getcwd()) | 188 print space, git_try |
| 379 misc_utils.print_subprocess_args(space, [git, 'checkout', branch_name]) | |
| 380 misc_utils.print_subprocess_args(space, git_cl) | |
| 381 if config.cl_bot_list: | |
| 382 misc_utils.print_subprocess_args(space, git_try) | |
| 383 print | 189 print |
| 384 return '' | |
| 385 else: | 190 else: |
| 386 vsp.check_call(git_cl) | 191 shell_utils.run(git_try) |
| 387 issue = vsp.strip_output([git, 'cl', 'issue']) | |
| 388 if config.cl_bot_list: | |
| 389 vsp.check_call(git_try) | |
| 390 return issue | |
| 391 | 192 |
| 392 | 193 |
| 393 def roll_deps(config, revision, git_hash): | 194 def roll_deps(config, revision): |
| 394 """Upload changed DEPS and a whitespace change. | 195 """Upload changed DEPS and a whitespace change. |
| 395 | 196 |
| 396 Given the correct git_hash, create two Reitveld issues. | 197 Given the correct git_hash, create two Reitveld issues. |
| 397 | 198 |
| 398 Args: | 199 Args: |
| 399 config: (roll_deps.DepsRollConfig) object containing options. | 200 config: (roll_deps.DepsRollConfig) object containing options. |
| 400 revision: (int) Skia SVN revision. | 201 revision: (string) Skia Git hash. |
| 401 git_hash: (string) Skia Git hash. | |
| 402 | 202 |
| 403 Returns: | 203 Returns: |
| 404 a tuple containing textual description of the two issues. | 204 a tuple containing textual description of the two issues. |
| 405 | 205 |
| 406 Raises: | 206 Raises: |
| 407 OSError: failed to execute git or git-cl. | 207 OSError: failed to execute git or git-cl. |
| 408 subprocess.CalledProcessError: git returned unexpected status. | 208 subprocess.CalledProcessError: git returned unexpected status. |
| 409 """ | 209 """ |
| 410 | 210 |
| 411 git = config.git | 211 with misc.ChDir(config.chromium_path, verbose=config.verbose): |
| 412 with misc_utils.ChangeDir(config.chromium_path, config.verbose): | 212 git_utils.Fetch() |
| 413 config.vsp.check_call([git, 'fetch', '-q', 'origin']) | 213 output = shell_utils.run([git_utils.GIT, 'show', 'origin/master:DEPS'], |
| 214 log_in_real_time=False).rstrip() |
| 215 match = re.search(REGEXP_SKIA_REVISION, output, flags=re.MULTILINE) |
| 216 old_revision = None |
| 217 if match: |
| 218 old_revision = match.group('revision') |
| 219 assert old_revision |
| 414 | 220 |
| 415 old_revision = misc_utils.ReSearch.search_within_output( | 221 master_hash = git_utils.FullHash('origin/master').rstrip() |
| 416 config.verbose, '"skia_revision": "(?P<return>[0-9]+)",', None, | |
| 417 [git, 'show', 'origin/master:DEPS']) | |
| 418 assert old_revision | |
| 419 if revision == int(old_revision): | |
| 420 print 'DEPS is up to date!' | |
| 421 return (None, None) | |
| 422 | |
| 423 master_hash = config.vsp.strip_output( | |
| 424 [git, 'show-ref', 'origin/master', '--hash']) | |
| 425 master_revision = get_svn_revision(config, 'origin/master') | |
| 426 | 222 |
| 427 # master_hash[8] gives each whitespace CL a unique name. | 223 # master_hash[8] gives each whitespace CL a unique name. |
| 428 if config.save_branches: | 224 branch = 'control_%s' % master_hash[:8] |
| 429 branch = 'control_%s' % master_hash[:8] | |
| 430 else: | |
| 431 branch = None | |
| 432 message = ('whitespace change %s\n\n' | 225 message = ('whitespace change %s\n\n' |
| 433 'Chromium base revision: %d / %s\n\n' | 226 'Chromium base revision: %s\n\n' |
| 434 'This CL was created by Skia\'s roll_deps.py script.\n' | 227 'This CL was created by Skia\'s roll_deps.py script.\n' |
| 435 ) % (master_hash[:8], master_revision, master_hash[:8]) | 228 ) % (master_hash[:8], master_hash[:8]) |
| 436 with git_utils.ChangeGitBranch(branch, 'origin/master', | 229 with git_utils.GitBranch(branch, message, |
| 437 config.verbose): | 230 delete_when_finished=not config.save_branches, |
| 438 branch = git_utils.git_branch_name(config.vsp.verbose) | 231 upload=not config.skip_cl_upload |
| 232 ) as whitespace_branch: |
| 233 branch = git_utils.GetCurrentBranch() |
| 234 with open(os.path.join('build', 'whitespace_file.txt'), 'a') as f: |
| 235 f.write('\nCONTROL\n') |
| 439 | 236 |
| 440 with open('build/whitespace_file.txt', 'a') as output_stream: | 237 control_url = whitespace_branch.commit_and_upload() |
| 441 output_stream.write('\nCONTROL\n') | 238 if config.cl_bot_list: |
| 239 submit_tries(config.cl_bot_list, dry_run=config.skip_cl_upload) |
| 240 whitespace_cl = control_url |
| 241 if config.save_branches: |
| 242 whitespace_cl += '\n branch: %s' % branch |
| 442 | 243 |
| 443 whitespace_cl = git_cl_uploader( | 244 branch = 'roll_%s_%s' % (revision, master_hash[:8]) |
| 444 config, message, ['build/whitespace_file.txt']) | |
| 445 | |
| 446 control_url = misc_utils.ReSearch.search_within_string( | |
| 447 whitespace_cl, '(?P<return>https?://[^) ]+)', '?') | |
| 448 if config.save_branches: | |
| 449 whitespace_cl = '%s\n branch: %s' % (whitespace_cl, branch) | |
| 450 | |
| 451 if config.save_branches: | |
| 452 branch = 'roll_%d_%s' % (revision, master_hash[:8]) | |
| 453 else: | |
| 454 branch = None | |
| 455 message = ( | 245 message = ( |
| 456 'roll skia DEPS to %d\n\n' | 246 'roll skia DEPS to %s\n\n' |
| 457 'Chromium base revision: %d / %s\n' | 247 'Chromium base revision: %s\n' |
| 458 'Old Skia revision: %s\n' | 248 'Old Skia revision: %s\n' |
| 459 'New Skia revision: %d\n' | 249 'New Skia revision: %s\n' |
| 460 'Control CL: %s\n\n' | 250 'Control CL: %s\n\n' |
| 461 'This CL was created by Skia\'s roll_deps.py script.\n\n' | 251 'This CL was created by Skia\'s roll_deps.py script.\n\n' |
| 462 'Bypassing commit queue trybots:\n' | 252 'Bypassing commit queue trybots:\n' |
| 463 'NOTRY=true\n' | 253 'NOTRY=true\n' |
| 464 % (revision, master_revision, master_hash[:8], | 254 % (revision, master_hash[:8], |
| 465 old_revision, revision, control_url)) | 255 old_revision[:8], revision[:8], control_url)) |
| 466 with git_utils.ChangeGitBranch(branch, 'origin/master', | 256 with git_utils.GitBranch(branch, message, |
| 467 config.verbose): | 257 delete_when_finished=not config.save_branches, |
| 468 branch = git_utils.git_branch_name(config.vsp.verbose) | 258 upload=not config.skip_cl_upload |
| 469 | 259 ) as roll_branch: |
| 470 change_skia_deps(revision, git_hash, 'DEPS') | 260 change_skia_deps(revision, 'DEPS') |
| 471 deps_cl = git_cl_uploader(config, message, ['DEPS']) | 261 deps_url = roll_branch.commit_and_upload() |
| 262 if config.cl_bot_list: |
| 263 submit_tries(config.cl_bot_list, dry_run=config.skip_cl_upload) |
| 264 deps_cl = deps_url |
| 472 if config.save_branches: | 265 if config.save_branches: |
| 473 deps_cl = '%s\n branch: %s' % (deps_cl, branch) | 266 deps_cl += '\n branch: %s' % branch |
| 474 | 267 |
| 475 return deps_cl, whitespace_cl | 268 return deps_cl, whitespace_cl |
| 476 | 269 |
| 477 | 270 |
| 478 def find_hash_and_roll_deps(config, revision=None, partial_hash=None): | |
| 479 """Call find_hash_from_revision() and roll_deps(). | |
| 480 | |
| 481 The calls to git will be verbose on standard output. After a | |
| 482 successful upload of both issues, print links to the new | |
| 483 codereview issues. | |
| 484 | |
| 485 Args: | |
| 486 config: (roll_deps.DepsRollConfig) object containing options. | |
| 487 revision: (int or None) the Skia SVN revision number or None | |
| 488 to use the tip of the tree. | |
| 489 partial_hash: (string or None) a partial pure-git Skia commit | |
| 490 hash. Don't pass both partial_hash and revision. | |
| 491 | |
| 492 Raises: | |
| 493 roll_deps.DepsRollError: if the revision can't be found. | |
| 494 OSError: failed to execute git or git-cl. | |
| 495 subprocess.CalledProcessError: git returned unexpected status. | |
| 496 """ | |
| 497 | |
| 498 if revision and partial_hash: | |
| 499 raise DepsRollError('Pass revision or partial_hash, not both.') | |
| 500 | |
| 501 if partial_hash: | |
| 502 revision, git_hash = revision_and_hash_from_partial( | |
| 503 config, partial_hash) | |
| 504 elif revision: | |
| 505 revision, git_hash = revision_and_hash_from_revision(config, revision) | |
| 506 else: | |
| 507 revision, git_hash = revision_and_hash(config) | |
| 508 | |
| 509 print 'revision=%r\nhash=%r\n' % (revision, git_hash) | |
| 510 | |
| 511 deps_issue, whitespace_issue = roll_deps(config, revision, git_hash) | |
| 512 | |
| 513 if deps_issue and whitespace_issue: | |
| 514 print 'DEPS roll:\n %s\n' % deps_issue | |
| 515 print 'Whitespace change:\n %s\n' % whitespace_issue | |
| 516 else: | |
| 517 print >> sys.stderr, 'No issues created.' | |
| 518 | |
| 519 | |
| 520 def main(args): | 271 def main(args): |
| 521 """main function; see module-level docstring and GetOptionParser help. | 272 """main function; see module-level docstring and GetOptionParser help. |
| 522 | 273 |
| 523 Args: | 274 Args: |
| 524 args: sys.argv[1:]-type argument list. | 275 args: sys.argv[1:]-type argument list. |
| 525 """ | 276 """ |
| 526 option_parser = DepsRollConfig.GetOptionParser() | 277 option_parser = DepsRollConfig.GetOptionParser() |
| 527 options = option_parser.parse_args(args)[0] | 278 options = option_parser.parse_args(args)[0] |
| 528 | 279 |
| 280 if not options.revision: |
| 281 option_parser.error('Must specify a revision.') |
| 529 if not options.chromium_path: | 282 if not options.chromium_path: |
| 530 option_parser.error('Must specify chromium_path.') | 283 option_parser.error('Must specify chromium_path.') |
| 531 if not os.path.isdir(options.chromium_path): | 284 if not os.path.isdir(options.chromium_path): |
| 532 option_parser.error('chromium_path must be a directory.') | 285 option_parser.error('chromium_path must be a directory.') |
| 533 | 286 |
| 534 if not git_utils.git_executable(): | 287 config = DepsRollConfig(options) |
| 535 option_parser.error('Invalid git executable.') | 288 shell_utils.VERBOSE = options.verbose |
| 289 deps_issue, whitespace_issue = roll_deps(config, options.revision) |
| 536 | 290 |
| 537 config = DepsRollConfig(options) | 291 if deps_issue and whitespace_issue: |
| 538 find_hash_and_roll_deps(config, options.revision, options.git_hash) | 292 print 'DEPS roll:\n %s\n' % deps_issue |
| 293 print 'Whitespace change:\n %s\n' % whitespace_issue |
| 294 else: |
| 295 print >> sys.stderr, 'No issues created.' |
| 539 | 296 |
| 540 | 297 |
| 541 if __name__ == '__main__': | 298 if __name__ == '__main__': |
| 542 main(sys.argv[1:]) | 299 main(sys.argv[1:]) |
| 543 | |
| OLD | NEW |