diff --git a/roll_dep.py b/roll_dep.py index 32930f670..4b4f4f6fb 100755 --- a/roll_dep.py +++ b/roll_dep.py @@ -18,6 +18,8 @@ import subprocess import sys NEED_SHELL = sys.platform.startswith('win') +GCLIENT_PATH = os.path.join( + os.path.dirname(os.path.abspath(__file__)), 'gclient.py') class Error(Exception): @@ -70,22 +72,9 @@ def should_show_log(upstream_url): return True -def get_gclient_root(): - gclient = os.path.join( - os.path.dirname(os.path.abspath(__file__)), 'gclient.py') - return check_output([sys.executable, gclient, 'root']).strip() - - -def get_deps(root): - """Returns the path and the content of the DEPS file.""" - deps_path = os.path.join(root, 'DEPS') - try: - with open(deps_path, 'rb') as f: - deps_content = f.read() - except (IOError, OSError): - raise Error('Ensure the script is run in the directory ' - 'containing DEPS file.') - return deps_path, deps_content +def gclient(args): + """Executes gclient with the given args and returns the stdout.""" + return check_output([sys.executable, GCLIENT_PATH] + args).strip() def generate_commit_message( @@ -130,11 +119,11 @@ def generate_commit_message( return header + log_section -def calculate_roll(full_dir, dependency, gclient_dict, roll_to): +def calculate_roll(full_dir, dependency, roll_to): """Calculates the roll for a dependency by processing gclient_dict, and fetching the dependency via git. """ - head = gclient_eval.GetRevision(gclient_dict, dependency) + head = gclient(['getdep', '-r', dependency]) if not head: raise Error('%s is unpinned.' % dependency) check_call(['git', 'fetch', 'origin', '--quiet'], cwd=full_dir) @@ -154,21 +143,17 @@ def gen_commit_msg(logs, cmdline, reviewers, bug): return commit_msg -def finalize(commit_msg, deps_path, deps_content, rolls, root_dir): - """Edits the DEPS file, commits it, then uploads a CL.""" +def finalize(commit_msg, current_dir, rolls): + """Commits changes to the DEPS file, then uploads a CL.""" print('Commit message:') print('\n'.join(' ' + i for i in commit_msg.splitlines())) - with open(deps_path, 'wb') as f: - f.write(deps_content) - current_dir = os.path.dirname(deps_path) check_call(['git', 'add', 'DEPS'], cwd=current_dir) check_call(['git', 'commit', '--quiet', '-m', commit_msg], cwd=current_dir) # Pull the dependency to the right revision. This is surprising to users # otherwise. - for dependency, (_head, roll_to) in sorted(rolls.iteritems()): - full_dir = os.path.normpath(os.path.join(root_dir, dependency)) + for _head, roll_to, full_dir in sorted(rolls.itervalues()): check_call(['git', 'checkout', '--quiet', roll_to], cwd=full_dir) @@ -213,7 +198,7 @@ def main(): if not '@' in r: reviewers[i] = r + '@chromium.org' - gclient_root = get_gclient_root() + gclient_root = gclient(['root']) current_dir = os.getcwd() dependencies = sorted(d.rstrip('/').rstrip('\\') for d in args.dep_path) cmdline = 'roll-dep ' + ' '.join(dependencies) + ''.join( @@ -224,17 +209,17 @@ def main(): 'Ensure %s is clean first (no non-merged commits).' % current_dir) # First gather all the information without modifying anything, except for a # git fetch. - deps_path, deps_content = get_deps(current_dir) - gclient_dict = gclient_eval.Exec(deps_content, deps_path) - is_relative = gclient_dict.get('use_relative_paths', False) - root_dir = current_dir if is_relative else gclient_root rolls = {} for dependency in dependencies: - full_dir = os.path.normpath(os.path.join(root_dir, dependency)) + full_dir = os.path.normpath(os.path.join(gclient_root, dependency)) if not os.path.isdir(full_dir): - raise Error('Directory not found: %s (%s)' % (dependency, full_dir)) - head, roll_to = calculate_roll( - full_dir, dependency, gclient_dict, args.roll_to) + print('Dependency %s not found at %s' % (dependency, full_dir)) + full_dir = os.path.normpath(os.path.join(current_dir, dependency)) + print('Will look for relative dependency at %s' % full_dir) + if not os.path.isdir(full_dir): + raise Error('Directory not found: %s (%s)' % (dependency, full_dir)) + + head, roll_to = calculate_roll(full_dir, dependency, args.roll_to) if roll_to == head: if len(dependencies) == 1: raise AlreadyRolledError('No revision to roll!') @@ -242,20 +227,20 @@ def main(): else: print( '%s: Rolling from %s to %s' % (dependency, head[:10], roll_to[:10])) - rolls[dependency] = (head, roll_to) + rolls[dependency] = (head, roll_to, full_dir) logs = [] - for dependency, (head, roll_to) in sorted(rolls.iteritems()): - full_dir = os.path.normpath(os.path.join(root_dir, dependency)) + setdep_args = [] + for dependency, (head, roll_to, full_dir) in sorted(rolls.iteritems()): log = generate_commit_message( full_dir, dependency, head, roll_to, args.no_log, args.log_limit) logs.append(log) - gclient_eval.SetRevision(gclient_dict, dependency, roll_to) + setdep_args.extend(['-r', '{}@{}'.format(dependency, roll_to)]) - deps_content = gclient_eval.RenderDEPSFile(gclient_dict) + gclient(['setdep'] + setdep_args) commit_msg = gen_commit_msg(logs, cmdline, reviewers, args.bug) - finalize(commit_msg, deps_path, deps_content, rolls, root_dir) + finalize(commit_msg, current_dir, rolls) except Error as e: sys.stderr.write('error: %s\n' % e) return 2 if isinstance(e, AlreadyRolledError) else 1 diff --git a/tests/roll_dep_test.py b/tests/roll_dep_test.py index 42c6ed512..2109051c5 100644 --- a/tests/roll_dep_test.py +++ b/tests/roll_dep_test.py @@ -37,6 +37,9 @@ class FakeRepos(fake_repos.FakeReposBase): 'deps = {', ' "src/foo": "%(git_base)srepo_2@%(repo_2_revision)s",', '}', + 'hooks = [', + ' {"action": ["foo", "--android", "{checkout_android}"]}', + ']', ]) % { 'git_base': self.git_base, 'repo_2_revision': self.git_hashes['repo_2'][1][0], @@ -90,6 +93,9 @@ class RollDepTest(fake_repos.FakeReposTestBase): 'deps = {', ' "src/foo": "' + self.git_base + 'repo_2@' + expected_revision + '",', '}', + 'hooks = [', + ' {"action": ["foo", "--android", "{checkout_android}"]}', + ']', ], contents.splitlines()) commit_message = self.call(['git', 'log', '-n', '1'])[0] @@ -118,6 +124,9 @@ class RollDepTest(fake_repos.FakeReposTestBase): 'deps = {', ' "src/foo": "' + self.git_base + 'repo_2@' + expected_revision + '",', '}', + 'hooks = [', + ' {"action": ["foo", "--android", "{checkout_android}"]}', + ']', ], contents.splitlines()) commit_message = self.call(['git', 'log', '-n', '1'])[0]