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

Side by Side Diff: build/android/lint/suppress.py

Issue 1916603002: [Android] Fix lint suppression generation. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 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 # 2 #
3 # Copyright (c) 2013 The Chromium Authors. All rights reserved. 3 # Copyright (c) 2013 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be 4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file. 5 # found in the LICENSE file.
6 6
7 """Add all generated lint_result.xml files to suppressions.xml""" 7 """Add all generated lint_result.xml files to suppressions.xml"""
8 8
9 # pylint: disable=no-member 9 # pylint: disable=no-member
10 10
(...skipping 25 matching lines...) Expand all
36 ' globally if it is not applicable to the project.\n' 36 ' globally if it is not applicable to the project.\n'
37 '- You can also automatically add issues found so for in the\n' 37 '- You can also automatically add issues found so for in the\n'
38 ' build process by running:\n\n' 38 ' build process by running:\n\n'
39 ' ' + os.path.relpath(_THIS_FILE, host_paths.DIR_SOURCE_ROOT) + '\n\n' 39 ' ' + os.path.relpath(_THIS_FILE, host_paths.DIR_SOURCE_ROOT) + '\n\n'
40 ' which will generate this file (Comments are not preserved).\n' 40 ' which will generate this file (Comments are not preserved).\n'
41 ' Note: PRODUCT_DIR will be substituted at run-time with actual\n' 41 ' Note: PRODUCT_DIR will be substituted at run-time with actual\n'
42 ' directory path (e.g. out/Debug)\n' 42 ' directory path (e.g. out/Debug)\n'
43 ) 43 )
44 44
45 45
46 _Issue = collections.namedtuple('Issue', ['severity', 'paths']) 46 _Issue = collections.namedtuple('Issue', ['severity', 'paths', 'regexps'])
47 47
48 48
49 def _ParseConfigFile(config_path): 49 def _ParseConfigFile(config_path):
50 print 'Parsing %s' % config_path 50 print 'Parsing %s' % config_path
51 issues_dict = {} 51 issues_dict = {}
52 dom = minidom.parse(config_path) 52 dom = minidom.parse(config_path)
53 for issue in dom.getElementsByTagName('issue'): 53 for issue in dom.getElementsByTagName('issue'):
54 issue_id = issue.attributes['id'].value 54 issue_id = issue.attributes['id'].value
55 severity = issue.getAttribute('severity') 55 severity = issue.getAttribute('severity')
56 paths = set( 56
57 [p.attributes['path'].value for p in 57 path_elements = (
58 issue.getElementsByTagName('ignore')]) 58 p.attributes.get('path')
59 issues_dict[issue_id] = _Issue(severity, paths) 59 for p in issue.getElementsByTagName('ignore'))
60 paths = set(p.value for p in path_elements if p)
61
62 regexp_elements = (
63 p.attributes.get('regexp')
64 for p in issue.getElementsByTagName('ignore'))
65 regexps = set(r.value for r in regexp_elements if r)
66
67 issues_dict[issue_id] = _Issue(severity, paths, regexps)
60 return issues_dict 68 return issues_dict
61 69
62 70
63 def _ParseAndMergeResultFile(result_path, issues_dict): 71 def _ParseAndMergeResultFile(result_path, issues_dict):
64 print 'Parsing and merging %s' % result_path 72 print 'Parsing and merging %s' % result_path
65 dom = minidom.parse(result_path) 73 dom = minidom.parse(result_path)
66 for issue in dom.getElementsByTagName('issue'): 74 for issue in dom.getElementsByTagName('issue'):
67 issue_id = issue.attributes['id'].value 75 issue_id = issue.attributes['id'].value
68 severity = issue.attributes['severity'].value 76 severity = issue.attributes['severity'].value
69 path = issue.getElementsByTagName('location')[0].attributes['file'].value 77 path = issue.getElementsByTagName('location')[0].attributes['file'].value
70 if issue_id not in issues_dict: 78 if issue_id not in issues_dict:
71 issues_dict[issue_id] = _Issue(severity, set()) 79 issues_dict[issue_id] = _Issue(severity, set(), set())
72 issues_dict[issue_id].paths.add(path) 80 issues_dict[issue_id].paths.add(path)
73 81
74 82
75 def _WriteConfigFile(config_path, issues_dict): 83 def _WriteConfigFile(config_path, issues_dict):
76 new_dom = minidom.getDOMImplementation().createDocument(None, 'lint', None) 84 new_dom = minidom.getDOMImplementation().createDocument(None, 'lint', None)
77 top_element = new_dom.documentElement 85 top_element = new_dom.documentElement
78 top_element.appendChild(new_dom.createComment(_DOC)) 86 top_element.appendChild(new_dom.createComment(_DOC))
79 for issue_id in sorted(issues_dict.keys()): 87 for issue_id, issue in sorted(issues_dict.iteritems(), key=lambda i: i[0]):
80 severity = issues_dict[issue_id].severity 88 issue_element = new_dom.createElement('issue')
81 paths = issues_dict[issue_id].paths 89 issue_element.attributes['id'] = issue_id
82 issue = new_dom.createElement('issue') 90 if issue.severity:
83 issue.attributes['id'] = issue_id 91 issue_element.attributes['severity'] = issue.severity
84 if severity: 92 if issue.severity == 'ignore':
85 issue.attributes['severity'] = severity
86 if severity == 'ignore':
87 print 'Warning: [%s] is suppressed globally.' % issue_id 93 print 'Warning: [%s] is suppressed globally.' % issue_id
88 else: 94 else:
89 for path in sorted(paths): 95 for path in sorted(issue.paths):
90 ignore = new_dom.createElement('ignore') 96 ignore_element = new_dom.createElement('ignore')
91 ignore.attributes['path'] = path 97 ignore_element.attributes['path'] = path
92 issue.appendChild(ignore) 98 issue_element.appendChild(ignore_element)
93 top_element.appendChild(issue) 99 for regexp in sorted(issue.regexps):
100 ignore_element = new_dom.createElement('ignore')
101 ignore_element.attributes['regexp'] = regexp
102 issue_element.appendChild(ignore_element)
103 top_element.appendChild(issue_element)
94 104
95 with open(config_path, 'w') as f: 105 with open(config_path, 'w') as f:
96 f.write(new_dom.toprettyxml(indent=' ', encoding='utf-8')) 106 f.write(new_dom.toprettyxml(indent=' ', encoding='utf-8'))
97 print 'Updated %s' % config_path 107 print 'Updated %s' % config_path
98 108
99 109
100 def _Suppress(config_path, result_path): 110 def _Suppress(config_path, result_path):
101 issues_dict = _ParseConfigFile(config_path) 111 issues_dict = _ParseConfigFile(config_path)
102 _ParseAndMergeResultFile(result_path, issues_dict) 112 _ParseAndMergeResultFile(result_path, issues_dict)
103 _WriteConfigFile(config_path, issues_dict) 113 _WriteConfigFile(config_path, issues_dict)
104 114
105 115
106 def main(): 116 def main():
107 parser = optparse.OptionParser(usage='%prog RESULT-FILE') 117 parser = optparse.OptionParser(usage='%prog RESULT-FILE')
108 _, args = parser.parse_args() 118 _, args = parser.parse_args()
109 119
110 if len(args) != 1 or not os.path.exists(args[0]): 120 if len(args) != 1 or not os.path.exists(args[0]):
111 parser.error('Must provide RESULT-FILE') 121 parser.error('Must provide RESULT-FILE')
112 122
113 _Suppress(_CONFIG_PATH, args[0]) 123 _Suppress(_CONFIG_PATH, args[0])
114 124
115 125
116 if __name__ == '__main__': 126 if __name__ == '__main__':
117 main() 127 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