fastlane-plugin-create_simulator_devices 0.0.4 → 0.0.6
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 +14 -4
- data/lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/models/apple_build_version.rb +6 -1
- data/lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/runner.rb +35 -13
- data/lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/runtime_helper.rb +29 -15
- data/lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/shell_helper.rb +15 -19
- data/lib/fastlane/plugin/create_simulator_devices/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a77a05dbf6d484a920978945f9e5941b67ec86f549dfeaa7d9add45d1e778174
|
4
|
+
data.tar.gz: '00961903381d91b9170c63bc51ebb2bbea55111511856eea951c854834d77b37'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: be42b6fb3d60074b6b24c738c53cba15516c599b7f7ac80dce53a0a8dc7e845c2855de0ed9175487daae482c237af90a0b1d93954a4eded31387e4ea0359ed39
|
7
|
+
data.tar.gz: c0c89fe57b0992f5d2b1dbae8821e64f3719836500c01c7eaf5442c6bf5b5feba4c99ce59ef4d0b89b9950d2c44fd25a0e24d2db33f29f86e3de22dc2044558c
|
data/lib/fastlane/plugin/create_simulator_devices/actions/create_simulator_devices_action.rb
CHANGED
@@ -25,7 +25,7 @@ module Fastlane
|
|
25
25
|
required_devices = params[:devices]
|
26
26
|
UI.user_error!('No devices specified') if required_devices.nil? || required_devices.empty?
|
27
27
|
|
28
|
-
shell_helper = CreateSimulatorDevices::ShellHelper.new(
|
28
|
+
shell_helper = CreateSimulatorDevices::ShellHelper.new(print_command: params[:print_command], print_command_output: params[:print_command_output], action_context: self)
|
29
29
|
runtime_helper = CreateSimulatorDevices::RuntimeHelper.new(cache_dir: params[:cache_dir], shell_helper:, verbose:)
|
30
30
|
|
31
31
|
runner = CreateSimulatorDevices::Runner.new(
|
@@ -69,16 +69,26 @@ module Fastlane
|
|
69
69
|
default_value: 'iPhone 16'),
|
70
70
|
::FastlaneCore::ConfigItem.new(key: :cache_dir,
|
71
71
|
description: 'The directory to cache the simulator runtimes',
|
72
|
-
|
72
|
+
type: String,
|
73
73
|
optional: true,
|
74
74
|
default_value: "#{Dir.home}/.cache/create_simulator_devices"),
|
75
75
|
::FastlaneCore::ConfigItem.new(key: :verbose,
|
76
76
|
env_name: 'VERBOSE',
|
77
77
|
description: 'Verbose output',
|
78
|
-
|
78
|
+
type: Boolean,
|
79
79
|
optional: true,
|
80
80
|
default_value: ::FastlaneCore::Globals.verbose?,
|
81
|
-
default_value_dynamic: true)
|
81
|
+
default_value_dynamic: true),
|
82
|
+
::FastlaneCore::ConfigItem.new(key: :print_command,
|
83
|
+
description: 'Print xcrun simctl commands',
|
84
|
+
type: Boolean,
|
85
|
+
optional: true,
|
86
|
+
default_value: false),
|
87
|
+
::FastlaneCore::ConfigItem.new(key: :print_command_output,
|
88
|
+
description: 'Print xcrun simctl commands output',
|
89
|
+
type: Boolean,
|
90
|
+
optional: true,
|
91
|
+
default_value: false)
|
82
92
|
]
|
83
93
|
end
|
84
94
|
|
@@ -58,7 +58,12 @@ module Fastlane
|
|
58
58
|
|
59
59
|
return self == other unless lhs_is_beta && rhs_is_beta && lhs_build_version.length == rhs_build_version.length
|
60
60
|
|
61
|
-
|
61
|
+
# Take only leading chars up to the first letter included e.g. 22C146 -> 22C
|
62
|
+
lhs_build_version.minor_version == rhs_build_version.minor_version
|
63
|
+
end
|
64
|
+
|
65
|
+
def minor_version
|
66
|
+
AppleBuildVersion.new(@build_version.match(/^[0-9]+[A-Z]+/)[0])
|
62
67
|
end
|
63
68
|
|
64
69
|
def <(other)
|
data/lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/runner.rb
CHANGED
@@ -18,6 +18,8 @@ module Fastlane
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def run(devices)
|
21
|
+
UI.message("Simulator devices to create: #{devices.join(', ')}")
|
22
|
+
|
21
23
|
shell_helper.stop_core_simulator_services
|
22
24
|
|
23
25
|
# Delete unusable runtimes and unavailable devices.
|
@@ -29,6 +31,11 @@ module Fastlane
|
|
29
31
|
.filter_map { |device| required_device_for_device(device) }
|
30
32
|
.uniq { |required_device| [required_device.device_type.name, required_device.required_runtime.product_version] }
|
31
33
|
|
34
|
+
if verbose
|
35
|
+
UI.message('Unique required devices:')
|
36
|
+
UI.message(" #{required_devices.map(&:description).join("\n ")}")
|
37
|
+
end
|
38
|
+
|
32
39
|
# Install missing runtimes if needed.
|
33
40
|
runtime_helper.install_missing_runtimes(required_devices)
|
34
41
|
|
@@ -39,12 +46,7 @@ module Fastlane
|
|
39
46
|
matched_devices = required_devices
|
40
47
|
.reject { |required_device| required_device.available_device.nil? }
|
41
48
|
|
42
|
-
|
43
|
-
UI.message('Matched devices:')
|
44
|
-
matched_devices.each do |matched_device|
|
45
|
-
UI.message("\n\t#{matched_device.description}: #{matched_device.available_device.description}")
|
46
|
-
end
|
47
|
-
end
|
49
|
+
log_matched_devices
|
48
50
|
|
49
51
|
matched_devices.map!(&:description)
|
50
52
|
|
@@ -53,6 +55,18 @@ module Fastlane
|
|
53
55
|
matched_devices
|
54
56
|
end
|
55
57
|
|
58
|
+
def log_matched_devices
|
59
|
+
UI.message('Matched devices:')
|
60
|
+
matched_devices.each do |matched_device|
|
61
|
+
device_info = ''
|
62
|
+
if verbose
|
63
|
+
device_info = shell_helper.device_info_by_udid(matched_device.available_device.udid)
|
64
|
+
device_info = "\n#{device_info}"
|
65
|
+
end
|
66
|
+
UI.message(" #{matched_device.description}: #{matched_device.available_device.description}#{device_info}")
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
56
70
|
def delete_unavailable_devices
|
57
71
|
return unless shell_helper.available_devices_for_runtimes.values.flatten.any?(&:available?)
|
58
72
|
|
@@ -68,7 +82,12 @@ module Fastlane
|
|
68
82
|
|
69
83
|
return [] if available_devices.nil?
|
70
84
|
|
71
|
-
|
85
|
+
# Find the device with the same name as the required device.
|
86
|
+
devices_with_same_type = available_devices
|
87
|
+
.select { |available_device| available_device.device_type_identifier == required_device.device_type.identifier }
|
88
|
+
|
89
|
+
devices_with_same_type
|
90
|
+
.detect { |available_device| available_device.name == required_device.device_type.name }
|
72
91
|
end
|
73
92
|
|
74
93
|
def create_missing_devices(required_devices)
|
@@ -77,12 +96,15 @@ module Fastlane
|
|
77
96
|
missing_devices = required_devices
|
78
97
|
.select { |required_device| required_device.available_device.nil? }
|
79
98
|
|
80
|
-
|
99
|
+
if missing_devices.empty?
|
100
|
+
UI.message('All required devices are present. Skipping device creation...') if verbose
|
101
|
+
return
|
102
|
+
end
|
81
103
|
|
82
104
|
UI.message('Creating missing devices')
|
83
105
|
missing_devices.each do |missing_device|
|
84
106
|
shell_helper.create_device(
|
85
|
-
missing_device.
|
107
|
+
missing_device.device_type.name,
|
86
108
|
missing_device.device_type.identifier,
|
87
109
|
missing_device.available_runtime.identifier
|
88
110
|
)
|
@@ -113,9 +135,11 @@ module Fastlane
|
|
113
135
|
def required_device_for_device(device)
|
114
136
|
available_device_types = shell_helper.available_device_types
|
115
137
|
|
138
|
+
device_os_version = device[/ \(([\d.]*?)\)$/, 1]
|
139
|
+
device_name = device.delete_suffix(" (#{device_os_version})").strip unless device_os_version.nil?
|
140
|
+
|
116
141
|
device_type = available_device_types.detect do |available_device_type|
|
117
|
-
|
118
|
-
"#{device} ".start_with?("#{available_device_type.name} ")
|
142
|
+
device_name == available_device_type.name
|
119
143
|
end
|
120
144
|
|
121
145
|
unless device_type
|
@@ -126,8 +150,6 @@ module Fastlane
|
|
126
150
|
product_family = device_type.product_family
|
127
151
|
|
128
152
|
os_name = PRODUCT_FAMILY_TO_OS_NAME[product_family]
|
129
|
-
device_os_version = device.delete_prefix(device_type.name).strip
|
130
|
-
device_os_version = device_os_version[/\(([\d.]*?)\)/, 1]
|
131
153
|
|
132
154
|
runtime_version = nil
|
133
155
|
unless device_os_version.nil? || device_os_version.empty?
|
data/lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/runtime_helper.rb
CHANGED
@@ -43,7 +43,10 @@ module Fastlane
|
|
43
43
|
|
44
44
|
missing_runtimes = missing_runtimes(needed_runtimes)
|
45
45
|
|
46
|
-
|
46
|
+
if missing_runtimes.empty?
|
47
|
+
UI.message('All required runtimes are present. Skipping runtime installation...') if verbose
|
48
|
+
return
|
49
|
+
end
|
47
50
|
|
48
51
|
missing_runtimes.each do |missing_runtime|
|
49
52
|
download_and_install_missing_runtime(missing_runtime)
|
@@ -74,8 +77,24 @@ module Fastlane
|
|
74
77
|
def available_runtime_matching_needed_runtime?(needed_runtime)
|
75
78
|
matching_runtimes = shell_helper.available_runtimes
|
76
79
|
.select do |available_runtime|
|
77
|
-
next false if needed_runtime.os_name != available_runtime.platform
|
78
|
-
|
80
|
+
next false if needed_runtime.os_name != available_runtime.platform
|
81
|
+
|
82
|
+
# If the product version is not equal, check if the first two segments are equal.
|
83
|
+
is_product_version_equal = if needed_runtime.product_version == available_runtime.version
|
84
|
+
true
|
85
|
+
else
|
86
|
+
lhs_segments = needed_runtime.product_version.segments
|
87
|
+
rhs_segments = available_runtime.version.segments
|
88
|
+
if rhs_segments.size == 3
|
89
|
+
lhs_segments[0] == rhs_segments[0] && lhs_segments[1] == rhs_segments[1]
|
90
|
+
else
|
91
|
+
false
|
92
|
+
end
|
93
|
+
end
|
94
|
+
next false unless is_product_version_equal
|
95
|
+
|
96
|
+
# If the product version is not equal, use the available runtime version.
|
97
|
+
needed_runtime.product_version = available_runtime.version
|
79
98
|
|
80
99
|
needed_runtime.product_build_version = [needed_runtime.product_build_version, available_runtime.build_version].compact.max
|
81
100
|
|
@@ -108,17 +127,6 @@ module Fastlane
|
|
108
127
|
available_runtime
|
109
128
|
end
|
110
129
|
|
111
|
-
def install_missing_runtime(missing_runtime, cached_runtime_file)
|
112
|
-
runtime_name = missing_runtime.runtime_name
|
113
|
-
|
114
|
-
if missing_runtime.product_build_version.nil?
|
115
|
-
UI.important("Failed to find runtime build version for #{runtime_name}")
|
116
|
-
return
|
117
|
-
end
|
118
|
-
|
119
|
-
shell_helper.import_runtime(cached_runtime_file, runtime_name)
|
120
|
-
end
|
121
|
-
|
122
130
|
def download_and_install_missing_runtime(missing_runtime)
|
123
131
|
UI.message("Attempting to install #{missing_runtime.runtime_name} runtime.")
|
124
132
|
|
@@ -152,9 +160,15 @@ module Fastlane
|
|
152
160
|
# shipped with Xcode betas and use the same product version.
|
153
161
|
# E.g. Xcode 26.0 Beta 3 has iOS 26.0 (23A5287e) SDK, but
|
154
162
|
# xcodebuild downloads iphonesimulator_26.0_23A5287g.dmg as latest.
|
155
|
-
runtime_dmg_search_pattern += missing_runtime.product_build_version.to_s
|
163
|
+
runtime_dmg_search_pattern += missing_runtime.product_build_version.minor_version.to_s if missing_runtime.product_build_version
|
156
164
|
runtime_dmg_search_pattern += '*.dmg'
|
157
165
|
|
166
|
+
if verbose
|
167
|
+
UI.message("Searching for #{missing_runtime.runtime_name} runtime image in #{cache_dir} with pattern: #{runtime_dmg_search_pattern}")
|
168
|
+
UI.message("Available dmg files: #{Dir.glob("#{cache_dir}/*.dmg")}")
|
169
|
+
UI.message("Available files with pattern: #{Dir.glob(runtime_dmg_search_pattern)}")
|
170
|
+
end
|
171
|
+
|
158
172
|
runtime_file = Dir
|
159
173
|
.glob(runtime_dmg_search_pattern)
|
160
174
|
.max_by { |filename| runtime_build_version_for_filename(filename) }
|
data/lib/fastlane/plugin/create_simulator_devices/helpers/create_simulator_devices/shell_helper.rb
CHANGED
@@ -10,16 +10,17 @@ module Fastlane
|
|
10
10
|
UI = ::Fastlane::UI unless defined?(UI)
|
11
11
|
|
12
12
|
# Proprty verbose
|
13
|
-
attr_accessor :
|
13
|
+
attr_accessor :print_command, :print_command_output, :action_context
|
14
14
|
|
15
|
-
def initialize(
|
16
|
-
self.
|
15
|
+
def initialize(print_command: false, print_command_output: false, action_context: nil)
|
16
|
+
self.print_command = print_command
|
17
|
+
self.print_command_output = print_command_output
|
17
18
|
self.action_context = action_context
|
18
19
|
end
|
19
20
|
|
20
|
-
def sh(command:, print_command:
|
21
|
+
def sh(command:, print_command: self.print_command, print_command_output: self.print_command_output)
|
21
22
|
if action_context
|
22
|
-
action_context.sh(command, print_command
|
23
|
+
action_context.sh(command, print_command: print_command, print_command_output: print_command_output)
|
23
24
|
else
|
24
25
|
# Fallback for testing or direct usage
|
25
26
|
require 'open3'
|
@@ -148,11 +149,8 @@ module Fastlane
|
|
148
149
|
missing_runtime.os_name.shellescape
|
149
150
|
]
|
150
151
|
|
151
|
-
|
152
|
-
|
153
|
-
# Prefer the build version if available, otherwise use the product version.
|
154
|
-
command << (missing_runtime.product_build_version || missing_runtime.product_version.to_s).shellescape
|
155
|
-
end
|
152
|
+
command << '-buildVersion'
|
153
|
+
command << missing_runtime.product_version.to_s.shellescape
|
156
154
|
|
157
155
|
sh(command: command.join(' '), print_command: true, print_command_output: true)
|
158
156
|
end
|
@@ -167,15 +165,13 @@ module Fastlane
|
|
167
165
|
end
|
168
166
|
end
|
169
167
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
# end
|
178
|
-
# end
|
168
|
+
def device_info_by_udid(udid)
|
169
|
+
sh(
|
170
|
+
command: "xcrun simctl list devices --json | jq '.devices | to_entries[].value[] | select(.udid==\"#{udid.shellescape}\")'",
|
171
|
+
print_command: false,
|
172
|
+
print_command_output: false
|
173
|
+
)
|
174
|
+
end
|
179
175
|
end
|
180
176
|
end
|
181
177
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
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.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vitalii Budnik
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-08-29 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email: developers@setapp.com
|