Chromium Code Reviews| 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: "asan").') | |
| 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'): | |
|
nsylvain
2012/11/27 00:23:15
this is used for more than windows, so all the cur
iannucci
2012/11/27 01:39:13
I suppose it's not expected, but the filter will b
| |
| 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 |