| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # coding=utf-8 | 2 # coding=utf-8 |
| 3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 3 # Copyright (c) 2012 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 """Runs strace or dtrace on a test and processes the logs to extract the | 7 """Runs strace or dtrace on a test and processes the logs to extract the |
| 8 dependencies from the source tree. | 8 dependencies from the source tree. |
| 9 | 9 |
| 10 Automatically extracts directories where all the files are used to make the | 10 Automatically extracts directories where all the files are used to make the |
| 11 dependencies list more compact. | 11 dependencies list more compact. |
| 12 """ | 12 """ |
| 13 | 13 |
| 14 import codecs | 14 import codecs |
| 15 import csv | 15 import csv |
| 16 import logging | 16 import logging |
| 17 import optparse | 17 import optparse |
| 18 import os | 18 import os |
| 19 import re | 19 import re |
| 20 import subprocess | 20 import subprocess |
| 21 import sys | 21 import sys |
| 22 from xml.etree import ElementTree | 22 from xml.etree import ElementTree |
| 23 | 23 |
| 24 | 24 |
| 25 BASE_DIR = os.path.dirname(os.path.abspath(__file__)) | 25 BASE_DIR = os.path.dirname(os.path.abspath(__file__)) |
| 26 ROOT_DIR = os.path.dirname(os.path.dirname(BASE_DIR)) | 26 ROOT_DIR = os.path.dirname(os.path.dirname(BASE_DIR)) |
| 27 | 27 |
| 28 KEY_TRACKED = 'isolate_dependency_tracked' |
| 29 KEY_UNTRACKED = 'isolate_dependency_untracked' |
| 30 |
| 28 | 31 |
| 29 if sys.platform == 'win32': | 32 if sys.platform == 'win32': |
| 30 from ctypes.wintypes import create_unicode_buffer | 33 from ctypes.wintypes import create_unicode_buffer |
| 31 from ctypes.wintypes import windll, FormatError # pylint: disable=E0611 | 34 from ctypes.wintypes import windll, FormatError # pylint: disable=E0611 |
| 32 from ctypes.wintypes import GetLastError # pylint: disable=E0611 | 35 from ctypes.wintypes import GetLastError # pylint: disable=E0611 |
| 33 | 36 |
| 34 | 37 |
| 35 def QueryDosDevice(drive_letter): | 38 def QueryDosDevice(drive_letter): |
| 36 """Returns the Windows 'native' path for a DOS drive letter.""" | 39 """Returns the Windows 'native' path for a DOS drive letter.""" |
| 37 assert re.match(r'^[a-zA-Z]:$', drive_letter), drive_letter | 40 assert re.match(r'^[a-zA-Z]:$', drive_letter), drive_letter |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 113 'freebsd7': 'freebsd', | 116 'freebsd7': 'freebsd', |
| 114 'freebsd8': 'freebsd', | 117 'freebsd8': 'freebsd', |
| 115 } | 118 } |
| 116 return flavors.get(sys.platform, 'linux') | 119 return flavors.get(sys.platform, 'linux') |
| 117 | 120 |
| 118 | 121 |
| 119 def isEnabledFor(level): | 122 def isEnabledFor(level): |
| 120 return logging.getLogger().isEnabledFor(level) | 123 return logging.getLogger().isEnabledFor(level) |
| 121 | 124 |
| 122 | 125 |
| 126 def fix_python_path(cmd): |
| 127 """Returns the fixed command line to call the right python executable.""" |
| 128 out = cmd[:] |
| 129 if out[0] == 'python': |
| 130 out[0] = sys.executable |
| 131 elif out[0].endswith('.py'): |
| 132 out.insert(0, sys.executable) |
| 133 return out |
| 134 |
| 135 |
| 123 class Strace(object): | 136 class Strace(object): |
| 124 """strace implies linux.""" | 137 """strace implies linux.""" |
| 125 IGNORED = ( | 138 IGNORED = ( |
| 126 '/bin', | 139 '/bin', |
| 127 '/dev', | 140 '/dev', |
| 128 '/etc', | 141 '/etc', |
| 129 '/lib', | 142 '/lib', |
| 130 '/proc', | 143 '/proc', |
| 131 '/sys', | 144 '/sys', |
| 132 '/tmp', | 145 '/tmp', |
| (...skipping 1031 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1164 - force_trace: Will force to trace unconditionally even if a trace already | 1177 - force_trace: Will force to trace unconditionally even if a trace already |
| 1165 exist. | 1178 exist. |
| 1166 """ | 1179 """ |
| 1167 logging.debug( | 1180 logging.debug( |
| 1168 'trace_inputs(%s, %s, %s, %s, %s, %s)' % ( | 1181 'trace_inputs(%s, %s, %s, %s, %s, %s)' % ( |
| 1169 logfile, cmd, root_dir, cwd_dir, product_dir, force_trace)) | 1182 logfile, cmd, root_dir, cwd_dir, product_dir, force_trace)) |
| 1170 | 1183 |
| 1171 # It is important to have unambiguous path. | 1184 # It is important to have unambiguous path. |
| 1172 assert os.path.isabs(root_dir), root_dir | 1185 assert os.path.isabs(root_dir), root_dir |
| 1173 assert os.path.isabs(logfile), logfile | 1186 assert os.path.isabs(logfile), logfile |
| 1187 assert not cwd_dir or not os.path.isabs(cwd_dir), cwd_dir |
| 1188 assert not product_dir or not os.path.isabs(product_dir), product_dir |
| 1189 |
| 1190 cmd = fix_python_path(cmd) |
| 1174 assert ( | 1191 assert ( |
| 1175 (os.path.isfile(logfile) and not force_trace) or os.path.isabs(cmd[0]) | 1192 (os.path.isfile(logfile) and not force_trace) or os.path.isabs(cmd[0]) |
| 1176 ), cmd[0] | 1193 ), cmd[0] |
| 1177 assert not cwd_dir or not os.path.isabs(cwd_dir), cwd_dir | |
| 1178 assert not product_dir or not os.path.isabs(product_dir), product_dir | |
| 1179 | 1194 |
| 1180 # Resolve any symlink | 1195 # Resolve any symlink |
| 1181 root_dir = os.path.realpath(root_dir) | 1196 root_dir = os.path.realpath(root_dir) |
| 1182 | 1197 |
| 1183 if sys.platform == 'win32': | 1198 if sys.platform == 'win32': |
| 1184 # Help ourself and lowercase all the paths. | 1199 # Help ourself and lowercase all the paths. |
| 1185 # TODO(maruel): handle short path names by converting them to long path name | 1200 # TODO(maruel): handle short path names by converting them to long path name |
| 1186 # as needed. | 1201 # as needed. |
| 1187 root_dir = root_dir.lower() | 1202 root_dir = root_dir.lower() |
| 1188 if cwd_dir: | 1203 if cwd_dir: |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1271 # empty if the whole directory containing the gyp file is needed. | 1286 # empty if the whole directory containing the gyp file is needed. |
| 1272 return f[len(cwd_dir):] or './' | 1287 return f[len(cwd_dir):] or './' |
| 1273 else: | 1288 else: |
| 1274 return '<(DEPTH)/%s' % f | 1289 return '<(DEPTH)/%s' % f |
| 1275 | 1290 |
| 1276 corrected = [fix(f) for f in simplified] | 1291 corrected = [fix(f) for f in simplified] |
| 1277 files = [f for f in corrected if not f.endswith('/')] | 1292 files = [f for f in corrected if not f.endswith('/')] |
| 1278 dirs = [f for f in corrected if f.endswith('/')] | 1293 dirs = [f for f in corrected if f.endswith('/')] |
| 1279 variables = {} | 1294 variables = {} |
| 1280 if files: | 1295 if files: |
| 1281 variables['isolate_files'] = files | 1296 variables[KEY_TRACKED] = files |
| 1282 if dirs: | 1297 if dirs: |
| 1283 variables['isolate_dirs'] = dirs | 1298 variables[KEY_UNTRACKED] = dirs |
| 1284 value = { | 1299 value = { |
| 1285 'conditions': [ | 1300 'conditions': [ |
| 1286 ['OS=="%s"' % flavor, { | 1301 ['OS=="%s"' % flavor, { |
| 1287 'variables': variables, | 1302 'variables': variables, |
| 1288 }], | 1303 }], |
| 1289 ], | 1304 ], |
| 1290 } | 1305 } |
| 1291 pretty_print(value, sys.stdout) | 1306 pretty_print(value, sys.stdout) |
| 1292 return 0 | 1307 return 0 |
| 1293 | 1308 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1338 os.path.abspath(options.log), | 1353 os.path.abspath(options.log), |
| 1339 args, | 1354 args, |
| 1340 options.root_dir, | 1355 options.root_dir, |
| 1341 options.cwd, | 1356 options.cwd, |
| 1342 options.product_dir, | 1357 options.product_dir, |
| 1343 options.force) | 1358 options.force) |
| 1344 | 1359 |
| 1345 | 1360 |
| 1346 if __name__ == '__main__': | 1361 if __name__ == '__main__': |
| 1347 sys.exit(main()) | 1362 sys.exit(main()) |
| OLD | NEW |