Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(287)

Side by Side Diff: roll_dep.py

Issue 564363003: roll-dep: If applicable, include svn revision range in commit message (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: Trim commit msg, use "git rev-parse --short" Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2014 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2014 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """This scripts takes the path to a dep and an svn revision, and updates the 6 """This scripts takes the path to a dep and an svn revision, and updates the
7 parent repo's DEPS file with the corresponding git revision. Sample invocation: 7 parent repo's DEPS file with the corresponding git revision. Sample invocation:
8 8
9 [chromium/src]$ roll-dep third_party/WebKit 12345 9 [chromium/src]$ roll-dep third_party/WebKit 12345
10 10
11 After the script completes, the DEPS file will be dirty with the new revision. 11 After the script completes, the DEPS file will be dirty with the new revision.
12 The user can then: 12 The user can then:
13 13
14 $ git add DEPS 14 $ git add DEPS
15 $ git commit 15 $ git commit
16 """ 16 """
17 17
18 import ast 18 import ast
19 import os 19 import os
20 import re 20 import re
21 import sys 21 import sys
22 22
23 from itertools import izip 23 from itertools import izip
24 from subprocess import Popen, PIPE 24 from subprocess import check_output, Popen, PIPE
25 from textwrap import dedent 25 from textwrap import dedent
26 26
27 27
28 SHA1_RE = re.compile('^[a-fA-F0-9]{40}$') 28 SHA1_RE = re.compile('^[a-fA-F0-9]{40}$')
29 GIT_SVN_ID_RE = re.compile('^git-svn-id: .*@([0-9]+) .*$') 29 GIT_SVN_ID_RE = re.compile('^git-svn-id: .*@([0-9]+) .*$')
30 ROLL_DESCRIPTION_STR = '''Roll %s from %s to %s 30 ROLL_DESCRIPTION_STR = (
31 '''Roll %(dep_path)s %(before_rev)s:%(after_rev)s%(svn_range)s
31 32
32 Summary of changes available at: 33 Summary of changes available at:
33 %s 34 %(revlog_url)s
34 ''' 35 ''')
35 36
36 37
37 def shorten_dep_path(dep): 38 def shorten_dep_path(dep):
38 """Shorten the given dep path if necessary.""" 39 """Shorten the given dep path if necessary."""
39 while len(dep) > 31: 40 while len(dep) > 31:
40 dep = '.../' + dep.lstrip('./').partition('/')[2] 41 dep = '.../' + dep.lstrip('./').partition('/')[2]
41 return dep 42 return dep
42 43
43 44
44 def posix_path(path): 45 def posix_path(path):
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 git revision.""" 249 git revision."""
249 vars_node = find_deps_section(deps_ast, 'vars') 250 vars_node = find_deps_section(deps_ast, 'vars')
250 assert vars_node, 'Could not find "vars" section of DEPS file.' 251 assert vars_node, 'Could not find "vars" section of DEPS file.'
251 var_idx = find_dict_index(vars_node, var_name) 252 var_idx = find_dict_index(vars_node, var_name)
252 assert var_idx is not None, ( 253 assert var_idx is not None, (
253 'Could not find definition of "%s" var in DEPS file.' % var_name) 254 'Could not find definition of "%s" var in DEPS file.' % var_name)
254 val_node = vars_node.values[var_idx] 255 val_node = vars_node.values[var_idx]
255 return update_node(deps_lines, deps_ast, val_node, git_revision) 256 return update_node(deps_lines, deps_ast, val_node, git_revision)
256 257
257 258
258 def generate_commit_message(deps_section, dep_name, new_rev): 259 def short_rev(rev, dep_path):
260 return check_output(['git', 'rev-parse', '--short', rev],
261 cwd=dep_path).rstrip()
262
263
264 def generate_commit_message(deps_section, dep_path, dep_name, new_rev):
259 (url, _, old_rev) = deps_section[dep_name].partition('@') 265 (url, _, old_rev) = deps_section[dep_name].partition('@')
260 if url.endswith('.git'): 266 if url.endswith('.git'):
261 url = url[:-4] 267 url = url[:-4]
262 url += '/+log/%s..%s' % (old_rev[:12], new_rev[:12]) 268 old_rev_short = short_rev(old_rev, dep_path)
263 return dedent(ROLL_DESCRIPTION_STR % ( 269 new_rev_short = short_rev(new_rev, dep_path)
264 shorten_dep_path(dep_name), old_rev[:12], new_rev[:12], url)) 270 url += '/+log/%s..%s' % (old_rev_short, new_rev_short)
271 old_svn_rev = get_svn_revision(dep_path, old_rev)
272 new_svn_rev = get_svn_revision(dep_path, new_rev)
273 svn_range_str = ''
274 if old_svn_rev and new_svn_rev:
275 svn_range_str = ' (svn %s:%s)' % (old_svn_rev, new_svn_rev)
276 return dedent(ROLL_DESCRIPTION_STR % {
277 'dep_path': shorten_dep_path(dep_name),
278 'before_rev': old_rev_short,
279 'after_rev': new_rev_short,
280 'svn_range': svn_range_str,
281 'revlog_url': url,
282 })
265 283
266 def update_deps_entry(deps_lines, deps_ast, value_node, new_rev, comment): 284 def update_deps_entry(deps_lines, deps_ast, value_node, new_rev, comment):
267 line_idx = update_node(deps_lines, deps_ast, value_node, new_rev) 285 line_idx = update_node(deps_lines, deps_ast, value_node, new_rev)
268 (content, _, _) = deps_lines[line_idx].partition('#') 286 (content, _, _) = deps_lines[line_idx].partition('#')
269 if comment: 287 if comment:
270 deps_lines[line_idx] = '%s # %s' % (content.rstrip(), comment) 288 deps_lines[line_idx] = '%s # %s' % (content.rstrip(), comment)
271 else: 289 else:
272 deps_lines[line_idx] = content.rstrip() 290 deps_lines[line_idx] = content.rstrip()
273 291
274 def update_deps(soln_path, dep_name, new_rev, comment): 292 def update_deps(soln_path, dep_path, dep_name, new_rev, comment):
275 """Update the DEPS file with the new git revision.""" 293 """Update the DEPS file with the new git revision."""
276 commit_msg = '' 294 commit_msg = ''
277 deps_file = os.path.join(soln_path, 'DEPS') 295 deps_file = os.path.join(soln_path, 'DEPS')
278 with open(deps_file) as fh: 296 with open(deps_file) as fh:
279 deps_content = fh.read() 297 deps_content = fh.read()
280 deps_locals = {} 298 deps_locals = {}
281 def _Var(key): 299 def _Var(key):
282 return deps_locals['vars'][key] 300 return deps_locals['vars'][key]
283 deps_locals['Var'] = _Var 301 deps_locals['Var'] = _Var
284 exec deps_content in {}, deps_locals 302 exec deps_content in {}, deps_locals
285 deps_lines = deps_content.splitlines() 303 deps_lines = deps_content.splitlines()
286 deps_ast = ast.parse(deps_content, deps_file) 304 deps_ast = ast.parse(deps_content, deps_file)
287 deps_node = find_deps_section(deps_ast, 'deps') 305 deps_node = find_deps_section(deps_ast, 'deps')
288 assert deps_node, 'Could not find "deps" section of DEPS file' 306 assert deps_node, 'Could not find "deps" section of DEPS file'
289 dep_idx = find_dict_index(deps_node, dep_name) 307 dep_idx = find_dict_index(deps_node, dep_name)
290 if dep_idx is not None: 308 if dep_idx is not None:
291 value_node = deps_node.values[dep_idx] 309 value_node = deps_node.values[dep_idx]
292 update_deps_entry(deps_lines, deps_ast, value_node, new_rev, comment) 310 update_deps_entry(deps_lines, deps_ast, value_node, new_rev, comment)
293 commit_msg = generate_commit_message(deps_locals['deps'], dep_name, new_rev) 311 commit_msg = generate_commit_message(deps_locals['deps'], dep_path,
312 dep_name, new_rev)
294 deps_os_node = find_deps_section(deps_ast, 'deps_os') 313 deps_os_node = find_deps_section(deps_ast, 'deps_os')
295 if deps_os_node: 314 if deps_os_node:
296 for (os_name, os_node) in izip(deps_os_node.keys, deps_os_node.values): 315 for (os_name, os_node) in izip(deps_os_node.keys, deps_os_node.values):
297 dep_idx = find_dict_index(os_node, dep_name) 316 dep_idx = find_dict_index(os_node, dep_name)
298 if dep_idx is not None: 317 if dep_idx is not None:
299 value_node = os_node.values[dep_idx] 318 value_node = os_node.values[dep_idx]
300 if value_node.__class__ is ast.Name and value_node.id == 'None': 319 if value_node.__class__ is ast.Name and value_node.id == 'None':
301 pass 320 pass
302 else: 321 else:
303 update_deps_entry(deps_lines, deps_ast, value_node, new_rev, comment) 322 update_deps_entry(deps_lines, deps_ast, value_node, new_rev, comment)
304 commit_msg = generate_commit_message( 323 commit_msg = generate_commit_message(
305 deps_locals['deps_os'][os_name], dep_name, new_rev) 324 deps_locals['deps_os'][os_name], dep_path, dep_name, new_rev)
306 if commit_msg: 325 if commit_msg:
307 print 'Pinning %s' % dep_name 326 print 'Pinning %s' % dep_name
308 print 'to revision %s' % new_rev 327 print 'to revision %s' % new_rev
309 print 'in %s' % deps_file 328 print 'in %s' % deps_file
310 with open(deps_file, 'w') as fh: 329 with open(deps_file, 'w') as fh:
311 for line in deps_lines: 330 for line in deps_lines:
312 print >> fh, line 331 print >> fh, line
313 with open(os.path.join(soln_path, '.git', 'MERGE_MSG'), 'a') as fh: 332 with open(os.path.join(soln_path, '.git', 'MERGE_MSG'), 'a') as fh:
314 fh.write(commit_msg) 333 fh.write(commit_msg)
315 else: 334 else:
316 print 'Could not find an entry in %s to update.' % deps_file 335 print 'Could not find an entry in %s to update.' % deps_file
317 return 0 if commit_msg else 1 336 return 0 if commit_msg else 1
318 337
319 338
320 def main(argv): 339 def main(argv):
321 if len(argv) != 2 : 340 if len(argv) != 2 :
322 print >> sys.stderr, 'Usage: roll_dep.py <dep path> <svn revision>' 341 print >> sys.stderr, 'Usage: roll_dep.py <dep path> <svn revision>'
323 return 1 342 return 1
324 (dep_path, revision) = argv[0:2] 343 (dep_path, revision) = argv[0:2]
325 dep_path = platform_path(dep_path) 344 dep_path = platform_path(dep_path)
326 assert os.path.isdir(dep_path), 'No such directory: %s' % dep_path 345 assert os.path.isdir(dep_path), 'No such directory: %s' % dep_path
327 gclient_root = find_gclient_root() 346 gclient_root = find_gclient_root()
328 soln = get_solution(gclient_root, dep_path) 347 soln = get_solution(gclient_root, dep_path)
329 soln_path = os.path.relpath(os.path.join(gclient_root, soln['name'])) 348 soln_path = os.path.relpath(os.path.join(gclient_root, soln['name']))
330 dep_name = posix_path(os.path.relpath(dep_path, gclient_root)) 349 dep_name = posix_path(os.path.relpath(dep_path, gclient_root))
331 (git_rev, svn_rev) = get_git_revision(dep_path, revision) 350 (git_rev, svn_rev) = get_git_revision(dep_path, revision)
332 comment = ('from svn revision %s' % svn_rev) if svn_rev else None 351 comment = ('from svn revision %s' % svn_rev) if svn_rev else None
333 assert git_rev, 'Could not find git revision matching %s.' % revision 352 assert git_rev, 'Could not find git revision matching %s.' % revision
334 return update_deps(soln_path, dep_name, git_rev, comment) 353 return update_deps(soln_path, dep_path, dep_name, git_rev, comment)
335 354
336 if __name__ == '__main__': 355 if __name__ == '__main__':
337 sys.exit(main(sys.argv[1:])) 356 sys.exit(main(sys.argv[1:]))
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698