OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 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 | 5 |
6 """ Creates a zip file in the staging dir with the result of a compile. | 6 """ Creates a zip file in the staging dir with the result of a compile. |
7 It can be sent to other machines for testing. | 7 It can be sent to other machines for testing. |
8 """ | 8 """ |
9 | 9 |
10 import csv | 10 import csv |
11 import glob | 11 import glob |
12 import optparse | 12 import optparse |
13 import os | 13 import os |
14 import re | 14 import re |
15 import shutil | 15 import shutil |
16 import stat | 16 import stat |
17 import sys | 17 import sys |
18 import tempfile | 18 import tempfile |
19 | 19 |
20 from common import chromium_utils | 20 from common import chromium_utils |
21 from slave import slave_utils | 21 from slave import slave_utils |
22 | 22 |
23 class StagingError(Exception): pass | 23 class StagingError(Exception): pass |
24 | 24 |
25 | 25 |
| 26 def ASANFilter(path): |
| 27 """Takes a path to a file and returns the path to its asan'd counterpart. |
| 28 |
| 29 Returns None if path is already an asan'd file. |
| 30 Returns the original path otherwise. |
| 31 """ |
| 32 head, tail = os.path.split(path) |
| 33 parts = tail.split('.', 1) |
| 34 if len(parts) == 1: |
| 35 return path |
| 36 if parts[-1].startswith('asan'): # skip 'foo.asan.exe' entirely |
| 37 return None |
| 38 parts.insert(1, 'asan') |
| 39 asan_path = os.path.join(head, '.'.join(parts)) |
| 40 if os.path.exists(asan_path): |
| 41 return asan_path |
| 42 return path |
| 43 |
| 44 |
| 45 FILTERS = { |
| 46 'asan': ASANFilter, |
| 47 } |
| 48 |
| 49 |
26 def CopyDebugCRT(build_dir): | 50 def CopyDebugCRT(build_dir): |
27 # Copy the relevant CRT DLLs to |build_dir|. We copy DLLs from all versions | 51 # Copy the relevant CRT DLLs to |build_dir|. We copy DLLs from all versions |
28 # of VS installed to make sure we have the correct CRT version, unused DLLs | 52 # of VS installed to make sure we have the correct CRT version, unused DLLs |
29 # should not conflict with the others anyways. | 53 # should not conflict with the others anyways. |
30 crt_dlls = glob.glob( | 54 crt_dlls = glob.glob( |
31 'C:\\Program Files (x86)\\Microsoft Visual Studio *\\VC\\redist\\' | 55 'C:\\Program Files (x86)\\Microsoft Visual Studio *\\VC\\redist\\' |
32 'Debug_NonRedist\\x86\\Microsoft.*.DebugCRT\\*.dll') | 56 'Debug_NonRedist\\x86\\Microsoft.*.DebugCRT\\*.dll') |
33 for dll in crt_dlls: | 57 for dll in crt_dlls: |
34 shutil.copy(dll, build_dir) | 58 shutil.copy(dll, build_dir) |
35 | 59 |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 tmp_revision_file.close() | 211 tmp_revision_file.close() |
188 chromium_utils.MakeWorldReadable(tmp_revision_file.name) | 212 chromium_utils.MakeWorldReadable(tmp_revision_file.name) |
189 dest_path = os.path.join(dirname, | 213 dest_path = os.path.join(dirname, |
190 chromium_utils.FULL_BUILD_REVISION_FILENAME) | 214 chromium_utils.FULL_BUILD_REVISION_FILENAME) |
191 shutil.move(tmp_revision_file.name, dest_path) | 215 shutil.move(tmp_revision_file.name, dest_path) |
192 except IOError: | 216 except IOError: |
193 print 'Writing to revision file in %s failed.' % dirname | 217 print 'Writing to revision file in %s failed.' % dirname |
194 | 218 |
195 | 219 |
196 def MakeUnversionedArchive(build_dir, staging_dir, zip_file_list, | 220 def MakeUnversionedArchive(build_dir, staging_dir, zip_file_list, |
197 zip_file_name): | 221 zip_file_name, filters): |
198 """Creates an unversioned full build archive. | 222 """Creates an unversioned full build archive. |
199 Returns the path of the created archive.""" | 223 Returns the path of the created archive.""" |
200 (zip_dir, zip_file) = chromium_utils.MakeZip(staging_dir, | 224 (zip_dir, zip_file) = chromium_utils.MakeZip(staging_dir, |
201 zip_file_name, | 225 zip_file_name, |
202 zip_file_list, | 226 zip_file_list, |
203 build_dir, | 227 build_dir, |
204 raise_error=True) | 228 raise_error=True, |
| 229 replacements=filters) |
205 chromium_utils.RemoveDirectory(zip_dir) | 230 chromium_utils.RemoveDirectory(zip_dir) |
206 if not os.path.exists(zip_file): | 231 if not os.path.exists(zip_file): |
207 raise StagingError('Failed to make zip package %s' % zip_file) | 232 raise StagingError('Failed to make zip package %s' % zip_file) |
208 chromium_utils.MakeWorldReadable(zip_file) | 233 chromium_utils.MakeWorldReadable(zip_file) |
209 | 234 |
210 # Report the size of the zip file to help catch when it gets too big and | 235 # Report the size of the zip file to help catch when it gets too big and |
211 # can cause bot failures from timeouts during downloads to testers. | 236 # can cause bot failures from timeouts during downloads to testers. |
212 zip_size = os.stat(zip_file)[stat.ST_SIZE] | 237 zip_size = os.stat(zip_file)[stat.ST_SIZE] |
213 print 'Zip file is %ld bytes' % zip_size | 238 print 'Zip file is %ld bytes' % zip_size |
214 | 239 |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
312 | 337 |
313 # Build the list of files to archive. | 338 # Build the list of files to archive. |
314 root_files = os.listdir(build_dir) | 339 root_files = os.listdir(build_dir) |
315 path_filter = PathMatcher(options) | 340 path_filter = PathMatcher(options) |
316 print path_filter | 341 print path_filter |
317 print ('\nActually excluded: %s' % | 342 print ('\nActually excluded: %s' % |
318 [f for f in root_files if not path_filter.Match(f)]) | 343 [f for f in root_files if not path_filter.Match(f)]) |
319 | 344 |
320 zip_file_list = [f for f in root_files if path_filter.Match(f)] | 345 zip_file_list = [f for f in root_files if path_filter.Match(f)] |
321 zip_file = MakeUnversionedArchive(build_dir, staging_dir, zip_file_list, | 346 zip_file = MakeUnversionedArchive(build_dir, staging_dir, zip_file_list, |
322 unversioned_base_name) | 347 unversioned_base_name, options.filters) |
323 | 348 |
324 zip_base, zip_ext = MakeVersionedArchive(zip_file, version_suffix, options) | 349 zip_base, zip_ext = MakeVersionedArchive(zip_file, version_suffix, options) |
325 PruneOldArchives(staging_dir, zip_base, zip_ext) | 350 PruneOldArchives(staging_dir, zip_base, zip_ext) |
326 | 351 |
327 # Update the latest revision file in the staging directory | 352 # Update the latest revision file in the staging directory |
328 # to allow testers to figure out the latest packaged revision | 353 # to allow testers to figure out the latest packaged revision |
329 # without downloading tarballs. | 354 # without downloading tarballs. |
330 WriteRevisionFile(staging_dir, build_revision) | 355 WriteRevisionFile(staging_dir, build_revision) |
331 | 356 |
332 return 0 | 357 return 0 |
333 | 358 |
334 | 359 |
335 def main(argv): | 360 def main(argv): |
336 option_parser = optparse.OptionParser() | 361 option_parser = optparse.OptionParser() |
337 option_parser.add_option('--target', | 362 option_parser.add_option('--target', |
338 help='build target to archive (Debug or Release)') | 363 help='build target to archive (Debug or Release)') |
339 option_parser.add_option('--src-dir', default='src', | 364 option_parser.add_option('--src-dir', default='src', |
340 help='path to the top-level sources directory') | 365 help='path to the top-level sources directory') |
341 option_parser.add_option('--build-dir', default='chrome', | 366 option_parser.add_option('--build-dir', default='chrome', |
342 help=('path to main build directory (the parent of ' | 367 help=('path to main build directory (the parent of ' |
343 'the Release or Debug directory)')) | 368 'the Release or Debug directory)')) |
344 option_parser.add_option('--exclude-files', default='', | 369 option_parser.add_option('--exclude-files', default='', |
345 help=('Comma separated list of files that should ' | 370 help=('Comma separated list of files that should ' |
346 'always be excluded from the zip.')) | 371 'always be excluded from the zip.')) |
347 option_parser.add_option('--include-files', default='', | 372 option_parser.add_option('--include-files', default='', |
348 help=('Comma separated list of files that should ' | 373 help=('Comma separated list of files that should ' |
349 'always be included in the zip.')) | 374 'always be included in the zip.')) |
350 option_parser.add_option('--webkit-dir', | 375 option_parser.add_option('--webkit-dir', |
351 help='webkit directory path, relative to --src-dir') | 376 help='webkit directory path, relative to --src-dir') |
| 377 option_parser.add_option('--filters', action='append', default=[], |
| 378 help='Filters to apply to build zip ' |
| 379 '(avail: %r).' % list(FILTERS.keys())) |
352 chromium_utils.AddPropertiesOptions(option_parser) | 380 chromium_utils.AddPropertiesOptions(option_parser) |
353 | 381 |
354 options, args = option_parser.parse_args(argv) | 382 options, args = option_parser.parse_args(argv) |
355 | 383 |
356 if not options.target: | 384 if not options.target: |
357 options.target = options.factory_properties.get('target', 'Release') | 385 options.target = options.factory_properties.get('target', 'Release') |
358 if not options.webkit_dir: | 386 if not options.webkit_dir: |
359 options.webkit_dir = options.factory_properties.get('webkit_dir') | 387 options.webkit_dir = options.factory_properties.get('webkit_dir') |
360 | 388 |
361 # When option_parser is passed argv as a list, it can return the caller as | 389 # When option_parser is passed argv as a list, it can return the caller as |
362 # first unknown arg. So throw a warning if we have two or more unknown | 390 # first unknown arg. So throw a warning if we have two or more unknown |
363 # arguments. | 391 # arguments. |
364 if args[1:]: | 392 if args[1:]: |
365 print 'Warning -- unknown arguments' % args[1:] | 393 print 'Warning -- unknown arguments' % args[1:] |
366 | 394 |
| 395 if options.factory_properties.get('asan'): |
| 396 options.filters.append('asan') |
| 397 options.filters = [FILTERS[item] for item in set(options.filters)] |
| 398 |
367 return Archive(options) | 399 return Archive(options) |
368 | 400 |
| 401 |
369 if '__main__' == __name__: | 402 if '__main__' == __name__: |
370 sys.exit(main(sys.argv)) | 403 sys.exit(main(sys.argv)) |
OLD | NEW |