require_relative 'ui/ui' module FastlaneCore class ProvisioningProfile class << self # @return (Hash) The hash with the data of the provisioning profile # @example # {"AppIDName"=>"My App Name", # "ApplicationIdentifierPrefix"=>["5A997XSAAA"], # "CreationDate"=>#, # "DeveloperCertificates"=>[#], # "Entitlements"=> # {"keychain-access-groups"=>["5A997XSAAA.*"], # "get-task-allow"=>false, # "application-identifier"=>"5A997XAAA.net.sunapps.192", # "com.apple.developer.team-identifier"=>"5A997XAAAA", # "aps-environment"=>"production", # "beta-reports-active"=>true}, # "ExpirationDate"=>#, # "Name"=>"net.sunapps.192 AppStore", # "TeamIdentifier"=>["5A997XSAAA"], # "TeamName"=>"SunApps GmbH", # "TimeToLive"=>185, # "UUID"=>"1752e382-53bd-4910-a393-aaa7de0005ad", # "Version"=>1} def parse(path) require 'plist' plist = Plist.parse_xml(decode(path)) if (plist || []).count > 5 plist else UI.crash!("Error parsing provisioning profile at path '#{path}'") end end # @return [String] The UUID of the given provisioning profile def uuid(path) parse(path).fetch("UUID") end # @return [String] The Name of the given provisioning profile def name(path) parse(path).fetch("Name") end def profiles_path path = File.expand_path("~") + "/Library/MobileDevice/Provisioning Profiles/" # If the directory doesn't exist, create it first unless File.directory?(path) FileUtils.mkdir_p(path) end return path end # Installs a provisioning profile for Xcode to use def install(path) UI.message("Installing provisioning profile...") profile_filename = uuid(path) + ".mobileprovision" destination = File.join(profiles_path, profile_filename) if path != destination # copy to Xcode provisioning profile directory FileUtils.copy(path, destination) unless File.exist?(destination) UI.user_error!("Failed installation of provisioning profile at location: '#{destination}'") end end destination end private def decode(path) require 'tmpdir' Dir.mktmpdir('fastlane') do |dir| err = "#{dir}/cms.err" # we want to prevent the error output to mix up with the standard output because of # /dev/null: https://github.com/fastlane/fastlane/issues/6387 decoded = `security cms -D -i "#{path}" 2> #{err}` UI.error("Failure to decode #{path}. Exit: #{$?.exitstatus}: #{File.read(err)}") if $?.exitstatus != 0 decoded end end end end end