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 |