Commit faae42e1 authored by Edward Lemur's avatar Edward Lemur Committed by Commit Bot

roll-dep: Use gclient setdep/getdep.

Use gclient setdep/getdep instead of evaluating the contents of the
DEPS file, so we don't have to deal with builtin_variables.

Bug: 906114
Change-Id: I2082d4a3feb84d15c251b7d99056fd4c6f925453
Reviewed-on: https://chromium-review.googlesource.com/c/1347450Reviewed-by: 's avatarNico Weber <thakis@chromium.org>
Commit-Queue: Edward Lesmes <ehmaldonado@chromium.org>
parent 6c18a1af
......@@ -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):
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, gclient_dict, args.roll_to)
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
......
......@@ -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]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment