diff --git a/recipe_modules/bot_update/resources/bot_update.py b/recipe_modules/bot_update/resources/bot_update.py index d34a9f44e..2d9d87eef 100755 --- a/recipe_modules/bot_update/resources/bot_update.py +++ b/recipe_modules/bot_update/resources/bot_update.py @@ -339,7 +339,7 @@ def gclient_configure(solutions, target_os, target_os_only, git_cache_dir): solutions, target_os, target_os_only, git_cache_dir)) -def gclient_sync(with_branch_heads, shallow, break_repo_locks): +def gclient_sync(with_branch_heads, shallow, revisions, break_repo_locks): # We just need to allocate a filename. fd, gclient_output_file = tempfile.mkstemp(suffix='.json') os.close(fd) @@ -353,6 +353,8 @@ def gclient_sync(with_branch_heads, shallow, break_repo_locks): args += ['--shallow'] if break_repo_locks: args += ['--break_repo_locks'] + for name, revision in sorted(revisions.iteritems()): + args.extend(['--revision', '%s@%s' % (name, revision)]) try: call_gclient(*args, tries=1) @@ -750,20 +752,6 @@ def emit_json(out_file, did_run, gclient_output=None, **kwargs): f.write(json.dumps(output, sort_keys=True)) -def ensure_deps_revisions(deps_url_mapping, solutions, revisions): - """Ensure correct DEPS revisions, ignores solutions.""" - for deps_name, deps_data in sorted(deps_url_mapping.items()): - if deps_name.strip('/') in solutions: - # This has already been forced to the correct solution by git_checkout(). - continue - revision = get_target_revision(deps_name, deps_data.get('url', None), - revisions) - if not revision: - continue - git('fetch', 'origin', cwd=deps_name) - force_revision(deps_name, revision) - - def ensure_checkout(solutions, revisions, first_sln, target_os, target_os_only, patch_root, issue, patchset, rietveld_server, gerrit_repo, gerrit_ref, gerrit_rebase_patch_ref, revision_mapping, @@ -806,21 +794,22 @@ def ensure_checkout(solutions, revisions, first_sln, target_os, target_os_only, # Windows sometimes has trouble deleting files. This can make git commands # that rely on locks fail. break_repo_locks = True if sys.platform.startswith('win') else False + # We want to pass all non-solution revisions into the gclient sync call. + solution_dirs = {sln['name'] for sln in solutions} + gc_revisions = { + dirname: rev for dirname, rev in revisions.iteritems() + if dirname not in solution_dirs} # Let gclient do the DEPS syncing. # The branch-head refspec is a special case because its possible Chrome # src, which contains the branch-head refspecs, is DEPSed in. gclient_output = gclient_sync(BRANCH_HEADS_REFSPEC in refs, shallow, - break_repo_locks) + gc_revisions, break_repo_locks) # Now that gclient_sync has finished, we should revert any .DEPS.git so that # presubmit doesn't complain about it being modified. if git('ls-files', '.DEPS.git', cwd=first_sln).strip(): git('checkout', 'HEAD', '--', '.DEPS.git', cwd=first_sln) - # Finally, ensure that all DEPS are pinned to the correct revision. - dir_names = [sln['name'] for sln in solutions] - ensure_deps_revisions(gclient_output.get('solutions', {}), - dir_names, revisions) # Apply the rest of the patch here (sans DEPS) if issue: apply_rietveld_issue(issue, patchset, patch_root, rietveld_server, diff --git a/tests/bot_update_coverage_test.py b/tests/bot_update_coverage_test.py index 6d4a3ddae..a14da63f9 100755 --- a/tests/bot_update_coverage_test.py +++ b/tests/bot_update_coverage_test.py @@ -22,7 +22,7 @@ DEFAULT_PARAMS = { 'name': 'somename', 'url': 'https://fake.com' }], - 'revisions': [], + 'revisions': {}, 'first_sln': 'somename', 'target_os': None, 'target_os_only': None, @@ -122,11 +122,13 @@ class MockedGclientSync(): def __init__(self, fake_filesystem): self.output = {} self.fake_filesystem = fake_filesystem + self.records = [] def __call__(self, *args, **_): output_json_index = args.index('--output-json') + 1 with self.fake_filesystem.open(args[output_json_index], 'w') as f: json.dump(self.output, f) + self.records.append(args) class FakeFile(): @@ -203,6 +205,20 @@ class BotUpdateUnittests(unittest.TestCase): bot_update.ensure_checkout(**self.params) return self.call.records + def testBasicRevision(self): + self.params['revisions'] = { + 'src': 'HEAD', 'src/v8': 'deadbeef', 'somename': 'DNE'} + bot_update.ensure_checkout(**self.params) + args = self.gclient.records[0] + idx_first_revision = args.index('--revision') + idx_second_revision = args.index( + '--revision', idx_first_revision+1) + with self.assertRaises(ValueError): + args.index('--revision', idx_second_revision+1) + self.assertEquals(args[idx_first_revision+1], 'src@HEAD') + self.assertEquals(args[idx_second_revision+1], 'src/v8@deadbeef') + return self.call.records + def testBreakLocks(self): self.overrideSetupForWindows() bot_update.ensure_checkout(**self.params)