justincohen | 6a03a3d | 2016-03-26 21:44:38 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | # Copyright 2016 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 | |
justincohen | aa615f07 | 2016-11-30 18:46:41 | [diff] [blame] | 6 | """Compress and upload Mac toolchain files. |
| 7 | |
| 8 | Stored in in https://pantheon.corp.google.com/storage/browser/chrome-mac-sdk/. |
| 9 | """ |
justincohen | 6a03a3d | 2016-03-26 21:44:38 | [diff] [blame] | 10 | |
Raul Tambre | 9e24293b | 2019-05-12 06:11:07 | [diff] [blame] | 11 | from __future__ import print_function |
| 12 | |
justincohen | 6a03a3d | 2016-03-26 21:44:38 | [diff] [blame] | 13 | import argparse |
| 14 | import glob |
| 15 | import os |
| 16 | import plistlib |
| 17 | import re |
| 18 | import subprocess |
| 19 | import sys |
| 20 | import tarfile |
| 21 | import tempfile |
| 22 | |
| 23 | |
| 24 | TOOLCHAIN_URL = "gs://chrome-mac-sdk" |
| 25 | |
| 26 | # It's important to at least remove unused Platform folders to cut down on the |
| 27 | # size of the toolchain folder. There are other various unused folders that |
| 28 | # have been removed through trial and error. If future versions of Xcode become |
| 29 | # problematic it's possible this list is incorrect, and can be reduced to just |
| 30 | # the unused platforms. On the flip side, it's likely more directories can be |
| 31 | # excluded. |
justincohen | aa615f07 | 2016-11-30 18:46:41 | [diff] [blame] | 32 | DEFAULT_EXCLUDE_FOLDERS = [ |
justincohen | 6a03a3d | 2016-03-26 21:44:38 | [diff] [blame] | 33 | 'Contents/Applications', |
| 34 | 'Contents/Developer/Documentation', |
justincohen | aa615f07 | 2016-11-30 18:46:41 | [diff] [blame] | 35 | 'Contents/Developer/Library/Xcode/Templates', |
justincohen | 6a03a3d | 2016-03-26 21:44:38 | [diff] [blame] | 36 | 'Contents/Developer/Platforms/AppleTVOS.platform', |
| 37 | 'Contents/Developer/Platforms/AppleTVSimulator.platform', |
justincohen | aa615f07 | 2016-11-30 18:46:41 | [diff] [blame] | 38 | 'Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/' |
| 39 | 'usr/share/man/', |
justincohen | 6a03a3d | 2016-03-26 21:44:38 | [diff] [blame] | 40 | 'Contents/Developer/Platforms/WatchOS.platform', |
| 41 | 'Contents/Developer/Platforms/WatchSimulator.platform', |
justincohen | aa615f07 | 2016-11-30 18:46:41 | [diff] [blame] | 42 | 'Contents/Developer/Toolchains/Swift*', |
justincohen | 6a03a3d | 2016-03-26 21:44:38 | [diff] [blame] | 43 | 'Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift', |
justincohen | aa615f07 | 2016-11-30 18:46:41 | [diff] [blame] | 44 | 'Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift-migrator', |
| 45 | 'Contents/Resources/Packages/MobileDevice.pkg', |
justincohen | 6a03a3d | 2016-03-26 21:44:38 | [diff] [blame] | 46 | ] |
| 47 | |
justincohen | aa615f07 | 2016-11-30 18:46:41 | [diff] [blame] | 48 | MAC_EXCLUDE_FOLDERS = [ |
justincohen | ccbbfa2 | 2017-02-13 20:51:43 | [diff] [blame] | 49 | # The only thing we need in iPhoneOS.platform on mac is: |
| 50 | # \Developer\Library\Xcode\PrivatePlugins |
| 51 | # \Info.Plist. |
| 52 | # This is the cleanest way to get these. |
| 53 | 'Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Frameworks', |
| 54 | 'Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/GPUTools', |
| 55 | 'Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/' |
| 56 | 'GPUToolsPlatform', |
| 57 | 'Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/' |
| 58 | 'PrivateFrameworks', |
| 59 | 'Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr', |
| 60 | 'Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs', |
| 61 | 'Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport', |
| 62 | 'Contents/Developer/Platforms/iPhoneOS.platform/Library', |
| 63 | 'Contents/Developer/Platforms/iPhoneOS.platform/usr', |
| 64 | |
| 65 | # iPhoneSimulator has a similar requirement, but the bulk of the binary size is |
| 66 | # in \Developer\SDKs, so only excluding that here. |
justincohen | 62d09b76 | 2017-02-08 00:38:20 | [diff] [blame] | 67 | 'Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs', |
justincohen | aa615f07 | 2016-11-30 18:46:41 | [diff] [blame] | 68 | ] |
| 69 | |
| 70 | IOS_EXCLUDE_FOLDERS = [ |
| 71 | 'Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/' |
| 72 | 'Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/' |
| 73 | 'iPhoneSimulator.sdk/Applications/', |
| 74 | 'Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/' |
| 75 | 'iPhoneSimulator.sdk/System/Library/AccessibilityBundles/', |
| 76 | 'Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/' |
| 77 | 'iPhoneSimulator.sdk/System/Library/CoreServices/', |
| 78 | 'Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/' |
| 79 | 'iPhoneSimulator.sdk/System/Library/LinguisticData/', |
| 80 | ] |
justincohen | 6a03a3d | 2016-03-26 21:44:38 | [diff] [blame] | 81 | |
| 82 | def main(): |
| 83 | """Compress |target_dir| and upload to |TOOLCHAIN_URL|""" |
| 84 | parser = argparse.ArgumentParser() |
| 85 | parser.add_argument('target_dir', |
| 86 | help="Xcode installation directory.") |
justincohen | aa615f07 | 2016-11-30 18:46:41 | [diff] [blame] | 87 | parser.add_argument('platform', choices=['ios', 'mac'], |
| 88 | help="Target platform for bundle.") |
| 89 | parser_args = parser.parse_args() |
justincohen | 6a03a3d | 2016-03-26 21:44:38 | [diff] [blame] | 90 | |
| 91 | # Verify this looks like an Xcode directory. |
justincohen | aa615f07 | 2016-11-30 18:46:41 | [diff] [blame] | 92 | contents_dir = os.path.join(parser_args.target_dir, 'Contents') |
justincohen | 6a03a3d | 2016-03-26 21:44:38 | [diff] [blame] | 93 | plist_file = os.path.join(contents_dir, 'version.plist') |
| 94 | try: |
| 95 | info = plistlib.readPlist(plist_file) |
| 96 | except: |
Raul Tambre | 9e24293b | 2019-05-12 06:11:07 | [diff] [blame] | 97 | print("Invalid Xcode dir.") |
justincohen | 6a03a3d | 2016-03-26 21:44:38 | [diff] [blame] | 98 | return 0 |
| 99 | build_version = info['ProductBuildVersion'] |
| 100 | |
| 101 | # Look for previous toolchain tgz files with the same |build_version|. |
justincohen | aa615f07 | 2016-11-30 18:46:41 | [diff] [blame] | 102 | fname = 'toolchain' |
| 103 | if parser_args.platform == 'ios': |
| 104 | fname = 'ios-' + fname |
| 105 | wildcard_filename = '%s/%s-%s-*.tgz' % (TOOLCHAIN_URL, fname, build_version) |
justincohen | 6a03a3d | 2016-03-26 21:44:38 | [diff] [blame] | 106 | p = subprocess.Popen(['gsutil.py', 'ls', wildcard_filename], |
| 107 | stdout=subprocess.PIPE, |
| 108 | stderr=subprocess.PIPE) |
| 109 | output = p.communicate()[0] |
| 110 | next_count = 1 |
| 111 | if p.returncode == 0: |
| 112 | next_count = len(output.split('\n')) |
| 113 | sys.stdout.write("%s already exists (%s). " |
| 114 | "Do you want to create another? [y/n] " |
| 115 | % (build_version, next_count - 1)) |
| 116 | |
| 117 | if raw_input().lower() not in set(['yes','y', 'ye']): |
Raul Tambre | 9e24293b | 2019-05-12 06:11:07 | [diff] [blame] | 118 | print("Skipping duplicate upload.") |
justincohen | 6a03a3d | 2016-03-26 21:44:38 | [diff] [blame] | 119 | return 0 |
| 120 | |
justincohen | aa615f07 | 2016-11-30 18:46:41 | [diff] [blame] | 121 | os.chdir(parser_args.target_dir) |
| 122 | toolchain_file_name = "%s-%s-%s" % (fname, build_version, next_count) |
justincohen | 6a03a3d | 2016-03-26 21:44:38 | [diff] [blame] | 123 | toolchain_name = tempfile.mktemp(suffix='toolchain.tgz') |
| 124 | |
Raul Tambre | 9e24293b | 2019-05-12 06:11:07 | [diff] [blame] | 125 | print("Creating %s (%s)." % (toolchain_file_name, toolchain_name)) |
justincohen | 6a03a3d | 2016-03-26 21:44:38 | [diff] [blame] | 126 | os.environ["COPYFILE_DISABLE"] = "1" |
justincohen | aa615f07 | 2016-11-30 18:46:41 | [diff] [blame] | 127 | os.environ["GZ_OPT"] = "-8" |
justincohen | 6a03a3d | 2016-03-26 21:44:38 | [diff] [blame] | 128 | args = ['tar', '-cvzf', toolchain_name] |
justincohen | aa615f07 | 2016-11-30 18:46:41 | [diff] [blame] | 129 | exclude_folders = DEFAULT_EXCLUDE_FOLDERS |
| 130 | if parser_args.platform == 'mac': |
| 131 | exclude_folders += MAC_EXCLUDE_FOLDERS |
| 132 | else: |
| 133 | exclude_folders += IOS_EXCLUDE_FOLDERS |
| 134 | args.extend(map('--exclude={0}'.format, exclude_folders)) |
justincohen | 6a03a3d | 2016-03-26 21:44:38 | [diff] [blame] | 135 | args.extend(['.']) |
| 136 | subprocess.check_call(args) |
| 137 | |
Raul Tambre | 9e24293b | 2019-05-12 06:11:07 | [diff] [blame] | 138 | print("Uploading %s toolchain." % toolchain_file_name) |
justincohen | 6a03a3d | 2016-03-26 21:44:38 | [diff] [blame] | 139 | destination_path = '%s/%s.tgz' % (TOOLCHAIN_URL, toolchain_file_name) |
justincohen | a139a156 | 2016-11-16 18:52:24 | [diff] [blame] | 140 | subprocess.check_call(['gsutil.py', 'cp', '-n', toolchain_name, |
| 141 | destination_path]) |
justincohen | 6a03a3d | 2016-03-26 21:44:38 | [diff] [blame] | 142 | |
Raul Tambre | 9e24293b | 2019-05-12 06:11:07 | [diff] [blame] | 143 | print("Done with %s upload." % toolchain_file_name) |
justincohen | 6a03a3d | 2016-03-26 21:44:38 | [diff] [blame] | 144 | return 0 |
| 145 | |
| 146 | if __name__ == '__main__': |
| 147 | sys.exit(main()) |