| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """Download necessary mac toolchain files under certain conditions. If | 6 """Download necessary mac toolchain files under certain conditions. If |
| 7 xcode-select is already set and points to an external folder | 7 xcode-select is already set and points to an external folder |
| 8 (e.g. /Application/Xcode.app), this script only runs if the GYP_DEFINE | 8 (e.g. /Application/Xcode.app), this script only runs if the GYP_DEFINE |
| 9 |force_mac_toolchain| is set. To override the values in | 9 |force_mac_toolchain| is set. To override the values in |
| 10 |TOOLCHAIN_REVISION|-|TOOLCHAIN_SUB_REVISION| below, GYP_DEFINE | 10 |TOOLCHAIN_REVISION|-|TOOLCHAIN_SUB_REVISION| below, GYP_DEFINE |
| 11 mac_toolchain_revision can be used instead. | 11 mac_toolchain_revision can be used instead. |
| 12 | 12 |
| 13 This script will only run on machines if /usr/bin/xcodebuild and | 13 This script will only run on machines if /usr/bin/xcodebuild and |
| 14 /usr/bin/xcode-select has been added to the sudoers list so the license can be | 14 /usr/bin/xcode-select has been added to the sudoers list so the license can be |
| 15 accepted. | 15 accepted. |
| 16 | 16 |
| 17 Otherwise, user input would be required to complete the script. Perhaps future | 17 Otherwise, user input would be required to complete the script. Perhaps future |
| 18 versions can be modified to allow for user input on developer machines. | 18 versions can be modified to allow for user input on developer machines. |
| 19 """ | 19 """ |
| 20 | 20 |
| 21 import os | 21 import os |
| 22 import plistlib |
| 22 import shutil | 23 import shutil |
| 23 import subprocess | 24 import subprocess |
| 24 import sys | 25 import sys |
| 25 import tarfile | 26 import tarfile |
| 26 import time | 27 import time |
| 27 import tempfile | 28 import tempfile |
| 28 import urllib2 | 29 import urllib2 |
| 29 | 30 |
| 30 # This can be changed after running /build/package_mac_toolchain.py. | 31 # This can be changed after running /build/package_mac_toolchain.py. |
| 31 TOOLCHAIN_REVISION = '5B1008' | 32 TOOLCHAIN_REVISION = '5B1008' |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 os.unlink(temp_name) | 91 os.unlink(temp_name) |
| 91 | 92 |
| 92 | 93 |
| 93 def CanAccessToolchainBucket(): | 94 def CanAccessToolchainBucket(): |
| 94 """Checks whether the user has access to |TOOLCHAIN_URL|.""" | 95 """Checks whether the user has access to |TOOLCHAIN_URL|.""" |
| 95 proc = subprocess.Popen(['gsutil.py', 'ls', TOOLCHAIN_URL], | 96 proc = subprocess.Popen(['gsutil.py', 'ls', TOOLCHAIN_URL], |
| 96 stdout=subprocess.PIPE) | 97 stdout=subprocess.PIPE) |
| 97 proc.communicate() | 98 proc.communicate() |
| 98 return proc.returncode == 0 | 99 return proc.returncode == 0 |
| 99 | 100 |
| 101 def LoadPlist(path): |
| 102 """Loads Plist at |path| and returns it as a dictionary.""" |
| 103 fd, name = tempfile.mkstemp() |
| 104 try: |
| 105 subprocess.check_call(['plutil', '-convert', 'xml1', '-o', name, path]) |
| 106 with os.fdopen(fd, 'r') as f: |
| 107 return plistlib.readPlist(f) |
| 108 finally: |
| 109 os.unlink(name) |
| 110 |
| 100 | 111 |
| 101 def AcceptLicense(directory): | 112 def AcceptLicense(directory): |
| 102 """Use xcodebuild to accept new toolchain license. This only | 113 """Use xcodebuild to accept new toolchain license if necessary. Don't accept |
| 103 works if xcodebuild and xcode-select are in sudoers.""" | 114 the license if a newer license has already been accepted. This only works if |
| 104 xcodebuild_dir = os.path.join(TOOLCHAIN_BUILD_DIR, 'Contents/Developer') | 115 xcodebuild and xcode-select are passwordless in sudoers.""" |
| 116 |
| 117 # Check old license |
| 118 try: |
| 119 target_license_plist_path = \ |
| 120 os.path.join(TOOLCHAIN_BUILD_DIR, |
| 121 *['Contents','Resources','LicenseInfo.plist']) |
| 122 target_license_plist = LoadPlist(target_license_plist_path) |
| 123 build_type = target_license_plist['licenseType'] |
| 124 build_version = target_license_plist['licenseID'] |
| 125 |
| 126 accepted_license_plist = LoadPlist( |
| 127 '/Library/Preferences/com.apple.dt.Xcode.plist') |
| 128 agreed_to_key = 'IDELast%sLicenseAgreedTo' % build_type |
| 129 last_license_agreed_to = accepted_license_plist[agreed_to_key] |
| 130 |
| 131 # Historically all Xcode build numbers have been in the format of AANNNN, so |
| 132 # a simple string compare works. If Xcode's build numbers change this may |
| 133 # need a more complex compare. |
| 134 if build_version <= last_license_agreed_to: |
| 135 # Don't accept the license of older toolchain builds, this will break the |
| 136 # license of newer builds. |
| 137 return |
| 138 except (subprocess.CalledProcessError, KeyError) as e: |
| 139 # If there's never been a license of type |build_type| accepted, |
| 140 # |target_license_plist_path| or |agreed_to_key| may not exist. |
| 141 pass |
| 142 |
| 143 print "Accepting license." |
| 105 old_path = subprocess.Popen(['/usr/bin/xcode-select', '-p'], | 144 old_path = subprocess.Popen(['/usr/bin/xcode-select', '-p'], |
| 106 stdout=subprocess.PIPE).communicate()[0].strip() | 145 stdout=subprocess.PIPE).communicate()[0].strip() |
| 107 subprocess.check_call(['sudo', '/usr/bin/xcode-select', '-s', xcodebuild_dir]) | 146 try: |
| 108 subprocess.check_call(['sudo', '/usr/bin/xcodebuild', '-license', 'accept']) | 147 build_dir = os.path.join(TOOLCHAIN_BUILD_DIR, 'Contents/Developer') |
| 109 subprocess.check_call(['sudo', '/usr/bin/xcode-select', '-s', old_path]) | 148 subprocess.check_call(['sudo', '/usr/bin/xcode-select', '-s', build_dir]) |
| 149 subprocess.check_call(['sudo', '/usr/bin/xcodebuild', '-license', 'accept']) |
| 150 finally: |
| 151 subprocess.check_call(['sudo', '/usr/bin/xcode-select', '-s', old_path]) |
| 110 | 152 |
| 111 | 153 |
| 112 def UseLocalMacSDK(): | 154 def UseLocalMacSDK(): |
| 113 force_pull = os.environ.has_key('FORCE_MAC_TOOLCHAIN') | 155 force_pull = os.environ.has_key('FORCE_MAC_TOOLCHAIN') |
| 114 | 156 |
| 115 # Don't update the toolchain if there's already one installed outside of the | 157 # Don't update the toolchain if there's already one installed outside of the |
| 116 # expected location for a Chromium mac toolchain, unless |force_pull| is set. | 158 # expected location for a Chromium mac toolchain, unless |force_pull| is set. |
| 117 proc = subprocess.Popen(['xcode-select', '-p'], stdout=subprocess.PIPE) | 159 proc = subprocess.Popen(['xcode-select', '-p'], stdout=subprocess.PIPE) |
| 118 xcode_select_dir = proc.communicate()[0] | 160 xcode_select_dir = proc.communicate()[0] |
| 119 rc = proc.returncode | 161 rc = proc.returncode |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 157 print 'Toolchain %s unpacked.' % toolchain_revision | 199 print 'Toolchain %s unpacked.' % toolchain_revision |
| 158 WriteStampFile(toolchain_revision) | 200 WriteStampFile(toolchain_revision) |
| 159 return 0 | 201 return 0 |
| 160 except: | 202 except: |
| 161 print 'Failed to download toolchain %s.' % toolchain_file | 203 print 'Failed to download toolchain %s.' % toolchain_file |
| 162 print 'Exiting.' | 204 print 'Exiting.' |
| 163 return 1 | 205 return 1 |
| 164 | 206 |
| 165 if __name__ == '__main__': | 207 if __name__ == '__main__': |
| 166 sys.exit(main()) | 208 sys.exit(main()) |
| OLD | NEW |