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

Side by Side Diff: build/fix_gn_headers.py

Issue 2790563003: Use more accurate matching in fix_gn_headers.py (Closed)
Patch Set: 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):
wychen 2017/03/31 16:42:39 Locally I use joblib.Memory to decorate this, so I
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):
Nico 2017/03/31 16:50:57 function-level comment summarizing what this does
wychen 2017/04/01 05:32:04 Done.
29 matches = []
30 for line in grep_lines:
31 gnfile, linenr, contents = line.split(':')
32 linenr = int(linenr)
33 new = re.sub(cc, basename, contents)
34 lines = open(gnfile).read().splitlines()
35 assert contents in lines[linenr - 1]
36 # Skip if it's already there. It could be before or after the match.
37 if lines[linenr] == new:
38 continue
39 if lines[linenr - 2] == new:
40 continue
41 print ' ', gnfile, linenr, new
42 matches.append((gnfile, linenr, new))
43 return matches
44
45
20 def AddHeadersNextToCC(headers, skip_ambiguous=True): 46 def AddHeadersNextToCC(headers, skip_ambiguous=True):
21 """Add header files next to the corresponding .cc files in GN files. 47 """Add header files next to the corresponding .cc files in GN files.
22 48
23 When skip_ambiguous is True, skip if multiple .cc files are found. 49 When skip_ambiguous is True, skip if multiple .cc files are found.
24 Returns unhandled headers. 50 Returns unhandled headers.
25 51
26 Manual cleaning up is likely required, especially if not skip_ambiguous. 52 Manual cleaning up is likely required, especially if not skip_ambiguous.
27 """ 53 """
28 edits = {} 54 edits = {}
29 unhandled = [] 55 unhandled = []
30 for filename in headers: 56 for filename in headers:
31 filename = filename.strip() 57 filename = filename.strip()
32 if not (filename.endswith('.h') or filename.endswith('.hh')): 58 if not (filename.endswith('.h') or filename.endswith('.hh')):
33 continue 59 continue
34 basename = os.path.basename(filename) 60 basename = os.path.basename(filename)
35 print filename 61 print filename
36 cc = r'\b' + os.path.splitext(basename)[0] + r'\.(cc|cpp|mm)\b' 62 cc = r'\b' + os.path.splitext(basename)[0] + r'\.(cc|cpp|mm)\b'
37 p = subprocess.Popen( 63 out, returncode = GitGrep('(/|")' + cc + '"')
Nico 2017/03/31 16:50:57 nit: r'\b' instead of '(/|")'
wychen 2017/03/31 16:56:56 '\b' is already there, but it's not enough. For ex
wychen 2017/03/31 16:58:08 Ah. using sep might be better since we might want
38 ['git', 'grep', '-En', cc + '"', '--', '*.gn', '*.gni'], 64 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) 65 unhandled.append(filename)
43 continue 66 continue
44 67
45 if skip_ambiguous and len(out.splitlines()) > 1: 68 matches = ValidMatches(basename, cc, out.splitlines())
69
70 if len(matches) == 0:
71 continue
72 if len(matches) > 1:
46 print '\n[WARNING] Ambiguous matching for', filename 73 print '\n[WARNING] Ambiguous matching for', filename
47 print out 74 for i in enumerate(matches, 1):
48 continue 75 print '%d: %s' % (i[0], i[1])
76 print
77 if skip_ambiguous:
78 continue
49 79
50 for gnline in out.splitlines(): 80 picked = raw_input('Pick the matches ("2,3" for multiple): ')
51 gnfile, linenr, contents = gnline.split(':') 81 try:
52 linenr = int(linenr) 82 matches = [matches[int(i) - 1] for i in picked.split(',')]
53 new = re.sub(cc, basename, contents) 83 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 84 continue
58 if lines[linenr - 2] == new: 85
59 continue 86 for match in matches:
87 gnfile, linenr, new = match
60 print ' ', gnfile, linenr, new 88 print ' ', gnfile, linenr, new
61 edits.setdefault(gnfile, {})[linenr] = new 89 edits.setdefault(gnfile, {})[linenr] = new
62 90
63 for gnfile in edits: 91 for gnfile in edits:
64 lines = open(gnfile).read().splitlines() 92 lines = open(gnfile).read().splitlines()
65 for l in sorted(edits[gnfile].keys(), reverse=True): 93 for l in sorted(edits[gnfile].keys(), reverse=True):
66 lines.insert(l, edits[gnfile][l]) 94 lines.insert(l, edits[gnfile][l])
67 open(gnfile, 'w').write('\n'.join(lines) + '\n') 95 open(gnfile, 'w').write('\n'.join(lines) + '\n')
68 96
69 return unhandled 97 return unhandled
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 144
117 if args.prefix: 145 if args.prefix:
118 headers = [i for i in headers if i.startswith(args.prefix)] 146 headers = [i for i in headers if i.startswith(args.prefix)]
119 147
120 unhandled = AddHeadersNextToCC(headers) 148 unhandled = AddHeadersNextToCC(headers)
121 AddHeadersToSources(unhandled) 149 AddHeadersToSources(unhandled)
122 150
123 151
124 if __name__ == '__main__': 152 if __name__ == '__main__':
125 sys.exit(main()) 153 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