Class: Fastlane::CreateSimulatorDevices::ShellHelper

Inherits:
Object
  • Object
show all
Defined in:
lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/shell_helper.rb

Overview

Shell helper

Constant Summary collapse

UI =
::Fastlane::UI

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(verbose: false, action_context: nil) ⇒ ShellHelper

Returns a new instance of ShellHelper.



15
16
17
18
# File 'lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/shell_helper.rb', line 15

def initialize(verbose: false, action_context: nil)
  self.verbose = verbose
  self.action_context = action_context
end

Instance Attribute Details

#action_contextObject

Proprty verbose



13
14
15
# File 'lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/shell_helper.rb', line 13

def action_context
  @action_context
end

#verboseObject

Proprty verbose



13
14
15
# File 'lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/shell_helper.rb', line 13

def verbose
  @verbose
end

Instance Method Details

#available_device_types(force: false) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/shell_helper.rb', line 54

def available_device_types(force: false)
  return @available_device_types unless force || @available_device_types.nil?

  UI.message('Fetching available device types...')
  json = sh(command: 'xcrun simctl list --json --no-escape-slashes devicetypes')

  @available_device_types = JSON
    .parse(json, symbolize_names: true)[:devicetypes]
    .map { |device_type| SimCTL::DeviceType.from_hash(device_type) }

  @available_device_types
end

#available_devices_for_runtimes(force: false) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/shell_helper.rb', line 77

def available_devices_for_runtimes(force: false)
  return @available_devices_for_runtimes unless force || @available_devices_for_runtimes.nil?

  UI.message('Fetching available devices...')
  json = sh(command: 'xcrun simctl list --json --no-escape-slashes devices')

  @available_devices_for_runtimes = JSON
    .parse(json, symbolize_names: true)[:devices]
    .transform_values { |devices| devices.map { |device| SimCTL::Device.from_hash(device) } }

  @available_devices_for_runtimes
end

#available_runtimes(force: false) ⇒ Object



90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/shell_helper.rb', line 90

def available_runtimes(force: false)
  return @available_runtimes unless force || @available_runtimes.nil?

  UI.message('Fetching available runtimes...')
  json = sh(command: 'xcrun simctl list --json --no-escape-slashes runtimes')

  @available_runtimes = JSON
    .parse(json, symbolize_names: true)[:runtimes]
    .map { |runtime| SimCTL::Runtime.from_hash(runtime) }
    .select(&:available?)

  @available_runtimes
end

#available_sdks(force: false) ⇒ Object



113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/shell_helper.rb', line 113

def available_sdks(force: false)
  return @available_sdks unless force || @available_sdks.nil?

  UI.message('Fetching available sdks...')
  json = sh(command: 'xcrun xcodebuild -showsdks -json')

  @available_sdks = JSON
    .parse(json, symbolize_names: true)
    .map { |sdk| Xcodebuild::SDK.from_hash(sdk) }

  @available_sdks
end

#create_device(name, device_type_identifier, runtime_identifier) ⇒ Object



126
127
128
129
# File 'lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/shell_helper.rb', line 126

def create_device(name, device_type_identifier, runtime_identifier)
  UI.message("Creating device #{name}")
  sh(command: "xcrun simctl create #{name.shellescape} #{device_type_identifier.shellescape} #{runtime_identifier.shellescape}")
end

#delete_device(udid) ⇒ Object



67
68
69
70
# File 'lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/shell_helper.rb', line 67

def delete_device(udid)
  UI.message("Deleting device #{udid}...")
  sh(command: "xcrun simctl delete #{udid.shellescape}")
end

#delete_runtime(runtime_identifier) ⇒ Object



131
132
133
134
# File 'lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/shell_helper.rb', line 131

def delete_runtime(runtime_identifier)
  UI.message("Deleting runtime #{runtime_identifier}...")
  sh(command: "xcrun simctl runtime delete #{runtime_identifier.shellescape}")
end

#delete_unavailable_devicesObject



72
73
74
75
# File 'lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/shell_helper.rb', line 72

def delete_unavailable_devices
  UI.message('Deleting unavailable devices...')
  sh(command: 'xcrun simctl delete unavailable')
end

#download_runtime(missing_runtime, cache_dir) ⇒ Object



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/shell_helper.rb', line 136

def download_runtime(missing_runtime, cache_dir)
  UI.message("Downloading #{missing_runtime.runtime_name} to #{cache_dir}. This may take a while...")

  command = [
    'xcrun',
    'xcodebuild',
    '-verbose',

    '-exportPath',
    cache_dir.shellescape,

    '-downloadPlatform',
    missing_runtime.os_name.shellescape
  ]

  unless missing_runtime.latest?
    command << '-buildVersion'
    # Prefer the build version if available, otherwise use the product version.
    command << (missing_runtime.product_build_version || missing_runtime.product_version.to_s).shellescape
  end

  sh(command: command.join(' '), print_command: true, print_command_output: true)
end

#import_runtime(runtime_dmg_filename, runtime_name) ⇒ Object



160
161
162
163
164
165
166
167
168
# File 'lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/shell_helper.rb', line 160

def import_runtime(runtime_dmg_filename, runtime_name)
  UI.message("Importing runtime #{runtime_name} image from #{runtime_dmg_filename}...")
  import_platform_command = "xcrun xcodebuild -verbose -importPlatform #{runtime_dmg_filename.shellescape}"
  begin
    sh(command: import_platform_command)
  rescue StandardError => e
    UI.important("Failed to import runtime #{runtime_name} with '#{import_platform_command}' :\n#{e}")
  end
end

#installed_runtimes_with_stateObject



104
105
106
107
108
109
110
111
# File 'lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/shell_helper.rb', line 104

def installed_runtimes_with_state
  UI.message('Fetching runtimes with state...')
  json = sh(command: 'xcrun simctl runtime list --json')

  JSON
    .parse(json, symbolize_names: true)
    .map { |_, runtime| SimCTL::RuntimeWithState.from_hash(runtime) }
end

#sh(command:, print_command: verbose, print_command_output: verbose) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/shell_helper.rb', line 20

def sh(command:, print_command: verbose, print_command_output: verbose)
  if action_context
    action_context.sh(command, print_command:, print_command_output:)
  else
    # Fallback for testing or direct usage
    require 'open3'
    stdout, stderr, status = Open3.capture3(command)

    UI.message command if print_command

    if status.success?
      UI.message stdout if print_command_output
      stdout
    else
      error_message = "Command failed: #{command}\n#{stderr}"
      UI.error error_message
      raise StandardError, error_message
    end
  end
end

#stop_core_simulator_servicesObject



41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/shell_helper.rb', line 41

def stop_core_simulator_services
  UI.message('Stop CoreSimulator')
  services_to_stop = [
    'com.apple.CoreSimulator.CoreSimulatorService',
    'com.apple.CoreSimulator.SimulatorTrampoline',
    'com.apple.CoreSimulator.SimLaunchHost-arm64',
    'com.apple.CoreSimulator.SimLaunchHost-x86'
  ]
  services_to_stop.each do |service|
    sh(command: "launchctl remove #{service} || true")
  end
end