lib/xcode/install.rb in xcode-install-2.5.0 vs lib/xcode/install.rb in xcode-install-2.6.0

- old
+ new

@@ -6,11 +6,12 @@ require 'rubygems/version' require 'xcode/install/command' require 'xcode/install/version' require 'shellwords' require 'open3' -require 'fileutils' +require 'fastlane/action' +require 'fastlane/actions/verify_build' module XcodeInstall CACHE_DIR = Pathname.new("#{ENV['HOME']}/Library/Caches/XcodeInstall") class Curl COOKIES_PATH = Pathname.new('/tmp/curl-cookies.txt') @@ -55,10 +56,11 @@ FileUtils.rm_f(progress_log_file) retry_options = ['--retry', '3'] command = [ 'curl', + '--disable', *options, *retry_options, '--location', '--continue-at', '-', @@ -208,18 +210,17 @@ all_xcodes.sort_by(&:version) end def install_dmg(dmg_path, suffix = '', switch = true, clean = true) - archive_util = '/System/Library/CoreServices/Applications/Archive Utility.app/Contents/MacOS/Archive Utility' prompt = "Please authenticate for Xcode installation.\nPassword: " xcode_path = "/Applications/Xcode#{suffix}.app" if dmg_path.extname == '.xip' - `'#{archive_util}' #{dmg_path}` - xcode_orig_path = dmg_path.dirname + 'Xcode.app' - xcode_beta_path = dmg_path.dirname + 'Xcode-beta.app' + `xip -x #{dmg_path}` + xcode_orig_path = File.join(Dir.pwd, 'Xcode.app') + xcode_beta_path = File.join(Dir.pwd, 'Xcode-beta.app') if Pathname.new(xcode_orig_path).exist? `sudo -p "#{prompt}" mv "#{xcode_orig_path}" "#{xcode_path}"` elsif Pathname.new(xcode_beta_path).exist? `sudo -p "#{prompt}" mv "#{xcode_beta_path}" "#{xcode_path}"` else @@ -248,17 +249,18 @@ `sudo -p "#{prompt}" ditto "#{source}" "#{xcode_path}"` `umount "/Volumes/Xcode"` end - unless verify_integrity(xcode_path) + xcode = InstalledXcode.new(xcode_path) + + unless xcode.verify_integrity `sudo rm -rf #{xcode_path}` return end enable_developer_mode - xcode = InstalledXcode.new(xcode_path) xcode.approve_license xcode.install_components if switch `sudo rm -f #{SYMLINK_PATH}` unless current_symlink.nil? @@ -362,12 +364,13 @@ if url path = Pathname.new(url) return path if path.exist? end if ENV.key?('XCODE_INSTALL_CACHE_DIR') - cache_path = Pathname.new(ENV['XCODE_INSTALL_CACHE_DIR']) + Pathname.new("xcode-#{version}.dmg") - return cache_path if cache_path.exist? + Pathname.glob(ENV['XCODE_INSTALL_CACHE_DIR'] + '/*').each do |fpath| + return fpath if /^xcode_#{version}\.dmg|xip$/ =~ fpath.basename.to_s + end end download(version, progress, url, progress_block) end @@ -446,15 +449,10 @@ end links end - def verify_integrity(path) - puts `/usr/sbin/spctl --assess --verbose=4 --type execute #{path}` - $?.exitstatus.zero? - end - def hdiutil(*args) io = IO.popen(['hdiutil', *args]) result = io.read io.close unless $?.exitstatus.zero? @@ -576,10 +574,13 @@ template end end class InstalledXcode + TEAM_IDENTIFIER = '59GAB85EFG'.freeze + AUTHORITY = 'Software Signing'.freeze + attr_reader :path attr_reader :version attr_reader :bundle_version attr_reader :uuid attr_reader :downloadable_index_url @@ -611,16 +612,22 @@ end end def approve_license if Gem::Version.new(version) < Gem::Version.new('7.3') - license_path = "#{@path}/Contents/Resources/English.lproj/License.rtf" - license_id = IO.read(license_path).match(/\bEA\d{4}\b/) + license_info_path = File.join(@path, 'Contents/Resources/LicenseInfo.plist') + license_id = `/usr/libexec/PlistBuddy -c 'Print :licenseID' #{license_info_path}` + license_type = `/usr/libexec/PlistBuddy -c 'Print :licenseType' #{license_info_path}` license_plist_path = '/Library/Preferences/com.apple.dt.Xcode.plist' `sudo rm -rf #{license_plist_path}` - `sudo /usr/libexec/PlistBuddy -c "add :IDELastGMLicenseAgreedTo string #{license_id}" #{license_plist_path}` - `sudo /usr/libexec/PlistBuddy -c "add :IDEXcodeVersionForAgreedToGMLicense string #{@version}" #{license_plist_path}` + if license_type == 'GM' + `sudo /usr/libexec/PlistBuddy -c "add :IDELastGMLicenseAgreedTo string #{license_id}" #{license_plist_path}` + `sudo /usr/libexec/PlistBuddy -c "add :IDEXcodeVersionForAgreedToGMLicense string #{version}" #{license_plist_path}` + else + `sudo /usr/libexec/PlistBuddy -c "add :IDELastBetaLicenseAgreedTo string #{license_id}" #{license_plist_path}` + `sudo /usr/libexec/PlistBuddy -c "add :IDEXcodeVersionForAgreedToBetaLicense string #{version}" #{license_plist_path}` + end else `sudo #{@path}/Contents/Developer/usr/bin/xcodebuild -license accept` end end @@ -653,10 +660,14 @@ output = `DEVELOPER_DIR='' "#{@path}/Contents/Developer/usr/bin/xcodebuild" -version` return '0.0' if output.nil? || output.empty? # ¯\_(ツ)_/¯ output.split("\n").first.split(' ')[1] end + def verify_integrity + verify_app_security_assessment && verify_app_cert + end + :private def bundle_version_string digits = plist_entry(':DTXcode').to_i.to_s if digits.length < 3 @@ -666,9 +677,21 @@ end end def plist_entry(keypath) `/usr/libexec/PlistBuddy -c "Print :#{keypath}" "#{path}/Contents/Info.plist"`.chomp + end + + def verify_app_security_assessment + puts `/usr/sbin/spctl --assess --verbose=4 --type execute #{@path}` + $?.exitstatus.zero? + end + + def verify_app_cert + cert_info = Fastlane::Actions::VerifyBuildAction.gather_cert_info(@path.to_s) + apple_team_identifier_result = cert_info['team_identifier'] == TEAM_IDENTIFIER + apple_authority_result = cert_info['authority'].include?(AUTHORITY) + apple_team_identifier_result && apple_authority_result end end # A version of Xcode we fetched from the Apple Developer Portal # we can download & install.