1 #!/usr/bin/env python 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. 3 # Use of this source code is governed by a BSD-style license that can be 4 # found in the LICENSE file. 5 6 """Creates a tarball with V8 sources, but without .svn directories. 7 8 This allows easy packaging of V8, synchronized with browser releases. 9 10 Example usage: 11 12 export_v8_tarball.py /foo/bar 13 14 The above will create file /foo/bar/v8-VERSION.tar.bz2 if it doesn't exist. 15 """ 16 17 import optparse 18 import os 19 import re 20 import subprocess 21 import sys 22 import tarfile 23 24 _V8_MAJOR_VERSION_PATTERN = re.compile(r'#define\s+MAJOR_VERSION\s+(.*)') 25 _V8_MINOR_VERSION_PATTERN = re.compile(r'#define\s+MINOR_VERSION\s+(.*)') 26 _V8_BUILD_NUMBER_PATTERN = re.compile(r'#define\s+BUILD_NUMBER\s+(.*)') 27 _V8_PATCH_LEVEL_PATTERN = re.compile(r'#define\s+PATCH_LEVEL\s+(.*)') 28 29 _V8_PATTERNS = [ 30 _V8_MAJOR_VERSION_PATTERN, 31 _V8_MINOR_VERSION_PATTERN, 32 _V8_BUILD_NUMBER_PATTERN, 33 _V8_PATCH_LEVEL_PATTERN] 34 35 _NONESSENTIAL_DIRS = ( 36 'third_party/icu', 37 ) 38 39 40 def GetV8Version(v8_directory): 41 """ 42 Returns version number as string based on the string 43 contents of version.cc file. 44 """ 45 with open(os.path.join(v8_directory, 'src', 'version.cc')) as version_file: 46 version_contents = version_file.read() 47 48 version_components = [] 49 for pattern in _V8_PATTERNS: 50 version_components.append(pattern.search(version_contents).group(1).strip()) 51 52 if version_components[len(version_components) - 1] == '0': 53 version_components.pop() 54 55 return '.'.join(version_components) 56 57 58 def GetSourceDirectory(): 59 return os.path.realpath( 60 os.path.join(os.path.dirname(__file__), '..', '..', '..', 'src')) 61 62 63 def GetV8Directory(): 64 return os.path.join(GetSourceDirectory(), 'v8') 65 66 67 # Workaround lack of the exclude parameter in add method in python-2.4. 68 # TODO(phajdan.jr): remove the workaround when it's not needed on the bot. 69 class MyTarFile(tarfile.TarFile): 70 def set_remove_nonessential_files(self, remove): 71 self.__remove_nonessential_files = remove 72 73 def add(self, name, arcname=None, recursive=True, exclude=None, filter=None): 74 head, tail = os.path.split(name) 75 if tail in ('.svn', '.git'): 76 return 77 78 if self.__remove_nonessential_files: 79 # Remove contents of non-essential directories, but preserve gyp files, 80 # so that build/gyp_chromium can work. 81 for nonessential_dir in _NONESSENTIAL_DIRS: 82 dir_path = os.path.join(GetV8Directory(), nonessential_dir) 83 if (name.startswith(dir_path) and 84 os.path.isfile(name) and 85 'gyp' not in name): 86 return 87 88 tarfile.TarFile.add(self, name, arcname=arcname, recursive=recursive) 89 90 91 def main(argv): 92 parser = optparse.OptionParser() 93 options, args = parser.parse_args(argv) 94 95 if len(args) != 1: 96 print 'You must provide only one argument: output file directory' 97 return 1 98 99 v8_directory = GetV8Directory() 100 if not os.path.exists(v8_directory): 101 print 'Cannot find the v8 directory.' 102 return 1 103 104 v8_version = GetV8Version(v8_directory) 105 print 'Packaging V8 version %s...' % v8_version 106 107 subprocess.check_call(["make", "dependencies"], cwd=v8_directory) 108 109 output_basename = 'v8-%s' % v8_version 110 111 # Package full tarball. 112 output_fullname = os.path.join(args[0], output_basename + '.tar.bz2') 113 if not os.path.exists(output_fullname): 114 archive = MyTarFile.open(output_fullname, 'w:bz2') 115 archive.set_remove_nonessential_files(False) 116 try: 117 archive.add(v8_directory, arcname=output_basename) 118 finally: 119 archive.close() 120 121 # Package lite tarball. 122 output_fullname = os.path.join(args[0], output_basename + '-lite.tar.bz2') 123 if not os.path.exists(output_fullname): 124 archive = MyTarFile.open(output_fullname, 'w:bz2') 125 archive.set_remove_nonessential_files(True) 126 try: 127 archive.add(v8_directory, arcname=output_basename) 128 finally: 129 archive.close() 130 131 return 0 132 133 134 if __name__ == '__main__': 135 sys.exit(main(sys.argv[1:])) 136