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

Unified Diff: tools/roll_deps.py

Issue 123523003: DEPS roll script (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: lots of refactoring Created 6 years, 12 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/roll_deps.py
diff --git a/tools/roll_deps.py b/tools/roll_deps.py
new file mode 100755
index 0000000000000000000000000000000000000000..10051cf9c95e3f845cd1e35ccbdc9a9b8e9b1f32
--- /dev/null
+++ b/tools/roll_deps.py
@@ -0,0 +1,184 @@
+#!/usr/bin/python
+
+# Copyright 2014 Google Inc.
+#
+# Use of this source code is governed by a BSD-style license that can be
jcgregorio 2014/01/03 16:46:20 Needs a longer description of what this script doe
hal.canary 2014/01/03 21:06:15 Done.
+# found in the LICENSE file.
+
+
+import optparse
+import os
+import random
+import re
+import subprocess
+import shutil
+import sys
+import tempfile
+
+
+GIT = 'git' # Assume git is in your path. Change this otherwise.
borenet 2014/01/03 18:15:48 On the bots (and anywhere with depot_tools in the
hal.canary 2014/01/03 21:06:15 I've made it an option.
+
+
+def find_hash_from_revision(revision, search_depth):
+ '''
jcgregorio 2014/01/03 16:46:20 """Finds the hash associated with a revision. Sea
hal.canary 2014/01/03 21:06:15 Done.
+ Searches through the last N commits to find out the hash that is
+ associated with the revision number.
+ '''
borenet 2014/01/03 18:15:48 Please update your docstrings to follow this forma
hal.canary 2014/01/03 21:06:15 Done.
+ SKIA_URL = 'https://skia.googlesource.com/skia.git'
borenet 2014/01/03 18:15:48 This can go outside, at the module level. There's
hal.canary 2014/01/03 23:58:48 Let's figure out our use-case for modifying the ur
+ temp_dir = tempfile.mkdtemp(prefix='git_skia_tmp_')
+ devnull = open(os.devnull, "w")
borenet 2014/01/03 18:15:48 Is this just to avoid seeing output from the subpr
hal.canary 2014/01/03 21:06:15 That's why they introduced subprocess.DEVNULL!
+ try:
+ if 0 != subprocess.call([
+ GIT, 'clone', '--depth=%d' % search_depth, '--single-branch',
+ SKIA_URL, temp_dir], stdout=devnull, stderr=devnull):
+ raise Exception("Failed to grab a copy of Skia.")
borenet 2014/01/03 18:15:48 Why not use subprocess.check_call, which will rais
hal.canary 2014/01/03 21:06:15 Done.
+ for i in xrange(search_depth):
+ commit = 'origin/master~%d' % i
+ proc = subprocess.Popen([
+ GIT, 'log', '-n', '1', '--format=format:%B', commit],
+ cwd=temp_dir, stdout=subprocess.PIPE,
+ stderr=devnull)
+ revision_format = 'http://skia.googlecode.com/svn/trunk@%d'
+ revision_regex = re.compile(revision_format % revision)
+ for line in proc.stdout:
borenet 2014/01/03 18:15:48 I think it's a good idea to use proc.wait() before
hal.canary 2014/01/03 21:06:15 In theory,the output could be very long, but in pr
+ if revision_regex.search(line) is not None:
+ proc.stdout.close()
+ return subprocess.check_output([
+ GIT, 'log', '-n', '1', '--format=format:%H',
+ commit], cwd=temp_dir).strip()
+ finally:
+ shutil.rmtree(temp_dir)
+ devnull.close()
+ raise Exception('Failed to find revision.')
+
+
+def checkout_master():
+ '''
+ Stashes current changes if necessary, checkout master, pulls from
+ origin, and returns hash of current revision, plus arguments to be
+ passed to restore_repository to reture to original state.
borenet 2014/01/03 18:15:48 sp: "return"?
hal.canary 2014/01/03 21:06:15 Done.
+ '''
+ # Assumes the current directory is a git repository and master is
+ # tracking an upstream branch.
+ stash = (0 != len(subprocess.check_output([GIT, 'diff', '--shortstat'])))
+ if stash:
+ subprocess.check_call([GIT, 'stash', 'save'])
borenet 2014/01/03 18:15:48 Since this is (mostly) going to be run by bots, I
hal.canary 2014/01/03 21:06:15 This may be run by anyone who wants to force a DEP
+ old_branch = subprocess.check_output([GIT, 'symbolic-ref', '--short',
+ 'HEAD']).strip()
borenet 2014/01/03 18:15:48 nit: indent
+ if old_branch != 'master':
+ subprocess.check_call([GIT, 'checkout', 'master'])
+ subprocess.check_call([GIT, 'pull'])
+ master_hash = subprocess.check_output([GIT, 'show-ref', 'HEAD', '--hash'])
+ return master_hash.strip(), (old_branch, stash)
borenet 2014/01/03 18:15:48 I think it's a little confusing to return a tuple
hal.canary 2014/01/03 21:06:15 I've refactored.
+
+
+def restore_repository(restore):
borenet 2014/01/03 18:15:48 Please add docstrings for this and the other funct
hal.canary 2014/01/03 21:06:15 Done.
+ (old_branch, stash) = restore
borenet 2014/01/03 18:15:48 Why not take old_branch and stash as parameters to
hal.canary 2014/01/03 23:58:48 (refactored away)
+ if old_branch != 'master':
+ subprocess.check_call([GIT, 'checkout', old_branch])
+ if stash:
+ subprocess.check_call([GIT, 'stash', 'pop'])
+
+
+def change_skia_deps(revision, hashval, depspath):
+ temp_file = tempfile.NamedTemporaryFile(delete=False,
+ prefix='skia_DEPS_ROLL_tmp_')
borenet 2014/01/03 18:15:48 nit: indent
+ try:
+ deps_regex_rev = re.compile('"skia_revision": "[0-9]*",')
+ deps_regex_hash = re.compile('"skia_hash": "[0-9a-f]*",')
+
+ deps_regex_rev_repl = '"skia_revision": "{}",'.format(revision)
+ deps_regex_hash_repl = '"skia_hash": "{}",'.format(hashval)
borenet 2014/01/03 18:15:48 Same comment about the format strings as before...
hal.canary 2014/01/03 21:06:15 I missed those. Done.
+
+ with open(depspath, 'r') as f:
+ for line in f:
+ line = deps_regex_rev.sub(deps_regex_rev_repl, line)
+ line = deps_regex_hash.sub(deps_regex_hash_repl, line)
+ temp_file.write(line)
borenet 2014/01/03 18:15:48 Optional: You can entirely avoid using a temporary
+ finally:
+ temp_file.close()
+ shutil.move(temp_file.name, depspath)
+
+
+def git_branch_add_commit_cl_upload(file_list, message):
+ old_branch = subprocess.check_output([GIT, 'symbolic-ref', '--short',
+ 'HEAD']).strip()
borenet 2014/01/03 18:15:48 nit: indent
+ branch_name = 'tmp_%d' % random.randrange(1<<16)
borenet 2014/01/03 18:15:48 A timestamp would work well here. Alternatively,
hal.canary 2014/01/03 21:06:15 Done.
+ subprocess.check_call([GIT, 'checkout', '-b', branch_name])
+ args = [GIT, 'add']
+ args.extend(file_list)
borenet 2014/01/03 18:15:48 Since we're on a clean branch, it's probably okay
hal.canary 2014/01/03 21:06:15 Done.
hal.canary 2014/01/03 23:58:48 Well, that broke the git submodules in some weird
+ subprocess.check_call(args)
+ subprocess.check_call([GIT, 'commit', '-m', message])
+ subprocess.check_call([GIT, 'cl', 'upload'])
+ issue = subprocess.check_output([GIT, 'cl', 'issue']).strip()
+ subprocess.check_call([GIT, 'checkout', old_branch])
+ subprocess.check_call([GIT, 'branch', '-D', branch_name])
+ return issue
+
+
+def add_whitespace_change(file_name):
+ with open(file_name, 'a') as o:
+ o.write('\n')
+
+
+def roll_deps(revision, hashval, chromium_dir):
+ os.chdir(chromium_dir)
+
+ master_hash, restore = checkout_master()
+ message = 'roll skia DEPS to %d' % revision
+ change_skia_deps(revision, hashval, 'DEPS')
+ deps_issue = git_branch_add_commit_cl_upload(['DEPS'], message)
+
+ message = 'whitespace change %s' % master_hash[:8] # Unique name
+ add_whitespace_change('whitespace.txt')
+ whitespace_issue = git_branch_add_commit_cl_upload(['whitespace.txt'],
+ message)
borenet 2014/01/03 18:15:48 nit: indent
+ restore_repository(restore)
+ print '\n'
+ print 'DEPS roll:\n %s\n' % deps_issue
+ print 'Whitespace change:\n %s\n' % whitespace_issue
+
+
+def find_hash_and_roll_deps(revision, chromium_dir, search_depth):
+ hashval = find_hash_from_revision(revision, search_depth)
+ if hashval is None:
+ raise Exception('failed to find revision')
+
+ print 'revision=@%d hash=%s\n' % (revision, hashval)
+
+ roll_deps(revision, hashval, chromium_dir)
+
+
+def main(args):
+ usage = 'Usage: %prog -c CHROMIUM_PATH -r REVISION'
+
+ # Anyone using this script on a regular basis should set this
+ # environment variable.
+ chromium_repo_path_env = os.environ['CHROMIUM_REPO_PATH'] if (
jcgregorio 2014/01/03 16:46:20 Use: chromium_repo_path_env = os.environ.get('C
hal.canary 2014/01/03 21:06:15 Done.
+ 'CHROMIUM_REPO_PATH' in os.environ) else None
borenet 2014/01/03 18:15:48 Python supports defaults in dict retrieval: chromi
hal.canary 2014/01/03 21:06:15 Done.
+
+ option_parser = optparse.OptionParser(usage=usage)
+ option_parser.add_option(
+ '-c', '--chromium_path', help='Path to Chromium Git repository.',
+ default=chromium_repo_path_env)
+ option_parser.add_option(
+ '-r', '--revision', help='The Skia revision number', type="int")
+ option_parser.add_option(
+ '', '--search_depth', help='How far back to look for the revision',
+ type="int", default=100)
+ options = option_parser.parse_args(args)[0]
+
+ if (not options.revision and not options.chromium_path):
+ option_parser.error('Must specify revision and chromium_path.')
+ if (not options.revision):
+ option_parser.error('Must specify revision.')
+ if (not options.chromium_path):
+ option_parser.error('Must specify chromium_path.')
+
+ find_hash_and_roll_deps(options.revision, options.chromium_path,
+ options.search_depth)
borenet 2014/01/03 18:15:48 nit: indent
hal.canary 2014/01/03 21:06:15 Done.
+
+
+if __name__ == '__main__':
+ main(sys.argv[1:])
+
« 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