|
|
Created:
6 years, 7 months ago by hinoka Modified:
6 years, 7 months ago CC:
chromium-reviews, kjellander-cc_chromium.org, cmp-cc_chromium.org, ilevy-cc_chromium.org, stip+watch_chromium.org Base URL:
https://chromium.googlesource.com/chromium/tools/build.git@master Visibility:
Public. |
DescriptionOnly apply DEPS patches before gclient sync, apply all other patches afterwards
This should in theory allow for cross-repo patches.
BUG=370503
Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=269490
Patch Set 1 #Patch Set 2 : Fixes #Patch Set 3 : Adds filename printing #
Total comments: 7
Patch Set 4 : Review fixes #
Total comments: 4
Patch Set 5 : Review fix #Patch Set 6 : Rebase #Messages
Total messages: 13 (0 generated)
Tested by: python -u ../../../scripts/tools/runit.py ../../../scripts/slave/bot_update.py --spec "solutions = [{'custom_vars': {'googlecode_url': 'svn://svn-mirror.golo.chromium.org/%s', 'nacl_trunk': 'svn://svn-mirror.golo.chromium.org/native_client/t runk', 'sourceforge_url': 'svn://svn-mirror.golo.chromium.org/%(repo)s', 'webkit_trunk': 'svn://svn-mirror.golo.chromium.org/blink/trunk'}, 'deps_file': 'DEPS', 'managed': True, 'name': 'src', 'url': 'svn://svn-mirror.golo.chromium.org/chrome/trunk/src'}]" --root src --revision 268505 --p atch_url svn://svn.chromium.org/chrome-try/try/Matt_Menke.file.2014-05-06%2017.54.01.133000.diff@314861 --output_json /tmp/tmpaYNDxo.json --force python -u ../../../scripts/tools/runit.py ../../../scripts/slave/bot_update.py --spec "solutions = [{'custom_vars': {'googlecode_url': 'svn://svn-mirror.golo.chromium.org/%s', 'nacl_trunk': 'svn://svn-mirror.golo.chromium.org/native_client/trunk', 'sourceforge_url': 'svn://svn-mirror.golo.chromium.org/%(repo)s', 'webkit_trunk': 'svn://svn-mirror.golo.chromium.org/blink/trunk'}, 'deps_file': 'DEPS', 'managed': True, 'name': 'src', 'url': 'svn://svn-mirror.golo.chromium.org/chrome/trunk/src'}]" --root src --revision HEAD --issue 253603004 --patchset 170001 --output_json /tmp/tmp3zAa3y.json --force
[+iannucci review]
mostly lgtm % some nits, and obviously don't land until https://codereview.chromium.org/273543002/ does https://codereview.chromium.org/274493002/diff/30001/scripts/slave/bot_update.py File scripts/slave/bot_update.py (right): https://codereview.chromium.org/274493002/diff/30001/scripts/slave/bot_update... scripts/slave/bot_update.py:877: def apply_issue_rietveld(issue, patchset, root, server, rev_map, revision, apply_rietveld_issue (to match apply_svn_patch) https://codereview.chromium.org/274493002/diff/30001/scripts/slave/bot_update... scripts/slave/bot_update.py:877: def apply_issue_rietveld(issue, patchset, root, server, rev_map, revision, Also, take patch first (to match apply_svn_patch) https://codereview.chromium.org/274493002/diff/30001/scripts/slave/bot_update... scripts/slave/bot_update.py:884: I wouldn't put empty lines in the middle of this. https://codereview.chromium.org/274493002/diff/30001/scripts/slave/bot_update... scripts/slave/bot_update.py:891: # DEPRECATED? If it is, remove it. If it is still necessary, say why you're passing it.
seems fine to me, just some comments. https://codereview.chromium.org/274493002/diff/50001/scripts/slave/bot_update.py File scripts/slave/bot_update.py (right): https://codereview.chromium.org/274493002/diff/50001/scripts/slave/bot_update... scripts/slave/bot_update.py:235: for attempt in range(tries): hm... why not xrange? https://codereview.chromium.org/274493002/diff/50001/scripts/slave/bot_update... scripts/slave/bot_update.py:843: # Otherwise... I'm not really sure what to do with this. probably should abort loudly
https://codereview.chromium.org/274493002/diff/30001/scripts/slave/bot_update.py File scripts/slave/bot_update.py (right): https://codereview.chromium.org/274493002/diff/30001/scripts/slave/bot_update... scripts/slave/bot_update.py:877: def apply_issue_rietveld(issue, patchset, root, server, rev_map, revision, On 2014/05/07 21:39:00, agable wrote: > Also, take patch first (to match apply_svn_patch) Patchset here is actually an integer, where as "patches" in apply_svn_patch is actually an object that contains the contents of the patch. Because patchsets on rietveld are uniquely referred to as "issue - patchset", it always makes more sense to put issue first. https://codereview.chromium.org/274493002/diff/30001/scripts/slave/bot_update... scripts/slave/bot_update.py:884: On 2014/05/07 21:39:00, agable wrote: > I wouldn't put empty lines in the middle of this. Done. https://codereview.chromium.org/274493002/diff/30001/scripts/slave/bot_update... scripts/slave/bot_update.py:891: # DEPRECATED? On 2014/05/07 21:39:00, agable wrote: > If it is, remove it. If it is still necessary, say why you're passing it. Done. https://codereview.chromium.org/274493002/diff/50001/scripts/slave/bot_update.py File scripts/slave/bot_update.py (right): https://codereview.chromium.org/274493002/diff/50001/scripts/slave/bot_update... scripts/slave/bot_update.py:235: for attempt in range(tries): On 2014/05/08 22:17:01, iannucci wrote: > hm... why not xrange? "range" sounds cleaner (xrange isn't even a word!), and at O(3) the use of a generator is hardly relevant to performance. https://codereview.chromium.org/274493002/diff/50001/scripts/slave/bot_update... scripts/slave/bot_update.py:843: # Otherwise... I'm not really sure what to do with this. On 2014/05/08 22:17:01, iannucci wrote: > probably should abort loudly Done.
lgtm
The CQ bit was checked by hinoka@chromium.org
CQ is trying da patch. Follow status at https://chromium-status.appspot.com/cq/hinoka@chromium.org/274493002/70001
The CQ bit was unchecked by commit-bot@chromium.org
Failed to apply patch for build/scripts/slave/bot_update.py: While running patch -p1 --forward --force --no-backup-if-mismatch; patching file build/scripts/slave/bot_update.py Hunk #1 succeeded at 264 (offset 3 lines). Hunk #2 succeeded at 281 (offset 3 lines). Hunk #3 succeeded at 319 (offset 3 lines). Hunk #4 succeeded at 555 (offset -70 lines). Hunk #5 succeeded at 632 (offset -70 lines). Hunk #6 succeeded at 795 (offset -58 lines). Hunk #7 succeeded at 912 (offset -58 lines). Hunk #8 FAILED at 988. Hunk #9 succeeded at 977 with fuzz 2 (offset -45 lines). Hunk #10 FAILED at 1051. 2 out of 10 hunks FAILED -- saving rejects to file build/scripts/slave/bot_update.py.rej Patch: build/scripts/slave/bot_update.py Index: scripts/slave/bot_update.py diff --git build/scripts/slave/bot_update.py build/scripts/slave/bot_update.py index 1df92f1b25a03ee57db1711f48a6da22a00cab65..1078af436217728b3d0421ecb3dddd2961e90680 100755 --- a/build/scripts/slave/bot_update.py +++ b/build/scripts/slave/bot_update.py @@ -261,11 +261,16 @@ class SVNRevisionNotFound(Exception): pass +class InvalidDiff(Exception): + pass + + def call(*args, **kwargs): """Interactive subprocess call.""" kwargs['stdout'] = subprocess.PIPE kwargs['stderr'] = subprocess.STDOUT stdin_data = kwargs.pop('stdin_data', None) + tries = kwargs.pop('tries', RETRIES) if stdin_data: kwargs['stdin'] = subprocess.PIPE out = cStringIO.StringIO() @@ -273,7 +278,7 @@ def call(*args, **kwargs): env = copy.copy(os.environ) env.update(new_env) kwargs['env'] = env - for attempt in xrange(RETRIES): + for attempt in range(tries): attempt_msg = ' (retry #%d)' % attempt if attempt else '' if new_env: print '===Injecting Environment Variables===' @@ -311,7 +316,7 @@ def call(*args, **kwargs): print raise SubprocessFailed('%s failed with code %d in %s after %d attempts.' % - (' '.join(args), code, os.getcwd(), RETRIES), code) + (' '.join(args), code, os.getcwd(), tries), code) def git(*args, **kwargs): @@ -620,12 +625,16 @@ def _last_commit_for_file(filename, repo_base): def need_to_run_deps2git(repo_base, deps_file, deps_git_file): """Checks to see if we need to run deps2git. - Returns True if there was a DEPS change after the last .DEPS.git update. + Returns True if there was a DEPS change after the last .DEPS.git update + or if DEPS has local modifications. """ print 'Checking if %s exists' % deps_git_file if not path.isfile(deps_git_file): # .DEPS.git doesn't exist but DEPS does? We probably want to generate one. - print 'it exists!' + print 'it doesn\'t exist!' + return True + + if git('diff', deps_file, cwd=repo_base).strip(): return True last_known_deps_ref = _last_commit_for_file(deps_file, repo_base) @@ -693,10 +702,10 @@ def ensure_deps2git(sln_dir, shallow): repo_base = path.join(os.getcwd(), sln_dir) deps_file = path.join(repo_base, 'DEPS') deps_git_file = path.join(repo_base, '.DEPS.git') - print 'Checking if %s is newer than %s' % (deps_file, deps_git_file) if not path.isfile(deps_file): return + print 'Checking if %s is newer than %s' % (deps_file, deps_git_file) if not need_to_run_deps2git(repo_base, deps_file, deps_git_file): return @@ -844,24 +853,103 @@ def _download(url): raise -def apply_issue_svn(root, patch_url): +def parse_diff(diff): + """Takes a unified diff and returns a list of diffed files and their diffs. + + The return format is a list of pairs of: + (<filename>, <diff contents>) + <diff contents> is inclusive of the diff line. + """ + result = [] + current_diff = '' + current_header = None + for line in diff.splitlines(): + # "diff" is for git style patches, and "Index: " is for SVN style patches. + if line.startswith('diff') or line.startswith('Index: '): + if current_header: + # If we are in a diff portion, then save the diff. + result.append((current_header, '%s\n' % current_diff)) + git_header_match = re.match(r'diff (?:--git )?(\S+) (\S+)', line) + svn_header_match = re.match(r'Index: (.*)', line) + + if git_header_match: + # First, see if its a git style header. + from_file = git_header_match.group(1) + to_file = git_header_match.group(2) + if from_file != to_file and from_file.startswith('a/'): + # Sometimes git prepends 'a/' and 'b/' in front of file paths. + from_file = from_file[2:] + current_header = from_file + + elif svn_header_match: + # Otherwise, check if its an SVN style header. + current_header = svn_header_match.group(1) + + else: + # Otherwise... I'm not really sure what to do with this. + raise InvalidDiff('Can\'t process header: %s\nFull diff:\n%s' % + (line, diff)) + + current_diff = '' + current_diff += '%s\n' % line + if current_header: + # We hit EOF, gotta save the last diff. + result.append((current_header, current_diff)) + return result + + +def get_svn_patch(patch_url): + """Fetch patch from patch_url, return list of (filename, diff)""" patch_data = call('svn', 'cat', patch_url) - call(PATCH_TOOL, '-p0', '--remove-empty-files', '--force', '--forward', - stdin_data=patch_data, cwd=root) + return parse_diff(patch_data) + + +def apply_svn_patch(patch_root, patches, whitelist=None, blacklist=None): + """Expects a list of (filename, diff), applies it on top of patch_root.""" + if whitelist: + patches = [(name, diff) for name, diff in patches if name in whitelist] + elif blacklist: + patches = [(name, diff) for name, diff in patches if name not in blacklist] + diffs = [diff for _, diff in patches] + patch = ''.join(diffs) + + if patch: + print '===Patching files===' + for filename, _ in patches: + print 'Patching %s' % filename + call(PATCH_TOOL, '-p0', '--remove-empty-files', '--force', '--forward', + stdin_data=patch, cwd=patch_root, tries=1) -def apply_issue_rietveld(issue, patchset, root, server, rev_map, revision): +def apply_rietveld_issue(issue, patchset, root, server, rev_map, revision, + whitelist=None, blacklist=None): apply_issue_bin = ('apply_issue.bat' if sys.platform.startswith('win') else 'apply_issue') - call(apply_issue_bin, - '--root_dir', root, - '--issue', issue, - '--patchset', patchset, - '--no-auth', - '--server', server, - '--base_ref', revision, - '--force', - '--ignore_deps') + cmd = [apply_issue_bin, + # The patch will be applied on top of this directory. + '--root_dir', root, + # Tell apply_issue how to fetch the patch. + '--issue', issue, + '--patchset', patchset, + '--no-auth', + '--server', server, + # Always run apply_issue.py, otherwise it would see update.flag + # and then bail out. + '--force', + # Don't run gclient sync when it sees a DEPS change. + '--ignore_deps', + # Don't commit the patch or add it to the index. + '--no_commit', + ] + if whitelist: + for item in whitelist: + cmd.extend(['--whitelist', item]) + elif blacklist: + for item in blacklist: + cmd.extend(['--blacklist', item]) + + # Only try once, since subsequent failures hide the real failure. + call(*cmd, tries=1) def check_flag(flag_file): @@ -882,14 +970,6 @@ def emit_flag(flag_file): f.write('Success!') -def get_real_git_hash(git_hash, dir_name): - """Return git_hash or the parent of git_hash if its a patched hash.""" - log = git('log', '-1', '--format=%B', cwd=dir_name).strip() - if 'committed patch' in log.lower(): - return git('log', '-1', '--format=%H', 'HEAD^', cwd=dir_name).strip() - return git_hash - - def parse_got_revision(gclient_output, got_revision_mapping, use_svn_revs): """Translate git gclient revision mapping to build properties. @@ -908,7 +988,7 @@ def parse_got_revision(gclient_output, got_revision_mapping, use_svn_revs): else: # Since we are using .DEPS.git, everything had better be git. assert solution_output.get('scm') == 'git' - git_revision = get_real_git_hash(solution_output['revision'], dir_name) + git_revision = solution_output['revision'] if use_svn_revs: revision = get_svn_rev(git_revision, dir_name) if not revision: @@ -942,21 +1022,23 @@ def ensure_checkout(solutions, revision, first_sln, target_os, target_os_only, print 'Fetching Git checkout' git_ref = git_checkout(solutions, revision, shallow) - # If either patch_url or issue is passed in, then we need to apply a patch. + patches = None if patch_url: - # patch_url takes precidence since its only passed in on gcl try/git try. - apply_issue_svn(root, patch_url) - elif issue: - apply_issue_rietveld(issue, patchset, root, rietveld_server, - revision_mapping, git_ref) + patches = get_svn_patch(patch_url) + + if root == first_sln: + # Only top level DEPS patching is supported right now. + if patches: + apply_svn_patch(root, patches, whitelist=['DEPS']) + elif issue: + apply_rietveld_issue(issue, patchset, root, rietveld_server, + revision_mapping, git_ref, whitelist=['DEPS']) + if buildspec_name: buildspecs2git(root, buildspec_name) - elif first_sln == root: - # Run deps2git if there is a DEPS commit after the last .DEPS.git commit. - # We only need to ensure deps2git if the root is not overridden, since - # if the root is overridden, it means we are working with a sub repository - # patch, which means its impossible for it to touch DEPS. + else: + # Run deps2git if there is a DEPS change after the last .DEPS.git commit. ensu… (message too large)
The CQ bit was checked by hinoka@chromium.org
CQ is trying da patch. Follow status at https://chromium-status.appspot.com/cq/hinoka@chromium.org/274493002/90001
Message was sent while issue was closed.
Change committed as 269490 |