Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 #!/usr/bin/env python | |
| 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 | |
| 4 # found in the LICENSE file. | |
| 5 | |
| 6 """ | |
| 7 This tool creates a tarball with all the sources, but without .svn directories. | |
| 8 | |
| 9 It can also remove files which are not strictly required for build, so that | |
| 10 the resulting tarball can be reasonably small (last time it was ~110 MB). | |
| 11 | |
| 12 Example usage: | |
| 13 | |
| 14 export_tarball.py /foo/bar | |
| 15 | |
| 16 The above will create file /foo/bar.tar.bz2. | |
| 17 """ | |
| 18 | |
| 19 import optparse | |
| 20 import os | |
| 21 import subprocess | |
| 22 import sys | |
| 23 import tarfile | |
| 24 | |
| 25 | |
| 26 NONESSENTIAL_DIRS = ( | |
| 27 'breakpad/src/processor/testdata', | |
| 28 'chrome/browser/resources/tracing/tests', | |
| 29 'chrome/common/extensions/docs', | |
| 30 'chrome/tools/test/reference_build', | |
| 31 'courgette/testdata', | |
| 32 'data', | |
| 33 'native_client/src/trusted/service_runtime/testdata', | |
| 34 'src/chrome/test/data', | |
| 35 'o3d/documentation', | |
| 36 'o3d/samples', | |
| 37 'o3d/tests', | |
| 38 'ppapi/examples', | |
| 39 'ppapi/native_client/tests', | |
| 40 'third_party/angle/samples/gles2_book', | |
| 41 'third_party/findbugs', | |
| 42 'third_party/hunspell_dictionaries', | |
| 43 'third_party/hunspell/tests', | |
| 44 'third_party/lighttpd', | |
| 45 'third_party/sqlite/src/test', | |
| 46 'third_party/sqlite/test', | |
| 47 'third_party/vc_80', | |
| 48 'third_party/xdg-utils/tests', | |
| 49 'third_party/yasm/source/patched-yasm/modules/arch/x86/tests', | |
| 50 'third_party/yasm/source/patched-yasm/modules/dbgfmts/dwarf2/tests', | |
| 51 'third_party/yasm/source/patched-yasm/modules/objfmts/bin/tests', | |
| 52 'third_party/yasm/source/patched-yasm/modules/objfmts/coff/tests', | |
| 53 'third_party/yasm/source/patched-yasm/modules/objfmts/elf/tests', | |
| 54 'third_party/yasm/source/patched-yasm/modules/objfmts/macho/tests', | |
| 55 'third_party/yasm/source/patched-yasm/modules/objfmts/rdf/tests', | |
| 56 'third_party/yasm/source/patched-yasm/modules/objfmts/win32/tests', | |
| 57 'third_party/yasm/source/patched-yasm/modules/objfmts/win64/tests', | |
| 58 'third_party/yasm/source/patched-yasm/modules/objfmts/xdf/tests', | |
| 59 'third_party/WebKit/LayoutTests', | |
| 60 'third_party/WebKit/Source/JavaScriptCore/tests', | |
| 61 'third_party/WebKit/Source/WebCore/ChangeLog', | |
| 62 'third_party/WebKit/Source/WebKit2', | |
| 63 'third_party/WebKit/Tools/Scripts', | |
| 64 'tools/gyp/test', | |
| 65 'v8/test', | |
| 66 'webkit/data/layout_tests', | |
| 67 'webkit/tools/test/reference_build', | |
| 68 ) | |
| 69 | |
| 70 TESTDIRS = ( | |
| 71 'chrome/test/data', | |
| 72 'content/test/data', | |
| 73 'media/test/data', | |
| 74 'net/data', | |
| 75 ) | |
| 76 | |
| 77 | |
| 78 def GetSourceDirectory(): | |
| 79 return os.path.realpath( | |
| 80 os.path.join(os.path.dirname(__file__), '..', '..', '..', 'src')) | |
| 81 | |
| 82 | |
| 83 # Workaround lack of the exclude parameter in add method in python-2.4. | |
| 84 # TODO(phajdan.jr): remove the workaround when it's not needed on the bot. | |
|
pgervais
2015/04/24 18:05:05
Maybe it's time. The oldest Python we have is 2.6,
Paweł Hajdan Jr.
2015/04/24 18:15:39
We should be on 2.7 everywhere. I plan to look int
| |
| 85 class MyTarFile(tarfile.TarFile): | |
| 86 def set_remove_nonessential_files(self, remove): | |
| 87 self.__remove_nonessential_files = remove | |
| 88 | |
| 89 def set_verbose(self, verbose): | |
| 90 self.__verbose = verbose | |
| 91 | |
| 92 def __report_skipped(self, name): | |
| 93 if self.__verbose: | |
| 94 print 'D\t%s' % name | |
| 95 | |
| 96 def __report_added(self, name): | |
| 97 if self.__verbose: | |
| 98 print 'A\t%s' % name | |
| 99 | |
| 100 def add(self, name, arcname=None, recursive=True, exclude=None, filter=None): | |
| 101 head, tail = os.path.split(name) | |
| 102 if tail in ('.svn', '.git'): | |
| 103 self.__report_skipped(name) | |
| 104 return | |
| 105 | |
| 106 if self.__remove_nonessential_files: | |
| 107 # WebKit change logs take quite a lot of space. This saves ~10 MB | |
| 108 # in a bzip2-compressed tarball. | |
| 109 if 'ChangeLog' in name: | |
| 110 self.__report_skipped(name) | |
| 111 return | |
| 112 | |
| 113 # Remove contents of non-essential directories, but preserve gyp files, | |
| 114 # so that build/gyp_chromium can work. | |
| 115 for nonessential_dir in (NONESSENTIAL_DIRS + TESTDIRS): | |
| 116 dir_path = os.path.join(GetSourceDirectory(), nonessential_dir) | |
| 117 if (name.startswith(dir_path) and | |
| 118 os.path.isfile(name) and | |
| 119 'gyp' not in name): | |
| 120 self.__report_skipped(name) | |
| 121 return | |
| 122 | |
| 123 self.__report_added(name) | |
| 124 tarfile.TarFile.add(self, name, arcname=arcname, recursive=recursive) | |
| 125 | |
| 126 | |
| 127 def main(argv): | |
| 128 parser = optparse.OptionParser() | |
| 129 parser.add_option("--basename") | |
| 130 parser.add_option("--remove-nonessential-files", | |
| 131 dest="remove_nonessential_files", | |
| 132 action="store_true", default=False) | |
| 133 parser.add_option("--test-data", action="store_true") | |
| 134 # TODO(phajdan.jr): Remove --xz option when it's not needed for compatibility. | |
| 135 parser.add_option("--xz", action="store_true") | |
| 136 parser.add_option("--verbose", action="store_true", default=False) | |
| 137 parser.add_option("--progress", action="store_true", default=False) | |
| 138 | |
| 139 options, args = parser.parse_args(argv) | |
| 140 | |
| 141 if len(args) != 1: | |
| 142 print 'You must provide only one argument: output file name' | |
| 143 print '(without .tar.xz extension).' | |
| 144 return 1 | |
| 145 | |
| 146 if not os.path.exists(GetSourceDirectory()): | |
| 147 print 'Cannot find the src directory ' + GetSourceDirectory() | |
| 148 return 1 | |
| 149 | |
| 150 # These two commands are from src/DEPS; please keep them in sync. | |
|
pgervais
2015/04/24 18:05:05
I guess there is a similar comment in src/DEPS. Co
Paweł Hajdan Jr.
2015/04/24 18:15:39
I uploaded https://codereview.chromium.org/1105963
pgervais
2015/04/24 18:32:22
Keeping two things in sync in two different repos
| |
| 151 if subprocess.call(['python', 'build/util/lastchange.py', '-o', | |
| 152 'build/util/LASTCHANGE'], cwd=GetSourceDirectory()) != 0: | |
| 153 print 'Could not run build/util/lastchange.py to update LASTCHANGE.' | |
| 154 return 1 | |
| 155 if subprocess.call(['python', 'build/util/lastchange.py', '-s', | |
| 156 'third_party/WebKit', '-o', | |
| 157 'build/util/LASTCHANGE.blink'], | |
| 158 cwd=GetSourceDirectory()) != 0: | |
| 159 print 'Could not run build/util/lastchange.py to update LASTCHANGE.blink.' | |
| 160 return 1 | |
| 161 | |
| 162 output_fullname = args[0] + '.tar' | |
| 163 output_basename = options.basename or os.path.basename(args[0]) | |
| 164 | |
| 165 archive = MyTarFile.open(output_fullname, 'w') | |
| 166 archive.set_remove_nonessential_files(options.remove_nonessential_files) | |
| 167 archive.set_verbose(options.verbose) | |
| 168 try: | |
| 169 if options.test_data: | |
| 170 for directory in TESTDIRS: | |
| 171 archive.add(os.path.join(GetSourceDirectory(), directory), | |
| 172 arcname=os.path.join(output_basename, directory)) | |
| 173 else: | |
| 174 archive.add(GetSourceDirectory(), arcname=output_basename) | |
| 175 finally: | |
| 176 archive.close() | |
| 177 | |
| 178 if options.progress: | |
| 179 sys.stdout.flush() | |
| 180 pv = subprocess.Popen( | |
| 181 ['pv', '--force', output_fullname], | |
| 182 stdout=subprocess.PIPE, | |
| 183 stderr=sys.stdout) | |
| 184 with open(output_fullname + '.xz', 'w') as f: | |
| 185 rc = subprocess.call(['xz', '-9', '-'], stdin=pv.stdout, stdout=f) | |
| 186 pv.wait() | |
| 187 else: | |
| 188 rc = subprocess.call(['xz', '-9', output_fullname]) | |
| 189 | |
| 190 if rc != 0: | |
| 191 print 'xz -9 failed!' | |
| 192 return 1 | |
| 193 | |
| 194 return 0 | |
| 195 | |
| 196 | |
| 197 if __name__ == "__main__": | |
| 198 sys.exit(main(sys.argv[1:])) | |
| OLD | NEW |