add mac-mavericks to the target_platform list.
[WebKit-https.git] / Tools / BuildSlaveSupport / built-product-archive
1 #!/usr/bin/python
2
3 # Copyright (C) 2009 Apple Inc.  All rights reserved.
4 # Copyright (C) 2012 Google Inc. All rights reserved.
5 #
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
8 # are met:
9 #
10 # 1.  Redistributions of source code must retain the above copyright
11 #     notice, this list of conditions and the following disclaimer. 
12 # 2.  Redistributions in binary form must reproduce the above copyright
13 #     notice, this list of conditions and the following disclaimer in the
14 #     documentation and/or other materials provided with the distribution. 
15 #
16 # THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
17 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 # DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
20 # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27 import optparse
28 import os
29 import shutil
30 import subprocess
31 import sys
32 import zipfile
33
34 _buildDirectory = None
35
36
37 def main():
38     parser = optparse.OptionParser("usage: %prog [options] [action]")
39     parser.add_option("--platform", dest="platform")
40     parser.add_option("--debug", action="store_const", const="debug", dest="configuration")
41     parser.add_option("--release", action="store_const", const="release", dest="configuration")
42
43     options, (action, ) = parser.parse_args()
44     if not options.platform:
45         parser.error("Platform is required")
46         return 1
47     if not options.configuration:
48         parser.error("Configuration is required")
49         return 1
50     if action not in ('archive', 'extract'):
51         parser.error("Action is required")
52         return 1
53
54     genericPlatform = options.platform.split('-', 1)[0]
55     if not determineWebKitBuildDirectory(genericPlatform, options.configuration):
56         print >> sys.stderr, "Could not determine build directory"
57         return 1
58
59     if action == 'archive':
60         return archiveBuiltProduct(options.configuration, genericPlatform, options.platform)
61     else:
62         return extractBuiltProduct(options.configuration, genericPlatform)
63
64
65 def determineWebKitBuildDirectory(platform, configuration):
66     global _buildDirectory
67     _buildDirectory = subprocess.Popen(['perl', os.path.join(os.path.dirname(__file__), "..", "Scripts", "webkit-build-directory"),
68         "--" + platform, "--" + configuration, '--top-level'], stdout=subprocess.PIPE).communicate()[0].strip()
69     return _buildDirectory
70
71
72 def removeDirectoryIfExists(thinDirectory):
73     if os.path.isdir(thinDirectory):
74         shutil.rmtree(thinDirectory)
75
76
77 def copyBuildFiles(source, destination, patterns):
78     shutil.copytree(source, destination, ignore=shutil.ignore_patterns(*patterns))
79
80
81 def createZipManually(directoryToZip, archiveFile):
82     archiveZip = zipfile.ZipFile(archiveFile, "w")
83
84     for path, dirNames, fileNames in os.walk(directoryToZip):
85         relativePath = os.path.relpath(path, directoryToZip)
86         for fileName in fileNames:
87             archiveZip.write(os.path.join(path, fileName), os.path.join(relativePath, fileName))
88
89     archiveZip.close()
90
91
92 def createZip(directoryToZip, configuration, archiveConfigurationOnMac=False):
93     archiveDir = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "WebKitBuild"))
94     archiveFile = os.path.join(archiveDir, configuration + ".zip")
95
96     try:
97         os.unlink(archiveFile)
98     except OSError, e:
99         if e.errno != 2:
100             raise
101
102     if sys.platform == 'darwin':
103         if archiveConfigurationOnMac:
104             return subprocess.call(["ditto", "-c", "-k", "--keepParent", "--sequesterRsrc", directoryToZip, archiveFile])
105         return subprocess.call(["ditto", "-c", "-k", "--sequesterRsrc", directoryToZip, archiveFile])
106     elif sys.platform == 'cygwin':
107         return subprocess.call(["zip", "-r", archiveFile, "bin32"], cwd=directoryToZip)
108     elif sys.platform == 'win32':
109         createZipManually(directoryToZip, archiveFile)
110         return 0
111     elif sys.platform.startswith('linux'):
112         return subprocess.call(["zip", "-y", "-r", archiveFile, "."], cwd=directoryToZip)
113
114
115 def archiveBuiltProduct(configuration, platform, fullPlatform):
116     assert platform in ('mac', 'win', 'qt', 'gtk', 'efl')
117
118     configurationBuildDirectory = os.path.join(_buildDirectory, configuration.title())
119
120     if platform == 'mac':
121         return createZip(configurationBuildDirectory, configuration, archiveConfigurationOnMac=True)
122     elif platform == 'win':
123         binDirectory = os.path.join(configurationBuildDirectory, "bin32")
124         thinDirectory = os.path.join(configurationBuildDirectory, "thin")
125         thinBinDirectory = os.path.join(thinDirectory, "bin32")
126
127         removeDirectoryIfExists(thinDirectory)
128         copyBuildFiles(binDirectory, thinBinDirectory, ['*.ilk'])
129         if createZip(thinDirectory, configuration):
130             return 1
131
132         shutil.rmtree(thinDirectory)
133
134     elif platform == 'qt' or platform == 'gtk' or platform == 'efl':
135         thinDirectory = os.path.join(configurationBuildDirectory, "thin")
136
137         removeDirectoryIfExists(thinDirectory)
138         os.mkdir(thinDirectory)
139
140         if platform == 'qt' or platform == 'efl':
141             neededDirectories = ["bin", "lib"]
142         elif platform == 'gtk':
143             neededDirectories = ["Programs", ".libs", "Libraries", "TestNetscapePlugin"]
144
145         for dirname in neededDirectories:
146             fromDir = os.path.join(configurationBuildDirectory, dirname, ".")
147             toDir = os.path.join(thinDirectory, dirname)
148             os.makedirs(toDir)
149             if subprocess.call('cp -R %s %s' % (fromDir, toDir), shell=True):
150                 return 1
151
152         for root, dirs, files in os.walk(thinDirectory, topdown=False):
153             for name in files:
154                 if name.endswith(".o"):
155                     os.remove(os.path.join(root, name))
156
157         if createZip(thinDirectory, configuration):
158             return 1
159
160 def unzipArchive(directoryToExtractTo, configuration):
161     archiveDir = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "WebKitBuild"))
162     assert os.path.isdir(archiveDir)
163     archiveFile = os.path.join(archiveDir, configuration + ".zip")
164
165     if sys.platform == 'darwin':
166         if subprocess.call(["ditto", "-x", "-k", archiveFile, directoryToExtractTo]):
167             return 1
168     elif sys.platform == 'cygwin' or sys.platform.startswith('linux'):
169         if subprocess.call(["unzip", "-o", archiveFile], cwd=directoryToExtractTo):
170             return 1
171     elif sys.platform == 'win32':
172         archive = zipfile.ZipFile(archiveFile, "r")
173         archive.extractall(directoryToExtractTo)
174         archive.close()
175
176     os.unlink(archiveFile)
177
178
179 def extractBuiltProduct(configuration, platform):
180     assert platform in ('mac', 'win', 'qt', 'gtk', 'efl')
181
182     archiveFile = os.path.join(_buildDirectory, configuration + ".zip")
183     configurationBuildDirectory = os.path.join(_buildDirectory, configuration.title())
184
185     removeDirectoryIfExists(configurationBuildDirectory)
186     os.makedirs(configurationBuildDirectory)
187
188     if platform == 'mac':
189         return unzipArchive(_buildDirectory, configuration)
190     elif platform == 'win':
191         binDirectory = os.path.join(configurationBuildDirectory, "bin32")
192         os.makedirs(binDirectory)
193
194         safariPath = subprocess.Popen('cygpath -w "$PROGRAMFILES"/Safari',
195                                       shell=True, stdout=subprocess.PIPE).communicate()[0].strip()
196
197         if subprocess.call('cp -R "%s"/*.dll "%s"/*.resources %s' % (safariPath, safariPath, binDirectory), shell=True):
198             return 1
199
200         return unzipArchive(configurationBuildDirectory, configuration)
201     elif platform == 'qt' or platform == 'gtk' or platform == 'efl':
202         print "Extracting", configurationBuildDirectory
203         return unzipArchive(configurationBuildDirectory, configuration)
204
205
206 if __name__ == '__main__':
207     sys.exit(main())