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.
7 This tool creates a tarball with all the sources, but without .svn directories.
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).
14 export_tarball.py /foo/bar
16 The above will create file /foo/bar.tar.bz2.
27 'breakpad/src/processor/testdata',
28 'chrome/browser/resources/tracing/tests',
29 'chrome/common/extensions/docs',
30 'chrome/tools/test/reference_build',
33 'native_client/src/trusted/service_runtime/testdata',
34 'src/chrome/test/data',
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',
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',
66 'webkit/data/layout_tests',
67 'webkit/tools/test/reference_build',
78 def GetSourceDirectory():
79 return os
.path
.realpath(
80 os
.path
.join(os
.path
.dirname(__file__
), '..', '..', '..', 'src'))
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.
85 class MyTarFile(tarfile
.TarFile
):
86 def set_remove_nonessential_files(self
, remove
):
87 self
.__remove
_nonessential
_files
= remove
89 def set_verbose(self
, verbose
):
90 self
.__verbose
= verbose
92 def __report_skipped(self
, name
):
96 def __report_added(self
, name
):
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
)
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
)
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
120 self
.__report
_skipped
(name
)
123 self
.__report
_added
(name
)
124 tarfile
.TarFile
.add(self
, name
, arcname
=arcname
, recursive
=recursive
)
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)
139 options
, args
= parser
.parse_args(argv
)
142 print 'You must provide only one argument: output file name'
143 print '(without .tar.xz extension).'
146 if not os
.path
.exists(GetSourceDirectory()):
147 print 'Cannot find the src directory ' + GetSourceDirectory()
150 # These two commands are from src/DEPS; please keep them in sync.
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.'
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.'
162 output_fullname
= args
[0] + '.tar'
163 output_basename
= options
.basename
or os
.path
.basename(args
[0])
165 archive
= MyTarFile
.open(output_fullname
, 'w')
166 archive
.set_remove_nonessential_files(options
.remove_nonessential_files
)
167 archive
.set_verbose(options
.verbose
)
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
))
174 archive
.add(GetSourceDirectory(), arcname
=output_basename
)
180 pv
= subprocess
.Popen(
181 ['pv', '--force', output_fullname
],
182 stdout
=subprocess
.PIPE
,
184 with
open(output_fullname
+ '.xz', 'w') as f
:
185 rc
= subprocess
.call(['xz', '-9', '-'], stdin
=pv
.stdout
, stdout
=f
)
188 rc
= subprocess
.call(['xz', '-9', output_fullname
])
191 print 'xz -9 failed!'
197 if __name__
== "__main__":
198 sys
.exit(main(sys
.argv
[1:]))