fastlane-plugin-create_simulator_devices 0.0.11 → 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/fastlane/plugin/create_simulator_devices/actions/create_simulator_devices_action.rb +30 -4
- data/lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/models/apple_build_version.rb +11 -3
- data/lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/models/device_naming_style.rb +14 -0
- data/lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/models/required_device.rb +4 -4
- data/lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/models.rb +1 -0
- data/lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/runner.rb +114 -36
- data/lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/runtime_helper.rb +34 -29
- data/lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/shell_helper.rb +28 -19
- data/lib/fastlane/plugin/create_simulator_devices/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fbcf5d008c0e2e248db6b53d80c89c681cd516837439e1da34e95375c135e934
|
4
|
+
data.tar.gz: adc56432be831c59c299204092d96392f3a9483d08ae625a6c5d31695d58a3f0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ded9ef76090109dd7f69d96384625e3899bed635d8d59aee8213954cfe33003be2874de36b0b8aae3bf16cf7e10a27bd59adfd51a9cd4d7d3a2600061bf39d8e
|
7
|
+
data.tar.gz: 02cf2720d898e0cb315bb37d13eb1d86a9b10815635def22781465a3a268e1119b836bf39da22793b4c07d317565f67f118a329511035d478865ab3b3accf285
|
data/lib/fastlane/plugin/create_simulator_devices/actions/create_simulator_devices_action.rb
CHANGED
@@ -4,6 +4,7 @@ require 'fastlane'
|
|
4
4
|
require 'spaceship'
|
5
5
|
require_relative '../helpers/create_simulator_devices/runner'
|
6
6
|
require_relative '../helpers/create_simulator_devices/models'
|
7
|
+
require_relative '../helpers/create_simulator_devices/models/device_naming_style'
|
7
8
|
|
8
9
|
module Fastlane
|
9
10
|
module Actions
|
@@ -22,12 +23,15 @@ module Fastlane
|
|
22
23
|
UI.user_error!('No devices specified') if required_devices.nil? || required_devices.empty?
|
23
24
|
|
24
25
|
shell_helper = CreateSimulatorDevices::ShellHelper.new(print_command: params[:print_command], print_command_output: params[:print_command_output], action_context: self)
|
25
|
-
runtime_helper = CreateSimulatorDevices::RuntimeHelper.new(cache_dir: params[:cache_dir], shell_helper
|
26
|
+
runtime_helper = CreateSimulatorDevices::RuntimeHelper.new(cache_dir: params[:cache_dir], shell_helper: shell_helper, verbose: verbose)
|
26
27
|
|
27
28
|
runner = CreateSimulatorDevices::Runner.new(
|
28
29
|
runtime_helper: runtime_helper,
|
29
30
|
shell_helper: shell_helper,
|
30
|
-
verbose: verbose
|
31
|
+
verbose: verbose,
|
32
|
+
can_rename_devices: params[:rename_devices],
|
33
|
+
can_delete_duplicate_devices: params[:delete_duplicate_devices],
|
34
|
+
device_naming_style: params[:device_naming_style].to_sym
|
31
35
|
)
|
32
36
|
|
33
37
|
runner.run(required_devices)
|
@@ -52,7 +56,7 @@ module Fastlane
|
|
52
56
|
)"
|
53
57
|
end
|
54
58
|
|
55
|
-
def self.available_options
|
59
|
+
def self.available_options # rubocop:disable Metrics/MethodLength
|
56
60
|
[
|
57
61
|
::FastlaneCore::ConfigItem.new(key: :devices,
|
58
62
|
env_name: 'SCAN_DEVICES',
|
@@ -80,7 +84,29 @@ module Fastlane
|
|
80
84
|
description: 'Print xcrun simctl commands output',
|
81
85
|
type: Boolean,
|
82
86
|
optional: true,
|
83
|
-
default_value: false)
|
87
|
+
default_value: false),
|
88
|
+
::FastlaneCore::ConfigItem.new(key: :rename_devices,
|
89
|
+
env_name: 'CREATE_SIMULATOR_DEVICES_RENAME_DEVICES',
|
90
|
+
description: 'Rename devices if needed',
|
91
|
+
type: Boolean,
|
92
|
+
optional: true,
|
93
|
+
default_value: false),
|
94
|
+
::FastlaneCore::ConfigItem.new(key: :delete_duplicate_devices,
|
95
|
+
env_name: 'CREATE_SIMULATOR_DEVICES_DELETE_DUPLICATE_DEVICES',
|
96
|
+
description: 'Delete duplicate devices',
|
97
|
+
type: Boolean,
|
98
|
+
optional: true,
|
99
|
+
default_value: false),
|
100
|
+
::FastlaneCore::ConfigItem.new(key: :device_naming_style,
|
101
|
+
env_name: 'CREATE_SIMULATOR_DEVICES_DEVICE_NAMING_STYLE',
|
102
|
+
description: 'Device naming style',
|
103
|
+
type: String,
|
104
|
+
optional: true,
|
105
|
+
default_value: CreateSimulatorDevices::DeviceNamingStyle::SCAN.to_s,
|
106
|
+
verify_block: proc do |value|
|
107
|
+
allowed_values = CreateSimulatorDevices::DeviceNamingStyle::ALL
|
108
|
+
UI.user_error!("Invalid device naming style: #{value}. Allowed values: #{allowed_values.map(&:to_s).join(', ')}") unless allowed_values.include?(value.to_sym)
|
109
|
+
end)
|
84
110
|
]
|
85
111
|
end
|
86
112
|
|
@@ -58,11 +58,19 @@ module Fastlane
|
|
58
58
|
return self == other unless lhs_is_beta && rhs_is_beta && @build_version.length == rhs_build_version.to_s.length
|
59
59
|
|
60
60
|
# Take only leading chars up to the first letter included e.g. 22C146 -> 22C
|
61
|
-
|
61
|
+
major == rhs_build_version.major && minor == rhs_build_version.minor && patch == rhs_build_version.patch
|
62
62
|
end
|
63
63
|
|
64
|
-
def
|
65
|
-
|
64
|
+
def major
|
65
|
+
@build_version.match(/^([0-9]+)([A-Z][0-9]{2,3})([0-9]+)/)[1]
|
66
|
+
end
|
67
|
+
|
68
|
+
def minor
|
69
|
+
@build_version.match(/^([0-9]+)([A-Z][0-9]{2,3})([0-9]+)/)[2]
|
70
|
+
end
|
71
|
+
|
72
|
+
def patch
|
73
|
+
@build_version.match(/^([0-9]+)([A-Z][0-9]{2,3})([0-9]+)/)[3]
|
66
74
|
end
|
67
75
|
|
68
76
|
def <(other)
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Fastlane
|
4
|
+
module CreateSimulatorDevices
|
5
|
+
class DeviceNamingStyle
|
6
|
+
SCAN = :scan
|
7
|
+
RUN_TESTS = :run_tests
|
8
|
+
SNAPSHOT = :snapshot
|
9
|
+
CAPTURE_IOS_SCREENSHOTS = :capture_ios_screenshots
|
10
|
+
|
11
|
+
ALL = [SCAN, RUN_TESTS, SNAPSHOT, CAPTURE_IOS_SCREENSHOTS].freeze
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -4,14 +4,14 @@ module Fastlane
|
|
4
4
|
module CreateSimulatorDevices
|
5
5
|
# Represents a required runtime.
|
6
6
|
class RequiredDevice
|
7
|
-
attr_accessor :device_type, :os_name, :required_runtime, :
|
7
|
+
attr_accessor :device_type, :os_name, :required_runtime, :simctl_runtime, :simctl_device
|
8
8
|
|
9
|
-
def initialize(device_type:, os_name:, required_runtime:,
|
9
|
+
def initialize(device_type:, os_name:, required_runtime:, simctl_runtime:, simctl_device:)
|
10
10
|
self.device_type = device_type
|
11
11
|
self.os_name = os_name
|
12
12
|
self.required_runtime = required_runtime
|
13
|
-
self.
|
14
|
-
self.
|
13
|
+
self.simctl_runtime = simctl_runtime
|
14
|
+
self.simctl_device = simctl_device
|
15
15
|
end
|
16
16
|
|
17
17
|
def description
|
data/lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/models.rb
CHANGED
@@ -8,6 +8,7 @@ require_relative 'models/xcodebuild/sdk'
|
|
8
8
|
require_relative 'models/required_device'
|
9
9
|
require_relative 'models/required_runtime'
|
10
10
|
require_relative 'models/apple_build_version'
|
11
|
+
require_relative 'models/device_naming_style'
|
11
12
|
require 'fastlane'
|
12
13
|
|
13
14
|
module Fastlane
|
data/lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/runner.rb
CHANGED
@@ -3,20 +3,24 @@
|
|
3
3
|
require_relative 'runtime_helper'
|
4
4
|
require 'fastlane'
|
5
5
|
require_relative 'shared_values'
|
6
|
+
require_relative 'models/device_naming_style'
|
6
7
|
|
7
8
|
module Fastlane
|
8
9
|
# Create simulator devices.
|
9
10
|
module CreateSimulatorDevices
|
10
11
|
# Does all the work to create simulator devices.
|
11
|
-
class Runner
|
12
|
+
class Runner # rubocop:disable Metrics/ClassLength
|
12
13
|
UI = ::Fastlane::UI unless defined?(UI)
|
13
14
|
|
14
|
-
attr_accessor :shell_helper, :verbose, :runtime_helper
|
15
|
+
attr_accessor :shell_helper, :verbose, :runtime_helper, :can_rename_devices, :can_delete_duplicate_devices, :device_naming_style
|
15
16
|
|
16
|
-
def initialize(runtime_helper:, shell_helper:, verbose:)
|
17
|
+
def initialize(runtime_helper:, shell_helper:, verbose:, can_rename_devices:, can_delete_duplicate_devices:, device_naming_style:) # rubocop:disable Metrics/ParameterLists
|
17
18
|
self.shell_helper = shell_helper
|
18
19
|
self.verbose = verbose
|
19
20
|
self.runtime_helper = runtime_helper
|
21
|
+
self.can_rename_devices = can_rename_devices
|
22
|
+
self.can_delete_duplicate_devices = can_delete_duplicate_devices
|
23
|
+
self.device_naming_style = device_naming_style
|
20
24
|
end
|
21
25
|
|
22
26
|
def run(devices)
|
@@ -46,14 +50,16 @@ module Fastlane
|
|
46
50
|
|
47
51
|
# Return distinct matched devices strings
|
48
52
|
matched_devices = required_devices
|
49
|
-
.reject { |required_device| required_device.
|
53
|
+
.reject { |required_device| required_device.simctl_device.nil? }
|
50
54
|
|
51
55
|
log_matched_devices(matched_devices: matched_devices)
|
52
56
|
|
53
|
-
|
54
|
-
|
57
|
+
matched_devices_names = matched_devices.map { |matched_device| returning_device_name_for_required_device(matched_device) }
|
58
|
+
UI.message("Available simulator devices: #{matched_devices_names.join(', ')}")
|
55
59
|
|
56
|
-
|
60
|
+
Actions.lane_context[Actions::SharedValues::AVAILABLE_SIMULATOR_DEVICES] = matched_devices_names
|
61
|
+
|
62
|
+
matched_devices_names
|
57
63
|
end
|
58
64
|
|
59
65
|
def log_matched_devices(matched_devices:)
|
@@ -63,46 +69,118 @@ module Fastlane
|
|
63
69
|
matched_devices.each do |matched_device|
|
64
70
|
device_info = ''
|
65
71
|
if verbose
|
66
|
-
device_info = shell_helper.device_info_by_udid(matched_device.
|
72
|
+
device_info = shell_helper.device_info_by_udid(matched_device.simctl_device.udid)
|
67
73
|
device_info = "\n#{device_info}"
|
68
74
|
end
|
69
|
-
UI.message(" #{matched_device.description}: #{matched_device.
|
75
|
+
UI.message(" #{matched_device.description}: #{matched_device.simctl_device.description}#{device_info}")
|
70
76
|
end
|
71
|
-
|
72
|
-
matched_devices_names = matched_devices
|
73
|
-
.map { |matched_device| matched_device.available_device.name }
|
74
|
-
.join(', ')
|
75
|
-
UI.message("Available simulator devices: #{matched_devices_names}")
|
76
77
|
end
|
77
78
|
|
78
79
|
def delete_unavailable_devices
|
79
|
-
return unless shell_helper.
|
80
|
+
return unless shell_helper.simctl_devices_for_runtimes.values.flatten.any?(&:available?)
|
80
81
|
|
81
82
|
shell_helper.delete_unavailable_devices
|
82
83
|
|
83
|
-
shell_helper.
|
84
|
+
shell_helper.simctl_devices_for_runtimes(force: true)
|
84
85
|
end
|
85
86
|
|
86
|
-
def
|
87
|
-
return nil if required_device.
|
87
|
+
def simctl_device_for_required_device(required_device)
|
88
|
+
return nil if required_device.simctl_runtime.nil?
|
88
89
|
|
89
|
-
|
90
|
+
simctl_devices = shell_helper.simctl_devices_for_runtimes[required_device.simctl_runtime.identifier.to_sym]
|
90
91
|
|
91
|
-
return
|
92
|
+
return nil if simctl_devices.nil?
|
92
93
|
|
93
94
|
# Find the device with the same name as the required device.
|
94
|
-
devices_with_same_type =
|
95
|
-
.select { |
|
95
|
+
devices_with_same_type = simctl_devices
|
96
|
+
.select { |simctl_device| simctl_device.device_type_identifier == required_device.device_type.identifier }
|
97
|
+
|
98
|
+
preferred_device_name = device_name_for_required_device(required_device)
|
99
|
+
|
100
|
+
# Prefer device with the same name that includes the runtime version.
|
101
|
+
matching_device = devices_with_same_type.detect { |simctl_device| simctl_device.name == preferred_device_name }
|
102
|
+
|
103
|
+
if can_rename_devices
|
104
|
+
# Otherwise, if rename is enabled, use the first device with the same type.
|
105
|
+
matching_device ||= devices_with_same_type.first
|
106
|
+
rename_device_if_needed(matching_device, preferred_device_name)
|
107
|
+
end
|
108
|
+
|
109
|
+
delete_duplicate_devices(devices_with_same_type, matching_device) if can_delete_duplicate_devices
|
110
|
+
|
111
|
+
matching_device
|
112
|
+
end
|
113
|
+
|
114
|
+
def rename_device_if_needed(matching_device, preferred_device_name)
|
115
|
+
return if matching_device.nil? || matching_device.name == preferred_device_name
|
96
116
|
|
97
|
-
|
98
|
-
|
117
|
+
UI.message("Renaming device #{matching_device.name} (udid: #{matching_device.udid}) to #{preferred_device_name}")
|
118
|
+
shell_helper.rename_device(udid: matching_device.udid, name: preferred_device_name)
|
119
|
+
matching_device.name = preferred_device_name
|
120
|
+
end
|
121
|
+
|
122
|
+
def delete_duplicate_devices(matching_devices, matching_device)
|
123
|
+
return if matching_device.nil?
|
124
|
+
|
125
|
+
matching_devices
|
126
|
+
.reject { |simctl_device| simctl_device.udid == matching_device.udid }
|
127
|
+
.each do |simctl_device|
|
128
|
+
UI.message("Deleting duplicate device #{simctl_device.name} (udid: #{simctl_device.udid})")
|
129
|
+
shell_helper.delete_device(udid: simctl_device.udid)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# Returns the device name for the required device.
|
134
|
+
#
|
135
|
+
# This name is used in the simctl device name.
|
136
|
+
def device_name_for_required_device(required_device)
|
137
|
+
case device_naming_style
|
138
|
+
when DeviceNamingStyle::SCAN, DeviceNamingStyle::RUN_TESTS
|
139
|
+
# scan modifies the device name by removing the runtime version when searching for a passed device name.
|
140
|
+
# E.g.:
|
141
|
+
# * given "iPhone 15 (17.0)" match will search for simulator named "iPhone 15" with the SDK version 17.0.
|
142
|
+
# * given "iPhone 15" match will search for simulator named "iPhone 15" with the default SDK version.
|
143
|
+
# So we need to name the device by the device type name for scan to find the correct device.
|
144
|
+
required_device.device_type.name
|
145
|
+
when DeviceNamingStyle::SNAPSHOT, DeviceNamingStyle::CAPTURE_IOS_SCREENSHOTS
|
146
|
+
# snapshot nither does not modify the device name when searching for a passed device name nor extracts the runtime version from the device name.
|
147
|
+
# E.g.:
|
148
|
+
# * given "iPhone 15 (17.0)" match will search for device named exactly "iPhone 15 (17.0)".
|
149
|
+
# * given "iPhone 15" match will search for device named exactly "iPhone 15".
|
150
|
+
# So we need to return the full device name for the required device for snapshot to find the correct device.
|
151
|
+
runtime_build = required_device.simctl_runtime.build_version
|
152
|
+
build_suffix = runtime_build.beta? ? "-#{runtime_build}" : ''
|
153
|
+
"#{required_device.device_type.name} (#{required_device.simctl_runtime.version}#{build_suffix})"
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
# Returns the device name for the required device.
|
158
|
+
#
|
159
|
+
# This name is used when passing the device name to the scan or snapshot.
|
160
|
+
def returning_device_name_for_required_device(required_device)
|
161
|
+
case device_naming_style
|
162
|
+
when DeviceNamingStyle::SCAN, DeviceNamingStyle::RUN_TESTS
|
163
|
+
# scan respects the runtime version in the devices list, so we need to return the full device name for the required device, otherwise the default SDK version will be used.
|
164
|
+
# E.g.:
|
165
|
+
# * given "iPhone 15 (17.0)" match will search for simulator named "iPhone 15" with the SDK version 17.0.
|
166
|
+
# * given "iPhone 15" match will search for simulator named "iPhone 15" with the default SDK version.
|
167
|
+
# So we need to return the device name and the required runtime version for scan to find the correct device.
|
168
|
+
"#{required_device.simctl_device.name} (#{required_device.required_runtime.product_version})"
|
169
|
+
when DeviceNamingStyle::SNAPSHOT, DeviceNamingStyle::CAPTURE_IOS_SCREENSHOTS
|
170
|
+
# snapshot does not modify the device name when searching for a passed device name nor extracts the runtime version from the device name.
|
171
|
+
# E.g.:
|
172
|
+
# * given "iPhone 15 (17.0)" match will search for device named exactly "iPhone 15 (17.0)".
|
173
|
+
# * given "iPhone 15" match will search for device named exactly "iPhone 15" .
|
174
|
+
# So we need to return the full device name for the required device for snapshot to find the correct device.
|
175
|
+
required_device.simctl_device.name
|
176
|
+
end
|
99
177
|
end
|
100
178
|
|
101
179
|
def create_missing_devices(required_devices)
|
102
180
|
find_runtime_and_device_for_required_devices(required_devices)
|
103
181
|
|
104
182
|
missing_devices = required_devices
|
105
|
-
.select { |required_device| required_device.
|
183
|
+
.select { |required_device| required_device.simctl_device.nil? }
|
106
184
|
|
107
185
|
if missing_devices.empty?
|
108
186
|
UI.message('All required devices are present. Skipping device creation...') if verbose
|
@@ -112,13 +190,13 @@ module Fastlane
|
|
112
190
|
UI.message('Creating missing devices')
|
113
191
|
missing_devices.each do |missing_device|
|
114
192
|
shell_helper.create_device(
|
115
|
-
missing_device
|
193
|
+
device_name_for_required_device(missing_device),
|
116
194
|
missing_device.device_type.identifier,
|
117
|
-
missing_device.
|
195
|
+
missing_device.simctl_runtime.identifier
|
118
196
|
)
|
119
197
|
end
|
120
198
|
|
121
|
-
shell_helper.
|
199
|
+
shell_helper.simctl_devices_for_runtimes(force: true)
|
122
200
|
|
123
201
|
find_runtime_and_device_for_required_devices(missing_devices)
|
124
202
|
end
|
@@ -126,8 +204,8 @@ module Fastlane
|
|
126
204
|
def find_runtime_and_device_for_required_devices(required_devices)
|
127
205
|
UI.message('Searching for matching available devices...')
|
128
206
|
required_devices.each do |required_device|
|
129
|
-
required_device.
|
130
|
-
required_device.
|
207
|
+
required_device.simctl_runtime = runtime_helper.simctl_runtime_for_required_device(required_device)
|
208
|
+
required_device.simctl_device = simctl_device_for_required_device(required_device)
|
131
209
|
end
|
132
210
|
end
|
133
211
|
|
@@ -141,17 +219,17 @@ module Fastlane
|
|
141
219
|
}.freeze
|
142
220
|
|
143
221
|
def required_device_for_device(device)
|
144
|
-
|
222
|
+
simctl_device_types = shell_helper.simctl_device_types
|
145
223
|
|
146
224
|
device_os_version = device[/ \(([\d.]*?)\)$/, 1]
|
147
225
|
device_name = device_os_version.nil? ? device : device.delete_suffix(" (#{device_os_version})").strip
|
148
226
|
|
149
|
-
device_type =
|
150
|
-
device_name ==
|
227
|
+
device_type = simctl_device_types.detect do |simctl_device_type|
|
228
|
+
device_name == simctl_device_type.name
|
151
229
|
end
|
152
230
|
|
153
231
|
unless device_type
|
154
|
-
UI.important("Device type not found for device #{device}. Available device types: #{
|
232
|
+
UI.important("Device type not found for device #{device}. Available device types: #{simctl_device_types.map(&:name).join(', ')}.")
|
155
233
|
return nil
|
156
234
|
end
|
157
235
|
|
@@ -170,8 +248,8 @@ module Fastlane
|
|
170
248
|
device_type:,
|
171
249
|
os_name:,
|
172
250
|
required_runtime: nil,
|
173
|
-
|
174
|
-
|
251
|
+
simctl_runtime: nil,
|
252
|
+
simctl_device: nil
|
175
253
|
)
|
176
254
|
|
177
255
|
required_device.required_runtime = runtime_helper.required_runtime_for_device(required_device, runtime_version)
|
data/lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/runtime_helper.rb
CHANGED
@@ -35,8 +35,8 @@ module Fastlane
|
|
35
35
|
shell_helper.delete_runtime(runtime.identifier)
|
36
36
|
end
|
37
37
|
|
38
|
-
shell_helper.
|
39
|
-
shell_helper.
|
38
|
+
shell_helper.simctl_runtimes(force: true)
|
39
|
+
shell_helper.simctl_devices_for_runtimes(force: true)
|
40
40
|
end
|
41
41
|
|
42
42
|
def install_missing_runtimes(required_devices)
|
@@ -53,10 +53,10 @@ module Fastlane
|
|
53
53
|
download_and_install_missing_runtime(missing_runtime)
|
54
54
|
end
|
55
55
|
|
56
|
-
# Update
|
56
|
+
# Update simctl_runtimes after installing the runtimes.
|
57
57
|
shell_helper.installed_runtimes_with_state
|
58
|
-
shell_helper.
|
59
|
-
shell_helper.
|
58
|
+
shell_helper.simctl_runtimes(force: true)
|
59
|
+
shell_helper.simctl_devices_for_runtimes(force: true)
|
60
60
|
|
61
61
|
# Check if missing runtimes are available after installing
|
62
62
|
missing_runtimes = missing_runtimes(missing_runtimes)
|
@@ -71,21 +71,21 @@ module Fastlane
|
|
71
71
|
def missing_runtimes(needed_runtimes)
|
72
72
|
needed_runtimes.select do |needed_runtime|
|
73
73
|
# Check if available runtimes contain the needed runtime.
|
74
|
-
|
74
|
+
simctl_runtime_matching_needed_runtime?(needed_runtime).nil?
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
78
|
-
def
|
79
|
-
matching_runtimes = shell_helper.
|
80
|
-
.select do |
|
81
|
-
next false if needed_runtime.os_name !=
|
78
|
+
def simctl_runtime_matching_needed_runtime?(needed_runtime)
|
79
|
+
matching_runtimes = shell_helper.simctl_runtimes
|
80
|
+
.select do |simctl_runtime|
|
81
|
+
next false if needed_runtime.os_name != simctl_runtime.platform
|
82
82
|
|
83
83
|
# If the product version is not equal, check if the first two segments are equal.
|
84
|
-
is_product_version_equal = if needed_runtime.product_version ==
|
84
|
+
is_product_version_equal = if needed_runtime.product_version == simctl_runtime.version
|
85
85
|
true
|
86
86
|
else
|
87
87
|
lhs_segments = needed_runtime.product_version.segments
|
88
|
-
rhs_segments =
|
88
|
+
rhs_segments = simctl_runtime.version.segments
|
89
89
|
if rhs_segments.size == 3
|
90
90
|
lhs_segments[0] == rhs_segments[0] && lhs_segments[1] == rhs_segments[1]
|
91
91
|
else
|
@@ -95,37 +95,37 @@ module Fastlane
|
|
95
95
|
next false unless is_product_version_equal
|
96
96
|
|
97
97
|
# If the product version is not equal, use the available runtime version.
|
98
|
-
needed_runtime.product_version =
|
98
|
+
needed_runtime.product_version = simctl_runtime.version
|
99
99
|
|
100
|
-
needed_runtime.product_build_version = [needed_runtime.product_build_version,
|
100
|
+
needed_runtime.product_build_version = [needed_runtime.product_build_version, simctl_runtime.build_version].compact.max
|
101
101
|
|
102
|
-
needed_runtime.product_build_version.almost_equal?(
|
102
|
+
needed_runtime.product_build_version.almost_equal?(simctl_runtime.build_version)
|
103
103
|
end
|
104
104
|
|
105
|
-
matching_runtimes.max_by { |
|
105
|
+
matching_runtimes.max_by { |simctl_runtime| [simctl_runtime.version, simctl_runtime.build_version] }
|
106
106
|
end
|
107
107
|
|
108
|
-
def
|
109
|
-
|
108
|
+
def simctl_runtime_for_required_device(required_device)
|
109
|
+
simctl_runtime = simctl_runtime_matching_needed_runtime?(required_device.required_runtime)
|
110
110
|
|
111
|
-
if
|
111
|
+
if simctl_runtime.nil?
|
112
112
|
UI.important("Runtime #{required_device.required_runtime.description} not found. Skipping simulator creation for #{required_device.description}...")
|
113
113
|
return nil
|
114
114
|
end
|
115
115
|
|
116
116
|
# Check if the runtime supports the device type.
|
117
|
-
if
|
117
|
+
if simctl_runtime.supported_device_types
|
118
118
|
.none? { |supported_device_type| supported_device_type.identifier == required_device.device_type.identifier }
|
119
|
-
UI.important("Device type #{required_device.device_type.name} is not supported by runtime #{
|
119
|
+
UI.important("Device type #{required_device.device_type.name} is not supported by runtime #{simctl_runtime.identifier}. Skipping simulator creation for #{required_device.description}...")
|
120
120
|
return nil
|
121
121
|
end
|
122
122
|
|
123
|
-
if
|
123
|
+
if simctl_runtime.nil?
|
124
124
|
UI.important("Runtime #{required_device.required_runtime.description} not found. Skipping simulator creation for #{required_device.description}...")
|
125
125
|
return nil
|
126
126
|
end
|
127
127
|
|
128
|
-
|
128
|
+
simctl_runtime
|
129
129
|
end
|
130
130
|
|
131
131
|
def download_and_install_missing_runtime(missing_runtime)
|
@@ -161,7 +161,12 @@ module Fastlane
|
|
161
161
|
# shipped with Xcode betas and use the same product version.
|
162
162
|
# E.g. Xcode 26.0 Beta 3 has iOS 26.0 (23A5287e) SDK, but
|
163
163
|
# xcodebuild downloads iphonesimulator_26.0_23A5287g.dmg as latest.
|
164
|
-
|
164
|
+
product_build_version = missing_runtime.product_build_version
|
165
|
+
if product_build_version
|
166
|
+
runtime_dmg_search_pattern += product_build_version.major.to_s
|
167
|
+
runtime_dmg_search_pattern += product_build_version.minor.to_s
|
168
|
+
runtime_dmg_search_pattern += product_build_version.patch.to_s
|
169
|
+
end
|
165
170
|
runtime_dmg_search_pattern += '*.dmg'
|
166
171
|
|
167
172
|
if verbose
|
@@ -184,7 +189,7 @@ module Fastlane
|
|
184
189
|
end
|
185
190
|
|
186
191
|
def required_runtime_for_device(required_device, runtime_version)
|
187
|
-
sdk =
|
192
|
+
sdk = max_xcodebuild_simulator_sdks[required_device.os_name]
|
188
193
|
|
189
194
|
# If the runtime version is the same as the SDK version, use the SDK build version.
|
190
195
|
# This will allow to use different runtimes for the same version but different Xcode beta versions.
|
@@ -205,10 +210,10 @@ module Fastlane
|
|
205
210
|
end
|
206
211
|
|
207
212
|
# Returns a hash where key is platform string and value is sdk version.
|
208
|
-
def
|
209
|
-
return @
|
213
|
+
def max_xcodebuild_simulator_sdks
|
214
|
+
return @max_xcodebuild_simulator_sdks unless @max_xcodebuild_simulator_sdks.nil?
|
210
215
|
|
211
|
-
@
|
216
|
+
@max_xcodebuild_simulator_sdks = shell_helper.xcodebuild_sdks
|
212
217
|
# Only simulators
|
213
218
|
.filter { |sdk| sdk.platform.include?('simulator') }
|
214
219
|
# Calculate max version for each product name
|
@@ -218,7 +223,7 @@ module Fastlane
|
|
218
223
|
sdk_versions[os_name] = sdk if stored_sdk.nil? || sdk.product_version > stored_sdk.product_version
|
219
224
|
end
|
220
225
|
|
221
|
-
@
|
226
|
+
@max_xcodebuild_simulator_sdks
|
222
227
|
end
|
223
228
|
end
|
224
229
|
end
|
data/lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/shell_helper.rb
CHANGED
@@ -53,20 +53,20 @@ module Fastlane
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
-
def
|
57
|
-
return @
|
56
|
+
def simctl_device_types(force: false)
|
57
|
+
return @simctl_device_types unless force || @simctl_device_types.nil?
|
58
58
|
|
59
59
|
UI.message('Fetching available device types...')
|
60
60
|
json = sh(command: 'xcrun simctl list --json --no-escape-slashes devicetypes')
|
61
61
|
|
62
|
-
@
|
62
|
+
@simctl_device_types = JSON
|
63
63
|
.parse(json, symbolize_names: true)[:devicetypes]
|
64
64
|
.map { |device_type| SimCTL::DeviceType.from_hash(device_type) }
|
65
65
|
|
66
|
-
@
|
66
|
+
@simctl_device_types
|
67
67
|
end
|
68
68
|
|
69
|
-
def delete_device(udid)
|
69
|
+
def delete_device(udid:)
|
70
70
|
UI.message("Deleting device #{udid}...")
|
71
71
|
sh(command: "xcrun simctl delete #{udid.shellescape}")
|
72
72
|
end
|
@@ -76,31 +76,31 @@ module Fastlane
|
|
76
76
|
sh(command: 'xcrun simctl delete unavailable')
|
77
77
|
end
|
78
78
|
|
79
|
-
def
|
80
|
-
return @
|
79
|
+
def simctl_devices_for_runtimes(force: false)
|
80
|
+
return @simctl_devices_for_runtimes unless force || @simctl_devices_for_runtimes.nil?
|
81
81
|
|
82
82
|
UI.message('Fetching available devices...')
|
83
83
|
json = sh(command: 'xcrun simctl list --json --no-escape-slashes devices')
|
84
84
|
|
85
|
-
@
|
85
|
+
@simctl_devices_for_runtimes = JSON
|
86
86
|
.parse(json, symbolize_names: true)[:devices]
|
87
87
|
.transform_values { |devices| devices.map { |device| SimCTL::Device.from_hash(device) } }
|
88
88
|
|
89
|
-
@
|
89
|
+
@simctl_devices_for_runtimes
|
90
90
|
end
|
91
91
|
|
92
|
-
def
|
93
|
-
return @
|
92
|
+
def simctl_runtimes(force: false)
|
93
|
+
return @simctl_runtimes unless force || @simctl_runtimes.nil?
|
94
94
|
|
95
95
|
UI.message('Fetching available runtimes...')
|
96
96
|
json = sh(command: 'xcrun simctl list --json --no-escape-slashes runtimes')
|
97
97
|
|
98
|
-
@
|
98
|
+
@simctl_runtimes = JSON
|
99
99
|
.parse(json, symbolize_names: true)[:runtimes]
|
100
100
|
.map { |runtime| SimCTL::Runtime.from_hash(runtime) }
|
101
101
|
.select(&:available?)
|
102
102
|
|
103
|
-
@
|
103
|
+
@simctl_runtimes
|
104
104
|
end
|
105
105
|
|
106
106
|
def installed_runtimes_with_state
|
@@ -112,17 +112,17 @@ module Fastlane
|
|
112
112
|
.map { |_, runtime| SimCTL::RuntimeWithState.from_hash(runtime) }
|
113
113
|
end
|
114
114
|
|
115
|
-
def
|
116
|
-
return @
|
115
|
+
def xcodebuild_sdks(force: false)
|
116
|
+
return @xcodebuild_sdks unless force || @xcodebuild_sdks.nil?
|
117
117
|
|
118
118
|
UI.message('Fetching available sdks...')
|
119
119
|
json = sh(command: 'xcrun xcodebuild -showsdks -json')
|
120
120
|
|
121
|
-
@
|
121
|
+
@xcodebuild_sdks = JSON
|
122
122
|
.parse(json, symbolize_names: true)
|
123
123
|
.map { |sdk| Xcodebuild::SDK.from_hash(sdk) }
|
124
124
|
|
125
|
-
@
|
125
|
+
@xcodebuild_sdks
|
126
126
|
end
|
127
127
|
|
128
128
|
def create_device(name, device_type_identifier, runtime_identifier)
|
@@ -130,6 +130,11 @@ module Fastlane
|
|
130
130
|
sh(command: "xcrun simctl create #{name.shellescape} #{device_type_identifier.shellescape} #{runtime_identifier.shellescape}")
|
131
131
|
end
|
132
132
|
|
133
|
+
def rename_device(udid:, name:)
|
134
|
+
UI.message("Renaming device with udid #{udid} to #{name}")
|
135
|
+
sh(command: "xcrun simctl rename #{udid.shellescape} #{name.shellescape}")
|
136
|
+
end
|
137
|
+
|
133
138
|
def delete_runtime(runtime_identifier)
|
134
139
|
UI.message("Deleting runtime #{runtime_identifier}...")
|
135
140
|
sh(command: "xcrun simctl runtime delete #{runtime_identifier.shellescape}")
|
@@ -150,8 +155,12 @@ module Fastlane
|
|
150
155
|
missing_runtime.os_name.shellescape
|
151
156
|
]
|
152
157
|
|
153
|
-
|
154
|
-
|
158
|
+
is_beta = missing_runtime.product_build_version.nil? ? false : missing_runtime.product_build_version.beta?
|
159
|
+
|
160
|
+
unless is_beta
|
161
|
+
command << '-buildVersion'
|
162
|
+
command << missing_runtime.product_version.to_s.shellescape
|
163
|
+
end
|
155
164
|
|
156
165
|
sh(command: command.join(' '), print_command: true, print_command_output: true)
|
157
166
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fastlane-plugin-create_simulator_devices
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vitalii Budnik
|
@@ -22,6 +22,7 @@ files:
|
|
22
22
|
- lib/fastlane/plugin/create_simulator_devices/actions/create_simulator_devices_action.rb
|
23
23
|
- lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/models.rb
|
24
24
|
- lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/models/apple_build_version.rb
|
25
|
+
- lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/models/device_naming_style.rb
|
25
26
|
- lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/models/required_device.rb
|
26
27
|
- lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/models/required_runtime.rb
|
27
28
|
- lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/models/simctl/device.rb
|