| 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 | 22 |
| 23 | 23 |
| 24 BASE_DIR = os.path.dirname(os.path.abspath(__file__)) | 24 BASE_DIR = os.path.dirname(os.path.abspath(__file__)) |
| 25 ROOT_DIR = os.path.dirname(os.path.dirname(BASE_DIR)) | 25 ROOT_DIR = os.path.dirname(os.path.dirname(BASE_DIR)) |
| 26 | 26 |
| 27 KEY_TRACKED = 'isolate_dependency_tracked' |
| 28 KEY_UNTRACKED = 'isolate_dependency_untracked' |
| 29 |
| 27 | 30 |
| 28 if sys.platform == 'win32': | 31 if sys.platform == 'win32': |
| 29 from ctypes.wintypes import create_unicode_buffer | 32 from ctypes.wintypes import create_unicode_buffer |
| 30 from ctypes.wintypes import windll, FormatError # pylint: disable=E0611 | 33 from ctypes.wintypes import windll, FormatError # pylint: disable=E0611 |
| 31 from ctypes.wintypes import GetLastError # pylint: disable=E0611 | 34 from ctypes.wintypes import GetLastError # pylint: disable=E0611 |
| 32 | 35 |
| 33 | 36 |
| 34 def QueryDosDevice(drive_letter): | 37 def QueryDosDevice(drive_letter): |
| 35 """Returns the Windows 'native' path for a DOS drive letter.""" | 38 """Returns the Windows 'native' path for a DOS drive letter.""" |
| 36 assert re.match(r'^[a-zA-Z]:$', drive_letter), drive_letter | 39 assert re.match(r'^[a-zA-Z]:$', drive_letter), drive_letter |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 'freebsd7': 'freebsd', | 115 'freebsd7': 'freebsd', |
| 113 'freebsd8': 'freebsd', | 116 'freebsd8': 'freebsd', |
| 114 } | 117 } |
| 115 return flavors.get(sys.platform, 'linux') | 118 return flavors.get(sys.platform, 'linux') |
| 116 | 119 |
| 117 | 120 |
| 118 def isEnabledFor(level): | 121 def isEnabledFor(level): |
| 119 return logging.getLogger().isEnabledFor(level) | 122 return logging.getLogger().isEnabledFor(level) |
| 120 | 123 |
| 121 | 124 |
| 125 def fix_python_path(cmd): |
| 126 """Returns the fixed command line to call the right python executable.""" |
| 127 out = cmd[:] |
| 128 if out[0] == 'python': |
| 129 out[0] = sys.executable |
| 130 elif out[0].endswith('.py'): |
| 131 out.insert(0, sys.executable) |
| 132 return out |
| 133 |
| 134 |
| 122 class Strace(object): | 135 class Strace(object): |
| 123 """strace implies linux.""" | 136 """strace implies linux.""" |
| 124 IGNORED = ( | 137 IGNORED = ( |
| 125 '/bin', | 138 '/bin', |
| 126 '/dev', | 139 '/dev', |
| 127 '/etc', | 140 '/etc', |
| 128 '/lib', | 141 '/lib', |
| 129 '/proc', | 142 '/proc', |
| 130 '/sys', | 143 '/sys', |
| 131 '/tmp', | 144 '/tmp', |
| (...skipping 1022 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1154 - force_trace: Will force to trace unconditionally even if a trace already | 1167 - force_trace: Will force to trace unconditionally even if a trace already |
| 1155 exist. | 1168 exist. |
| 1156 """ | 1169 """ |
| 1157 logging.debug( | 1170 logging.debug( |
| 1158 'trace_inputs(%s, %s, %s, %s, %s, %s)' % ( | 1171 'trace_inputs(%s, %s, %s, %s, %s, %s)' % ( |
| 1159 logfile, cmd, root_dir, cwd_dir, product_dir, force_trace)) | 1172 logfile, cmd, root_dir, cwd_dir, product_dir, force_trace)) |
| 1160 | 1173 |
| 1161 # It is important to have unambiguous path. | 1174 # It is important to have unambiguous path. |
| 1162 assert os.path.isabs(root_dir), root_dir | 1175 assert os.path.isabs(root_dir), root_dir |
| 1163 assert os.path.isabs(logfile), logfile | 1176 assert os.path.isabs(logfile), logfile |
| 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 |
| 1180 cmd = fix_python_path(cmd) |
| 1164 assert ( | 1181 assert ( |
| 1165 (os.path.isfile(logfile) and not force_trace) or os.path.isabs(cmd[0]) | 1182 (os.path.isfile(logfile) and not force_trace) or os.path.isabs(cmd[0]) |
| 1166 ), cmd[0] | 1183 ), cmd[0] |
| 1167 assert not cwd_dir or not os.path.isabs(cwd_dir), cwd_dir | |
| 1168 assert not product_dir or not os.path.isabs(product_dir), product_dir | |
| 1169 | 1184 |
| 1170 # Resolve any symlink | 1185 # Resolve any symlink |
| 1171 root_dir = os.path.realpath(root_dir) | 1186 root_dir = os.path.realpath(root_dir) |
| 1172 | 1187 |
| 1173 if sys.platform == 'win32': | 1188 if sys.platform == 'win32': |
| 1174 # Help ourself and lowercase all the paths. | 1189 # Help ourself and lowercase all the paths. |
| 1175 # TODO(maruel): handle short path names by converting them to long path name | 1190 # TODO(maruel): handle short path names by converting them to long path name |
| 1176 # as needed. | 1191 # as needed. |
| 1177 root_dir = root_dir.lower() | 1192 root_dir = root_dir.lower() |
| 1178 if cwd_dir: | 1193 if cwd_dir: |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1261 # empty if the whole directory containing the gyp file is needed. | 1276 # empty if the whole directory containing the gyp file is needed. |
| 1262 return f[len(cwd_dir):] or './' | 1277 return f[len(cwd_dir):] or './' |
| 1263 else: | 1278 else: |
| 1264 return '<(DEPTH)/%s' % f | 1279 return '<(DEPTH)/%s' % f |
| 1265 | 1280 |
| 1266 corrected = [fix(f) for f in simplified] | 1281 corrected = [fix(f) for f in simplified] |
| 1267 files = [f for f in corrected if not f.endswith('/')] | 1282 files = [f for f in corrected if not f.endswith('/')] |
| 1268 dirs = [f for f in corrected if f.endswith('/')] | 1283 dirs = [f for f in corrected if f.endswith('/')] |
| 1269 variables = {} | 1284 variables = {} |
| 1270 if files: | 1285 if files: |
| 1271 variables['isolate_files'] = files | 1286 variables[KEY_TRACKED] = files |
| 1272 if dirs: | 1287 if dirs: |
| 1273 variables['isolate_dirs'] = dirs | 1288 variables[KEY_UNTRACKED] = dirs |
| 1274 value = { | 1289 value = { |
| 1275 'conditions': [ | 1290 'conditions': [ |
| 1276 ['OS=="%s"' % flavor, { | 1291 ['OS=="%s"' % flavor, { |
| 1277 'variables': variables, | 1292 'variables': variables, |
| 1278 }], | 1293 }], |
| 1279 ], | 1294 ], |
| 1280 } | 1295 } |
| 1281 pretty_print(value, sys.stdout) | 1296 pretty_print(value, sys.stdout) |
| 1282 return 0 | 1297 return 0 |
| 1283 | 1298 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1328 os.path.abspath(options.log), | 1343 os.path.abspath(options.log), |
| 1329 args, | 1344 args, |
| 1330 options.root_dir, | 1345 options.root_dir, |
| 1331 options.cwd, | 1346 options.cwd, |
| 1332 options.product_dir, | 1347 options.product_dir, |
| 1333 options.force) | 1348 options.force) |
| 1334 | 1349 |
| 1335 | 1350 |
| 1336 if __name__ == '__main__': | 1351 if __name__ == '__main__': |
| 1337 sys.exit(main()) | 1352 sys.exit(main()) |
| OLD | NEW |