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

Side by Side Diff: build/fix_gn_headers.py

Issue 2790563003: Use more accurate matching in fix_gn_headers.py (Closed)
Patch Set: comment Created 3 years, 8 months 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright 2017 The Chromium Authors. All rights reserved. 2 # Copyright 2017 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """Fix header files missing in GN. 6 """Fix header files missing in GN.
7 7
8 This script takes the missing header files from check_gn_headers.py, and 8 This script takes the missing header files from check_gn_headers.py, and
9 try to fix them by adding them to the GN files. 9 try to fix them by adding them to the GN files.
10 Manual cleaning up is likely required afterwards. 10 Manual cleaning up is likely required afterwards.
11 """ 11 """
12 12
13 import argparse 13 import argparse
14 import os 14 import os
15 import re 15 import re
16 import subprocess 16 import subprocess
17 import sys 17 import sys
18 18
19 19
20 def GitGrep(pattern):
21 p = subprocess.Popen(
22 ['git', 'grep', '-En', pattern, '--', '*.gn', '*.gni'],
23 stdout=subprocess.PIPE)
24 out, _ = p.communicate()
25 return out, p.returncode
26
27
28 def ValidMatches(basename, cc, grep_lines):
29 """Filter out 'git grep' matches with header files already."""
30 matches = []
31 for line in grep_lines:
32 gnfile, linenr, contents = line.split(':')
33 linenr = int(linenr)
34 new = re.sub(cc, basename, contents)
35 lines = open(gnfile).read().splitlines()
36 assert contents in lines[linenr - 1]
37 # Skip if it's already there. It could be before or after the match.
38 if lines[linenr] == new:
39 continue
40 if lines[linenr - 2] == new:
41 continue
42 print ' ', gnfile, linenr, new
43 matches.append((gnfile, linenr, new))
44 return matches
45
46
20 def AddHeadersNextToCC(headers, skip_ambiguous=True): 47 def AddHeadersNextToCC(headers, skip_ambiguous=True):
21 """Add header files next to the corresponding .cc files in GN files. 48 """Add header files next to the corresponding .cc files in GN files.
22 49
23 When skip_ambiguous is True, skip if multiple .cc files are found. 50 When skip_ambiguous is True, skip if multiple .cc files are found.
24 Returns unhandled headers. 51 Returns unhandled headers.
25 52
26 Manual cleaning up is likely required, especially if not skip_ambiguous. 53 Manual cleaning up is likely required, especially if not skip_ambiguous.
27 """ 54 """
28 edits = {} 55 edits = {}
29 unhandled = [] 56 unhandled = []
30 for filename in headers: 57 for filename in headers:
31 filename = filename.strip() 58 filename = filename.strip()
32 if not (filename.endswith('.h') or filename.endswith('.hh')): 59 if not (filename.endswith('.h') or filename.endswith('.hh')):
33 continue 60 continue
34 basename = os.path.basename(filename) 61 basename = os.path.basename(filename)
35 print filename 62 print filename
36 cc = r'\b' + os.path.splitext(basename)[0] + r'\.(cc|cpp|mm)\b' 63 cc = r'\b' + os.path.splitext(basename)[0] + r'\.(cc|cpp|mm)\b'
37 p = subprocess.Popen( 64 out, returncode = GitGrep('(/|")' + cc + '"')
38 ['git', 'grep', '-En', cc + '"', '--', '*.gn', '*.gni'], 65 if returncode != 0 or not out:
39 stdout=subprocess.PIPE)
40 out, _ = p.communicate()
41 if p.returncode != 0 or not out:
42 unhandled.append(filename) 66 unhandled.append(filename)
43 continue 67 continue
44 68
45 if skip_ambiguous and len(out.splitlines()) > 1: 69 matches = ValidMatches(basename, cc, out.splitlines())
70
71 if len(matches) == 0:
72 continue
73 if len(matches) > 1:
46 print '\n[WARNING] Ambiguous matching for', filename 74 print '\n[WARNING] Ambiguous matching for', filename
47 print out 75 for i in enumerate(matches, 1):
48 continue 76 print '%d: %s' % (i[0], i[1])
77 print
78 if skip_ambiguous:
79 continue
49 80
50 for gnline in out.splitlines(): 81 picked = raw_input('Pick the matches ("2,3" for multiple): ')
51 gnfile, linenr, contents = gnline.split(':') 82 try:
52 linenr = int(linenr) 83 matches = [matches[int(i) - 1] for i in picked.split(',')]
53 new = re.sub(cc, basename, contents) 84 except (ValueError, IndexError):
54 lines = open(gnfile).read().splitlines()
55 # Skip if it's already there. It could be before or after the match.
56 if lines[linenr] == new:
57 continue 85 continue
58 if lines[linenr - 2] == new: 86
59 continue 87 for match in matches:
88 gnfile, linenr, new = match
60 print ' ', gnfile, linenr, new 89 print ' ', gnfile, linenr, new
61 edits.setdefault(gnfile, {})[linenr] = new 90 edits.setdefault(gnfile, {})[linenr] = new
62 91
63 for gnfile in edits: 92 for gnfile in edits:
64 lines = open(gnfile).read().splitlines() 93 lines = open(gnfile).read().splitlines()
65 for l in sorted(edits[gnfile].keys(), reverse=True): 94 for l in sorted(edits[gnfile].keys(), reverse=True):
66 lines.insert(l, edits[gnfile][l]) 95 lines.insert(l, edits[gnfile][l])
67 open(gnfile, 'w').write('\n'.join(lines) + '\n') 96 open(gnfile, 'w').write('\n'.join(lines) + '\n')
68 97
69 return unhandled 98 return unhandled
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 145
117 if args.prefix: 146 if args.prefix:
118 headers = [i for i in headers if i.startswith(args.prefix)] 147 headers = [i for i in headers if i.startswith(args.prefix)]
119 148
120 unhandled = AddHeadersNextToCC(headers) 149 unhandled = AddHeadersNextToCC(headers)
121 AddHeadersToSources(unhandled) 150 AddHeadersToSources(unhandled)
122 151
123 152
124 if __name__ == '__main__': 153 if __name__ == '__main__':
125 sys.exit(main()) 154 sys.exit(main())
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698