class FastlaneCore::DeviceManager
Public Class Methods
all(requested_os_type = "")
click to toggle source
# File fastlane_core/lib/fastlane_core/device_manager.rb, line 10 def all(requested_os_type = "") return connected_devices(requested_os_type) + simulators(requested_os_type) end
connected_devices(requested_os_type)
click to toggle source
# File fastlane_core/lib/fastlane_core/device_manager.rb, line 68 def connected_devices(requested_os_type) UI.verbose("Fetching available connected devices") device_types = if requested_os_type == "tvOS" ["AppleTV"] elsif requested_os_type == "iOS" ["iPhone", "iPad", "iPod"] else [] end devices = [] # Return early if no supported devices are being searched for if device_types.count == 0 return devices end usb_devices_output = '' Open3.popen3("system_profiler SPUSBDataType -xml") do |stdin, stdout, stderr, wait_thr| usb_devices_output = stdout.read end device_uuids = [] result = Plist.parse_xml(usb_devices_output) discover_devices(result[0], device_types, device_uuids) if result[0] if device_uuids.count > 0 # instruments takes a little while to return so skip it if we have no devices instruments_devices_output = '' Open3.popen3("instruments -s devices") do |stdin, stdout, stderr, wait_thr| instruments_devices_output = stdout.read end instruments_devices_output.split(/\n/).each do |instruments_device| device_uuids.each do |device_uuid| match = instruments_device.match(/(.+) \(([0-9.]+)\) \[(\h{40}|\h{8}-\h{16})\]?/) if match && match[3].delete("-") == device_uuid devices << Device.new(name: match[1], udid: match[3], os_type: requested_os_type, os_version: match[2], state: "Booted", is_simulator: false) UI.verbose("USB Device Found - \"" + match[1] + "\" (" + match[2] + ") UUID:" + match[3]) end end end end return devices end
discover_devices(usb_item, device_types, discovered_device_udids)
click to toggle source
Recursively handle all USB items, discovering devices that match the desired types.
# File fastlane_core/lib/fastlane_core/device_manager.rb, line 116 def discover_devices(usb_item, device_types, discovered_device_udids) (usb_item['_items'] || []).each do |child_item| discover_devices(child_item, device_types, discovered_device_udids) end is_supported_device = device_types.any?(usb_item['_name']) serial_num = usb_item['serial_num'] || '' has_serial_number = serial_num.length == 40 || serial_num.length == 24 if is_supported_device && has_serial_number discovered_device_udids << serial_num end end
latest_simulator_version_for_device(device)
click to toggle source
# File fastlane_core/lib/fastlane_core/device_manager.rb, line 130 def latest_simulator_version_for_device(device) simulators.select { |s| s.name == device } .sort_by { |s| Gem::Version.create(s.os_version) } .last .os_version end
simulators(requested_os_type = "")
click to toggle source
# File fastlane_core/lib/fastlane_core/device_manager.rb, line 14 def simulators(requested_os_type = "") UI.verbose("Fetching available simulator devices") @devices = [] os_type = 'unknown' os_version = 'unknown' output = '' Open3.popen3('xcrun simctl list devices') do |stdin, stdout, stderr, wait_thr| output = stdout.read end runtime_info = '' Open3.popen3('xcrun simctl list runtimes') do |stdin, stdout, stderr, wait_thr| # This regex outputs the version info in the format "<platform> <version><exact version>" runtime_info = stdout.read.lines.map { |v| v.sub(/(\w+ \S+)\s*\((\S+)\s[\S\s]*/, "\\1 \\2") }.drop(1) end exact_versions = Hash.new({}) runtime_info.each do |r| platform, general, exact = r.split exact_versions[platform] = {} unless exact_versions.include?(platform) exact_versions[platform][general] = exact end unless output.include?("== Devices ==") UI.error("xcrun simctl CLI broken, run `xcrun simctl list devices` and make sure it works") UI.user_error!("xcrun simctl not working.") end output.split(/\n/).each do |line| next if line =~ /unavailable/ next if line =~ /^== / if line =~ /^-- / (os_type, os_version) = line.gsub(/-- (.*) --/, '\1').split else next if os_type =~ /^Unavailable/ # " iPad (5th generation) (852A5796-63C3-4641-9825-65EBDC5C4259) (Shutdown)" # This line will turn the above string into # ["iPad (5th generation)", "(852A5796-63C3-4641-9825-65EBDC5C4259)", "(Shutdown)"] matches = line.strip.scan(/^(.*?) (\([^)]*?\)) (\([^)]*?\))$/).flatten.reject(&:empty?) state = matches.pop.to_s.delete('(').delete(')') udid = matches.pop.to_s.delete('(').delete(')') name = matches.join(' ') if matches.count && (os_type == requested_os_type || requested_os_type == "") # This is disabled here because the Device is defined later in the file, and that's a problem for the cop @devices << Device.new(name: name, os_type: os_type, os_version: (exact_versions[os_type][os_version] || os_version), udid: udid, state: state, is_simulator: true) end end end return @devices end