Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(278)

Side by Side Diff: scripts/slave/patch_path_filter.py

Issue 27575002: Patch path filtering script. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Addressed comments Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « scripts/slave/apply_svn_patch.py ('k') | scripts/slave/unittests/data/patch_path_filter/README » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 Usage: pipe the patch contents to stdin and the filtered output will be written
9 to stdout.
10 The output will be compatible with the patch program, both for Subversion and
11 Git patches.
12 NOTICE: the script can only manage patches created by depot tools (i.e. it
13 is supposed to be used for tryjob generated patches. This is because it relies
14 no the Index: line being present, which is normally not the case for Git patches
15 (it is added by depot_tools/third_party/upload.py during the creation of the
16 try job).
17 """
18
19 import optparse
20 import os
21 import re
22 import sys
23
24 from depot_tools import patch
25
26
27 _FILENAME_REGEX = re.compile(r'^.*: ([^\t]+).*\n$')
28
29
30 def parse_patch_set(patch_contents):
31 patch_chunks = []
32 current_chunk = []
33 for line in patch_contents.splitlines(True):
34 # See https://code.google.com/p/chromium/codesearch#
35 # chromium/tools/depot_tools/third_party/upload.py
36 # for details on how patches uploaded with depot_tools will have each
37 # file chunk start with either of these strings (for both Git and SVN).
38 if line.startswith(('Index:', 'Property changes on:')) and current_chunk:
39 patch_chunks.insert(0, current_chunk)
40 current_chunk = []
41 current_chunk.append(line)
42
43 if current_chunk:
44 patch_chunks.insert(0, current_chunk)
45
46 # Parse filename for each patch chunk and create FilePatchDiff objects
47
48 patches = []
49 for chunk in patch_chunks:
50 match = _FILENAME_REGEX.match(chunk[0])
51 if not match:
52 raise Exception('Did not find any filename in line "%s". Notice that '
53 'only patches uploaded using depot tools are supported '
54 'since normal Git patches don\'t include the "Index:" '
55 'line.' % chunk[0])
56 filename = match.group(1).replace('\\', '/')
57 patches.append(patch.FilePatchDiff(filename=filename, diff=''.join(chunk),
58 svn_properties=[]))
59 return patch.PatchSet(patches)
60
61
62 def convert_to_patch_compatible_diff(filename, patch_data):
63 """Convert patch data to be compatible with the standard patch program.
64
65 This will remove the "a/" and "b/" prefixes added by Git, so the patch becomes
66 compatible with the standard patch program.
67 """
68 diff = ''
69 for line in patch_data.splitlines(True):
70 if line.startswith('---'):
71 line = line.replace('a/' + filename, filename)
72 elif line.startswith('+++'):
73 line = line.replace('b/' + filename, filename)
74 diff += line
75 return diff
76
77
78 def main():
79 usage = '%s -f <path-filter> [-r <root-dir>]' % os.path.basename(sys.argv[0])
80 parser = optparse.OptionParser(usage=usage)
81 parser.add_option('-f', '--path-filter',
82 help=('The path filter (UNIX paths) that all file paths '
83 'are required to have to pass this filter (no '
84 'regexp).'))
85 parser.add_option('-r', '--root-dir',
86 help=('The patch root dir in which to apply the patch. If '
87 'specified, it will be prepended to the filename '
88 'for each patch entry before the filter is applied.'))
89
90 options, args = parser.parse_args()
91 if args:
92 parser.error('Unused args: %s' % args)
93 if not options.path_filter:
94 parser.error('A path filter must be be specified.')
95
96 patch_contents = sys.stdin.read()
97
98 # Only print the patch entries that passes our path filter.
99 for patch_entry in parse_patch_set(patch_contents):
100 filename = patch_entry.filename
101 if options.root_dir:
102 filename = os.path.join(options.root_dir, filename)
103
104 if filename.startswith(options.path_filter):
105 print convert_to_patch_compatible_diff(patch_entry.filename,
106 patch_entry.get(for_git=False)),
107
108 if __name__ == '__main__':
109 sys.exit(main())
OLDNEW
« no previous file with comments | « scripts/slave/apply_svn_patch.py ('k') | scripts/slave/unittests/data/patch_path_filter/README » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698