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

Side by Side Diff: tools/gn_check_autofix.py

Issue 2555813003: Add a tool to fix (some) errors reported by gn gen --check. (Closed)
Patch Set: More improvements! Created 4 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
« .gn ('K') | « .gn ('k') | 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
(Empty)
1 #!/usr/bin/env python
2
3 # Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
4 #
5 # Use of this source code is governed by a BSD-style license
6 # that can be found in the LICENSE file in the root of the source
7 # tree. An additional intellectual property rights grant can be found
8 # in the file PATENTS. All contributing project authors may
9 # be found in the AUTHORS file in the root of the source tree.
10
11 import os
12 import re
13 import subprocess
14 import sys
15
16 from collections import defaultdict
17
18 def Run(cmd):
19 sub = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
20 return sub.communicate()
21
22 def fix_missing(filename, missing_deps, deleted_sources):
23 with open(filename) as f:
24 contents = f.readlines()
25 target_re = re.compile(r'(?P<indentation_level>\s*)\w*\("(?P<target_name>\w*)" \) {$')
26 blocks = ""
27 last_indentation_level = None
28 for line_number, line in enumerate(contents):
29 match = target_re.match(line)
30 if match:
31 target = match.group('target_name')
32 if target in missing_deps:
33 last_indentation_level = match.group('indentation_level')
34 elif last_indentation_level is not None:
35 match = re.match(last_indentation_level + '}$', line)
36 if match:
37 line = ('deps = [\n' +
38 ''.join(' "' + dep + '",\n' for dep in missing_deps[target]) +
39 ']\n') + line
40 last_indentation_level = None
41 elif line.strip().startswith('deps'):
42 is_inline_deps = line.strip() == 'deps = []'
43 line = (('deps = [\n' if is_inline_deps else line) +
44 ''.join(' "' + dep + '",\n' for dep in missing_deps[target]) +
45 (']\n' if is_inline_deps else ''))
46 last_indentation_level = None
47 if line.strip() in deleted_sources:
48 line = ""
49
50 blocks += line
51 with open(filename, 'w') as f:
52 f.write(blocks)
53 Run(['gn', 'format', filename])
54
55 def rebase(base_path, dependency_path, dependency):
56 base_path = base_path.split(os.path.sep)
57 dependency_path = dependency_path.split(os.path.sep)
58 for common_prefix in range(min(len(dependency_path), len(base_path))):
59 if dependency_path[common_prefix] != base_path[common_prefix]:
60 common_prefix -= 1
61 break
62 common_prefix += 1
63 base_path = base_path[common_prefix:]
64 dependency_path = dependency_path[common_prefix:]
65 return (os.path.sep.join((['..'] * len(base_path)) + dependency_path) +
66 ':' + dependency)
67
68 def main():
69 deleted_sources = set()
70 errors_by_file = defaultdict(lambda: defaultdict(set))
71
72 gn_output = Run(['gn', 'gen', 'out/gn', '--check'])[0]
kjellander_webrtc 2016/12/08 11:57:23 Ideally we'd generate a temporary directory here a
73 errors = gn_output.split('ERROR')[1:]
74 for error in errors:
75 error = error.splitlines()
76 target_msg = 'The target:'
77 if target_msg not in error:
78 target_msg = 'It is not in any dependency of'
79 if target_msg not in error:
80 print '\n'.join(error)
81 continue
82 index = error.index(target_msg) + 1
83 path, target = error[index].strip().split(':')
84 if error[index+1] in ('is including a file from the target:',
85 'The include file is in the target(s):'):
86 dep = error[index+2].strip()
87 dep_path, dep = dep.split(':')
88 dep = rebase(path, dep_path, dep)
89 path = os.path.join(path[2:], 'BUILD.gn')
90 errors_by_file[path][target].add(dep)
91 elif error[index+1] == 'has a source file:':
92 deleted_file = '"' + os.path.basename(error[index+2].strip()) + '",'
93 deleted_sources.add(deleted_file)
94 else:
95 print '\n'.join(error)
96 continue
97
98 print errors_by_file
99
100 for path, missing_deps in errors_by_file.items():
101 fix_missing(path, missing_deps, deleted_sources)
102
103 return 0
104
105 if __name__ == '__main__':
106 sys.exit(main())
OLDNEW
« .gn ('K') | « .gn ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698