OLD | NEW |
---|---|
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2013 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2013 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 """Wrapper script to help run clang tools across Chromium code. | 5 """Wrapper script to help run clang tools across Chromium code. |
6 | 6 |
7 How to use run_tool.py: | 7 How to use run_tool.py: |
8 If you want to run a clang tool across all Chromium code: | 8 If you want to run a clang tool across all Chromium code: |
9 run_tool.py <tool> <path/to/compiledb> | 9 run_tool.py <tool> <path/to/compiledb> |
10 | 10 |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
101 toolname: Name of the clang tool to execute. | 101 toolname: Name of the clang tool to execute. |
102 tool_args: Arguments to be passed to the clang tool. Can be None. | 102 tool_args: Arguments to be passed to the clang tool. Can be None. |
103 build_directory: Directory that contains the compile database. | 103 build_directory: Directory that contains the compile database. |
104 filename: The file to run the clang tool over. | 104 filename: The file to run the clang tool over. |
105 | 105 |
106 Returns: | 106 Returns: |
107 A dictionary that must contain the key "status" and a boolean value | 107 A dictionary that must contain the key "status" and a boolean value |
108 associated with it. | 108 associated with it. |
109 | 109 |
110 If status is True, then the generated output is stored with the key | 110 If status is True, then the generated output is stored with the key |
111 "stdout_text" in the dictionary. | 111 "stdout_text" in the dictionary. Same for "stderr_text". |
112 | 112 |
113 Otherwise, the filename and the output from stderr are associated with the | 113 Otherwise, the filename and the output from stderr are associated with the |
114 keys "filename" and "stderr_text" respectively. | 114 keys "filename" and "stderr_text" respectively. |
115 """ | 115 """ |
116 args = [toolname, '-p', build_directory, filename] | 116 args = [toolname, '-p', build_directory, filename] |
117 if (tool_args): | 117 if (tool_args): |
118 args.extend(tool_args) | 118 args.extend(tool_args) |
119 command = subprocess.Popen( | 119 command = subprocess.Popen( |
120 args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | 120 args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
121 stdout_text, stderr_text = command.communicate() | 121 stdout_text, stderr_text = command.communicate() |
122 if command.returncode != 0: | 122 if command.returncode != 0: |
123 return {'status': False, 'filename': filename, 'stderr_text': stderr_text} | 123 return {'status': False, 'filename': filename, 'stderr_text': stderr_text} |
124 else: | 124 else: |
125 return {'status': True, 'filename': filename, 'stdout_text': stdout_text} | 125 return {'status': True, 'filename': filename, 'stdout_text': stdout_text, |
126 'stderr_text': stderr_text} | |
126 | 127 |
127 | 128 |
128 class _CompilerDispatcher(object): | 129 class _CompilerDispatcher(object): |
129 """Multiprocessing controller for running clang tools in parallel.""" | 130 """Multiprocessing controller for running clang tools in parallel.""" |
130 | 131 |
131 def __init__(self, toolname, tool_args, build_directory, filenames): | 132 def __init__(self, toolname, tool_args, build_directory, filenames): |
132 """Initializer method. | 133 """Initializer method. |
133 | 134 |
134 Args: | 135 Args: |
135 toolname: Path to the tool to execute. | 136 toolname: Path to the tool to execute. |
(...skipping 25 matching lines...) Expand all Loading... | |
161 | 162 |
162 def __ProcessResult(self, result): | 163 def __ProcessResult(self, result): |
163 """Handles result processing. | 164 """Handles result processing. |
164 | 165 |
165 Args: | 166 Args: |
166 result: The result dictionary returned by _ExecuteTool. | 167 result: The result dictionary returned by _ExecuteTool. |
167 """ | 168 """ |
168 if result['status']: | 169 if result['status']: |
169 self.__success_count += 1 | 170 self.__success_count += 1 |
170 sys.stdout.write(result['stdout_text']) | 171 sys.stdout.write(result['stdout_text']) |
172 sys.stderr.write(result['stderr_text']) | |
Łukasz Anforowicz
2017/01/05 18:45:19
Needed to stop eating stderr (which might contain
danakj
2017/01/05 18:55:19
assert if we're going to print things seems best s
Łukasz Anforowicz
2017/01/05 19:04:44
Okay - reverted. I think I still want to do this
| |
171 else: | 173 else: |
172 self.__failed_count += 1 | 174 self.__failed_count += 1 |
173 sys.stderr.write('\nFailed to process %s\n' % result['filename']) | 175 sys.stderr.write('\nFailed to process %s\n' % result['filename']) |
174 sys.stderr.write(result['stderr_text']) | 176 sys.stderr.write(result['stderr_text']) |
175 sys.stderr.write('\n') | 177 sys.stderr.write('\n') |
176 done_count = self.__success_count + self.__failed_count | 178 done_count = self.__success_count + self.__failed_count |
177 percentage = (float(done_count) / len(self.__filenames)) * 100 | 179 percentage = (float(done_count) / len(self.__filenames)) * 100 |
178 sys.stderr.write( | 180 sys.stderr.write( |
179 'Processed %d files with %s tool (%d failures) [%.2f%%]\r' % | 181 'Processed %d files with %s tool (%d failures) [%.2f%%]\r' % |
180 (done_count, self.__toolname, self.__failed_count, percentage)) | 182 (done_count, self.__toolname, self.__failed_count, percentage)) |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
222 | 224 |
223 dispatcher = _CompilerDispatcher(args.tool, args.tool_args, | 225 dispatcher = _CompilerDispatcher(args.tool, args.tool_args, |
224 args.compile_database, | 226 args.compile_database, |
225 source_filenames) | 227 source_filenames) |
226 dispatcher.Run() | 228 dispatcher.Run() |
227 return -dispatcher.failed_count | 229 return -dispatcher.failed_count |
228 | 230 |
229 | 231 |
230 if __name__ == '__main__': | 232 if __name__ == '__main__': |
231 sys.exit(main()) | 233 sys.exit(main()) |
OLD | NEW |