Chromium Code Reviews| Index: scripts/slave/patch_path_filter.py |
| diff --git a/scripts/slave/patch_path_filter.py b/scripts/slave/patch_path_filter.py |
| new file mode 100755 |
| index 0000000000000000000000000000000000000000..60d88491b43acf3a58d6f80ef5f129d6ac8df2a4 |
| --- /dev/null |
| +++ b/scripts/slave/patch_path_filter.py |
| @@ -0,0 +1,109 @@ |
| +#!/usr/bin/python |
| +# Copyright 2013 The Chromium Authors. All rights reserved. |
| +# Use of this source code is governed by a BSD-style license that can be |
| +# found in the LICENSE file. |
| + |
| +"""Script that can be used to filter out files from a patch/diff. |
| + |
| +Just pipe the patch contents to stdin and the filtered output will be written |
| +to stdout. |
| + |
| +This script supports the following types of diff entries where each file entry |
| +starts with the following four lines: |
| + |
| +* Subversion patch: |
| +Index: path_and_filename |
| +=================================================================== |
| +--- path_and_filename (revision xxxx) |
| ++++ path_and_filename (working copy) |
| + |
| + |
| +* Git patch: |
| +diff --git path_and_filename path_and_filename |
| +index abcdef..123456 100644 |
| +--- path_and_filename |
| ++++ path_and_filename |
| +""" |
| + |
| +import optparse |
| +import re |
| +import sys |
| + |
| + |
| +class PatchEntry(): |
| + def __init__(self, file_path, contents): |
| + self.file_path = file_path |
| + self.contents = contents |
| + |
| + def __str__(self): |
| + return self.contents |
| + |
| + |
| +GIT_REGEX = ('^diff\s--git\s(.*?)\s(.*?)\n' |
| + '^.*?\n' |
| + '^-{3}\s(.*?)\n' |
| + '^\+{3}\s(.*?)$') |
|
iannucci
2013/10/29 17:15:02
I would use a raw string here (i.e. r' stuff '). T
kjellander_chromium
2013/11/26 22:11:25
This is remade in Patch set #3.
|
| +SVN_REGEX = ('^Index:\s(.*?)\n' |
| + '^.*?\n' |
| + '^-{3}\s.*?\n' |
| + '^\+{3}\s.*?$') |
| +ITEM_PREFIX_TYPES = (GIT_REGEX, SVN_REGEX) |
| + |
| +def parse_entries(item_prefix_regex, patch_contents): |
| + regex = re.compile(item_prefix_regex, re.MULTILINE | re.DOTALL) |
| + |
| + # List to contain tuples of filename and start position in the patch. |
| + file_and_start_index_list = [] |
| + |
| + start_index = 0 |
| + match_data = regex.search(patch_contents[start_index:]) |
| + while match_data: |
| + file_and_start_index_list.append((match_data.group(1), |
| + start_index + match_data.start())) |
| + start_index += match_data.end() |
| + match_data = regex.search(patch_contents[start_index:]) |
| + |
| + # Build a PatchEntry list from the list of filename and start indexes. |
| + entries = [] |
| + i = iter(file_and_start_index_list) |
| + previous_item = None |
| + try: |
| + while True: |
| + item = i.next() |
| + if previous_item: |
| + entries.append(PatchEntry(previous_item[0], |
| + patch_contents[previous_item[1]:item[1]])) |
| + previous_item = item |
| + except StopIteration: |
| + if previous_item: |
| + entries.append(PatchEntry(previous_item[0], |
| + patch_contents[previous_item[1]:])) |
| + return entries |
| + |
| +def main(): |
| + parser = optparse.OptionParser() |
| + parser.add_option('-f', '--path-filter', |
| + help=('The path filter (UNIX paths) that all file paths ' |
| + 'are required to have to pass this filter (no ' |
| + 'regexp).')) |
| + |
| + options, args = parser.parse_args() |
| + if args: |
| + parser.error('Unused args: %s' % args) |
| + if not options.path_filter: |
| + parser.error('A path filter must be be specified.') |
| + |
| + patch_contents = sys.stdin.read() |
| + |
| + # Try with Git first, since it's the most likely used patch format. |
| + patch_entries = parse_entries(GIT_REGEX, patch_contents) |
| + if len(patch_entries) == 0: |
| + patch_entries = parse_entries(SVN_REGEX, patch_contents) |
| + |
| + # Only print the patch entries that passes our path filter. |
| + for entry in patch_entries: |
| + if entry.file_path.startswith(options.path_filter): |
| + print entry |
| + |
| +if __name__ == '__main__': |
| + sys.exit(main()) |