Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 #!/usr/bin/python | |
| 2 # Copyright 2013 The Chromium Authors. All rights reserved. | |
| 3 # Use of this source code is governed by a BSD-style license that can be | |
| 4 # found in the LICENSE file. | |
| 5 | |
| 6 """Script that can be used to filter out files from a patch/diff. | |
| 7 | |
| 8 Just pipe the patch contents to stdin and the filtered output will be written | |
| 9 to stdout. | |
| 10 """ | |
| 11 | |
| 12 import optparse | |
| 13 import os | |
| 14 import re | |
| 15 import sys | |
| 16 | |
| 17 from depot_tools import patch | |
| 18 | |
| 19 _GIT_PREFIX = 'diff --git ' | |
| 20 _SVN_PREFIX = 'Index: ' | |
| 21 | |
| 22 # The Git patches generated from depot_tools/git_cl.py has the a/ prefix for | |
| 23 # the source files stripped out. That's why it's optional non-capturing group | |
| 24 # below (to support both scenarios). | |
| 25 _GIT_FILENAME_REGEX = r'^diff \-\-git (?:a/)?(.*?) .*\n$' | |
| 26 _SVN_FILENAME_REGEX = r'^Index: ([^\t]+).*\n$' | |
| 27 | |
| 28 | |
| 29 def parse_git_patch_set(patch_contents): | |
| 30 return _parse_patch_set(_GIT_PREFIX, _GIT_FILENAME_REGEX, patch_contents) | |
| 31 | |
| 32 def parse_svn_patch_set(patch_contents): | |
| 33 return _parse_patch_set(_SVN_PREFIX, _SVN_FILENAME_REGEX, patch_contents) | |
| 34 | |
| 35 def _parse_patch_set(prefix, filename_pattern, patch_contents): | |
| 36 # Parse into chunks using the prefix. | |
| 37 patch_chunks = [] | |
| 38 current_chunk = [] | |
| 39 for line in patch_contents.splitlines(True): | |
| 40 if line.startswith(prefix) and current_chunk: | |
| 41 patch_chunks.insert(0, current_chunk) | |
| 42 current_chunk = [line] | |
| 43 else: | |
| 44 current_chunk.append(line) | |
| 45 if current_chunk: | |
| 46 patch_chunks.insert(0, current_chunk) | |
| 47 | |
| 48 # Parse filename for each patch chunk and create FilePatchDiff objects | |
| 49 filename_regex = re.compile(filename_pattern) | |
| 50 patches = [] | |
| 51 for chunk in patch_chunks: | |
| 52 match = filename_regex.match(chunk[0]) | |
| 53 if not match: | |
| 54 raise Exception('Did not find any filename in %s' % chunk[0]) | |
| 55 filename = match.group(1).replace('\\', '/') | |
| 56 diff = ''.join(chunk) | |
| 57 patches.append(patch.FilePatchDiff(filename=filename, diff=diff, | |
| 58 svn_properties=[])) | |
| 59 return patch.PatchSet(patches) | |
| 60 | |
| 61 def main(): | |
| 62 usage = '%s -f <path-filter> [-r <root-dir>]' % os.path.basename(sys.argv[0]) | |
| 63 parser = optparse.OptionParser(usage=usage) | |
| 64 parser.add_option('-f', '--path-filter', | |
| 65 help=('The path filter (UNIX paths) that all file paths ' | |
| 66 'are required to have to pass this filter (no ' | |
| 67 'regexp).')) | |
| 68 parser.add_option('-r', '--root-dir', | |
| 69 help=('The patch root dir in which to apply the patch. If ' | |
| 70 'specified, it will be prepended to the filename ' | |
| 71 'for each patch entry before the filter is applied.')) | |
| 72 | |
| 73 options, args = parser.parse_args() | |
| 74 if args: | |
| 75 parser.error('Unused args: %s' % args) | |
| 76 if not options.path_filter: | |
| 77 parser.error('A path filter must be be specified.') | |
| 78 | |
| 79 patch_contents = sys.stdin.read() | |
| 80 | |
| 81 # Find out if it's a Git or Subversion patch set. | |
| 82 is_git = any(l.startswith(_GIT_PREFIX) for l in patch_contents.splitlines()) | |
|
kjellander_chromium
2013/12/10 20:46:02
Turns out this is actually not needed if we assume
| |
| 83 if is_git: | |
| 84 patchset = parse_git_patch_set(patch_contents) | |
| 85 else: | |
| 86 patchset = parse_svn_patch_set(patch_contents) | |
| 87 | |
| 88 # Only print the patch entries that passes our path filter. | |
| 89 for patch_entry in patchset: | |
| 90 filename = patch_entry.filename | |
| 91 if options.root_dir: | |
| 92 filename = os.path.join(options.root_dir, filename) | |
| 93 if filename.startswith(options.path_filter): | |
| 94 print patch_entry.get(for_git=is_git) | |
| 95 | |
| 96 if __name__ == '__main__': | |
| 97 sys.exit(main()) | |
| OLD | NEW |