run_loop 1.5.1 → 1.5.2
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/run_loop.rb +2 -0
- data/lib/run_loop/app.rb +5 -0
- data/lib/run_loop/cli/instruments.rb +0 -1
- data/lib/run_loop/cli/simctl.rb +98 -13
- data/lib/run_loop/core.rb +194 -110
- data/lib/run_loop/device.rb +218 -2
- data/lib/run_loop/directory.rb +22 -5
- data/lib/run_loop/environment.rb +10 -0
- data/lib/run_loop/instruments.rb +55 -72
- data/lib/run_loop/life_cycle/core_simulator.rb +544 -0
- data/lib/run_loop/logging.rb +68 -0
- data/lib/run_loop/simctl/bridge.rb +15 -2
- data/lib/run_loop/version.rb +1 -1
- data/lib/run_loop/xcode.rb +15 -0
- data/lib/run_loop/xcrun.rb +75 -0
- data/lib/run_loop/xctools.rb +19 -0
- metadata +5 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2277694b8f2dd62516bcc3107dc59e8d227e952b
|
4
|
+
data.tar.gz: 77b5fa24065db03d3379d9e997251ca564ad9017
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 28529f12e82152e1b618a3ff6011db975d2ac84fb91668c64f95de840d69c8bddc09b94c4fe9e770b7cecd3b3cdaea418a154f6f8f13548231f3635b6f9346be
|
7
|
+
data.tar.gz: 6ccce42c7d166a850ecb10e2c558cc1930c73f9da097f03f78d2a32e718e3c70b440761d847233de17a1ded3d1a314414789c6fc98408482d01027afd4e0709f
|
data/lib/run_loop.rb
CHANGED
@@ -2,6 +2,7 @@ require 'run_loop/regex'
|
|
2
2
|
require 'run_loop/directory'
|
3
3
|
require 'run_loop/environment'
|
4
4
|
require 'run_loop/logging'
|
5
|
+
require 'run_loop/xcrun'
|
5
6
|
require 'run_loop/xcode'
|
6
7
|
require 'run_loop/l10n'
|
7
8
|
require 'run_loop/process_terminator'
|
@@ -23,6 +24,7 @@ require 'run_loop/cache/cache'
|
|
23
24
|
require 'run_loop/host_cache'
|
24
25
|
require 'run_loop/patches/awesome_print'
|
25
26
|
require 'run_loop/patches/retriable'
|
27
|
+
require 'run_loop/life_cycle/core_simulator'
|
26
28
|
require 'run_loop/simctl/bridge'
|
27
29
|
require 'run_loop/simctl/plists'
|
28
30
|
|
data/lib/run_loop/app.rb
CHANGED
data/lib/run_loop/cli/simctl.rb
CHANGED
@@ -37,7 +37,7 @@ module RunLoop
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
-
desc '
|
40
|
+
desc 'doctor', 'EXPERIMENTAL: Prepare the CoreSimulator environment for testing'
|
41
41
|
|
42
42
|
method_option 'debug',
|
43
43
|
:desc => 'Enable debug logging.',
|
@@ -46,23 +46,70 @@ module RunLoop
|
|
46
46
|
:default => false,
|
47
47
|
:type => :boolean
|
48
48
|
|
49
|
-
|
49
|
+
method_option 'device',
|
50
|
+
:desc => 'The simulator UDID or name.',
|
51
|
+
:aliases => '-d',
|
52
|
+
:required => false,
|
53
|
+
:type => :string
|
54
|
+
|
55
|
+
def doctor
|
56
|
+
debug = options[:debug]
|
57
|
+
device = options[:device]
|
58
|
+
|
59
|
+
if device
|
60
|
+
device = expect_device(options)
|
61
|
+
if debug
|
62
|
+
RunLoop::Environment.with_debugging do
|
63
|
+
launch_simulator(device)
|
64
|
+
end
|
65
|
+
else
|
66
|
+
launch_simulator(device)
|
67
|
+
end
|
68
|
+
else
|
69
|
+
if debug
|
70
|
+
RunLoop::Environment.with_debugging do
|
71
|
+
launch_each_simulator
|
72
|
+
end
|
73
|
+
else
|
74
|
+
launch_each_simulator
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
no_commands do
|
80
|
+
def launch_each_simulator
|
81
|
+
sim_control = RunLoop::SimControl.new
|
82
|
+
sim_control.simulators.each do |simulator|
|
83
|
+
launch_simulator(simulator, sim_control)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def launch_simulator(simulator, sim_control=RunLoop::SimControl.new)
|
88
|
+
core_sim = RunLoop::LifeCycle::CoreSimulator.new(nil,
|
89
|
+
simulator,
|
90
|
+
sim_control)
|
91
|
+
core_sim.launch_simulator
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
desc 'manage-processes', 'Manage CoreSimulator processes by quiting stale processes'
|
96
|
+
|
97
|
+
method_option 'debug',
|
98
|
+
:desc => 'Enable debug logging.',
|
99
|
+
:aliases => '-v',
|
100
|
+
:required => false,
|
101
|
+
:default => false,
|
102
|
+
:type => :boolean
|
103
|
+
|
104
|
+
def manage_processes
|
50
105
|
debug = options[:debug]
|
51
106
|
original_value = ENV['DEBUG']
|
52
107
|
|
53
108
|
ENV['DEBUG'] = '1' if debug
|
54
109
|
|
55
|
-
RunLoop::SimControl.terminate_all_sims
|
56
|
-
|
57
110
|
begin
|
58
|
-
|
59
|
-
|
60
|
-
if debug && pids.empty?
|
61
|
-
puts 'There are no CoreSimulatorServices processes running'
|
62
|
-
end
|
63
|
-
pids.each do |pid|
|
64
|
-
RunLoop::ProcessTerminator.new(pid, 'KILL', process_name).kill_process
|
65
|
-
end
|
111
|
+
RunLoop::SimControl.terminate_all_sims
|
112
|
+
terminate_core_simulator_processes
|
66
113
|
ensure
|
67
114
|
ENV['DEBUG'] = original_value if debug
|
68
115
|
end
|
@@ -78,6 +125,33 @@ module RunLoop
|
|
78
125
|
device.state == 'Booted'
|
79
126
|
end
|
80
127
|
end
|
128
|
+
|
129
|
+
# TODO this is duplicated code; extract!
|
130
|
+
# https://github.com/calabash/run_loop/issues/225
|
131
|
+
def terminate_core_simulator_processes
|
132
|
+
to_manage = RunLoop::LifeCycle::CoreSimulator::MANAGED_PROCESSES
|
133
|
+
to_manage << ['com.apple.CoreSimulator.CoreSimulatorService', false]
|
134
|
+
|
135
|
+
to_manage.each do |pair|
|
136
|
+
name = pair[0]
|
137
|
+
send_term = pair[1]
|
138
|
+
pids = RunLoop::ProcessWaiter.new(name).pids
|
139
|
+
pids.each do |pid|
|
140
|
+
|
141
|
+
if send_term
|
142
|
+
term = RunLoop::ProcessTerminator.new(pid, 'TERM', name)
|
143
|
+
killed = term.kill_process
|
144
|
+
else
|
145
|
+
killed = false
|
146
|
+
end
|
147
|
+
|
148
|
+
unless killed
|
149
|
+
term = RunLoop::ProcessTerminator.new(pid, 'KILL', name)
|
150
|
+
term.kill_process
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
81
155
|
end
|
82
156
|
|
83
157
|
desc 'install --app [OPTIONS]', 'Installs an app on a device'
|
@@ -89,7 +163,7 @@ module RunLoop
|
|
89
163
|
:type => :string
|
90
164
|
|
91
165
|
method_option 'device',
|
92
|
-
:desc => 'The
|
166
|
+
:desc => 'The simulator UDID or name.',
|
93
167
|
:aliases => '-d',
|
94
168
|
:required => false,
|
95
169
|
:type => :string
|
@@ -122,6 +196,17 @@ module RunLoop
|
|
122
196
|
|
123
197
|
bridge = RunLoop::Simctl::Bridge.new(device, app.path)
|
124
198
|
|
199
|
+
xcode = bridge.sim_control.xcode
|
200
|
+
if xcode.version >= RunLoop::Version.new('7.0')
|
201
|
+
puts "ERROR: Xcode #{xcode.version.to_s} detected."
|
202
|
+
puts "ERROR: Apple's simctl install/uninstall is broken for this version of Xcode."
|
203
|
+
puts "ERROR: See the following links for details:"
|
204
|
+
puts "ERROR: https://forums.developer.apple.com/message/51922"
|
205
|
+
puts "ERROR: https://github.com/calabash/run_loop/issues/235"
|
206
|
+
puts "ERROR: exiting 1"
|
207
|
+
exit 1
|
208
|
+
end
|
209
|
+
|
125
210
|
force_reinstall = options[:force]
|
126
211
|
|
127
212
|
before = Time.now
|
data/lib/run_loop/core.rb
CHANGED
@@ -68,6 +68,8 @@ module RunLoop
|
|
68
68
|
nil
|
69
69
|
end
|
70
70
|
|
71
|
+
# @deprecated 1.5.2 No public replacement.
|
72
|
+
#
|
71
73
|
# Raise an error if the application binary is not compatible with the
|
72
74
|
# target simulator.
|
73
75
|
#
|
@@ -85,6 +87,7 @@ module RunLoop
|
|
85
87
|
# @raise [RunLoop::IncompatibleArchitecture] Raises an error if the
|
86
88
|
# application binary is not compatible with the target simulator.
|
87
89
|
def self.expect_compatible_simulator_architecture(launch_options, sim_control)
|
90
|
+
RunLoop.deprecated('1.5.2', 'No public replacement.')
|
88
91
|
logger = launch_options[:logger]
|
89
92
|
if sim_control.xcode_version_gte_6?
|
90
93
|
sim_identifier = launch_options[:udid]
|
@@ -107,6 +110,30 @@ module RunLoop
|
|
107
110
|
end
|
108
111
|
end
|
109
112
|
|
113
|
+
# Raise an error if the application binary is not compatible with the
|
114
|
+
# target simulator.
|
115
|
+
#
|
116
|
+
# @note This method is implemented for CoreSimulator environments only;
|
117
|
+
# for Xcode < 6.0 this method does nothing.
|
118
|
+
#
|
119
|
+
# @param [RunLoop::Device] device The device to install on.
|
120
|
+
# @param [RunLoop::App] app The app to install.
|
121
|
+
# @param [RunLoop::Xcode] xcode The active Xcode.
|
122
|
+
#
|
123
|
+
# @raise [RunLoop::IncompatibleArchitecture] Raises an error if the
|
124
|
+
# application binary is not compatible with the target simulator.
|
125
|
+
def self.expect_simulator_compatible_arch(device, app, xcode)
|
126
|
+
if !xcode.version_gte_6?
|
127
|
+
RunLoop.log_warn("Checking for compatible arches is only available in CoreSimulator environments")
|
128
|
+
return
|
129
|
+
end
|
130
|
+
|
131
|
+
lipo = RunLoop::Lipo.new(app.path)
|
132
|
+
lipo.expect_compatible_arch(device)
|
133
|
+
|
134
|
+
RunLoop.log_debug("Simulator instruction set '#{device.instruction_set}' is compatible with '#{lipo.info}'")
|
135
|
+
end
|
136
|
+
|
110
137
|
# Prepares the simulator for running.
|
111
138
|
#
|
112
139
|
# 1. enabling accessibility and software keyboard
|
@@ -135,17 +162,37 @@ module RunLoop
|
|
135
162
|
|
136
163
|
# CoreSimulator
|
137
164
|
|
165
|
+
app_bundle_path = launch_options[:bundle_dir_or_bundle_id]
|
166
|
+
app = RunLoop::App.new(app_bundle_path)
|
167
|
+
|
168
|
+
unless app.valid?
|
169
|
+
if !File.exist?(app.path)
|
170
|
+
message = "App '#{app_bundle_path}' does not exist."
|
171
|
+
else
|
172
|
+
message = "App '#{app_bundle_path}' is not a valid .app bundle"
|
173
|
+
end
|
174
|
+
raise RuntimeError, message
|
175
|
+
end
|
176
|
+
|
138
177
|
udid = launch_options[:udid]
|
139
178
|
xcode = sim_control.xcode
|
140
179
|
|
141
|
-
device = sim_control.simulators.
|
180
|
+
device = sim_control.simulators.find do |sim|
|
142
181
|
sim.udid == udid || sim.instruments_identifier(xcode) == udid
|
143
182
|
end
|
144
183
|
|
145
184
|
if device.nil?
|
146
|
-
raise
|
185
|
+
raise RuntimeError,
|
186
|
+
"Could not find simulator with name or UDID that matches: '#{udid}'"
|
147
187
|
end
|
148
188
|
|
189
|
+
# Validate the architecture.
|
190
|
+
self.expect_simulator_compatible_arch(device, app, xcode)
|
191
|
+
|
192
|
+
bridge = RunLoop::LifeCycle::CoreSimulator.new(app, device, sim_control)
|
193
|
+
|
194
|
+
bridge.ensure_app_same
|
195
|
+
|
149
196
|
# Will quit the simulator if it is running.
|
150
197
|
# @todo fix accessibility_enabled? so we don't have to quit the sim
|
151
198
|
# SimControl#accessibility_enabled? is always false during Core#prepare_simulator
|
@@ -158,11 +205,10 @@ module RunLoop
|
|
158
205
|
# https://github.com/calabash/run_loop/issues/167
|
159
206
|
sim_control.ensure_software_keyboard(device)
|
160
207
|
|
208
|
+
|
161
209
|
# Xcode 6.3 instruments cannot launch an app that is already installed on
|
162
210
|
# iOS 8.3 Simulators. See: https://github.com/calabash/calabash-ios/issues/744
|
163
211
|
if sim_control.xcode.version_gte_63?
|
164
|
-
app_bundle_path = launch_options[:bundle_dir_or_bundle_id]
|
165
|
-
bridge = RunLoop::Simctl::Bridge.new(device, app_bundle_path)
|
166
212
|
|
167
213
|
if bridge.app_is_installed? && !sim_control.sim_is_running?
|
168
214
|
bridge.launch_simulator
|
@@ -259,7 +305,6 @@ Please update your sources to pass an instance of RunLoop::Xcode))
|
|
259
305
|
merged_options = options.merge(discovered_options)
|
260
306
|
|
261
307
|
if self.simulator_target?(merged_options)
|
262
|
-
self.expect_compatible_simulator_architecture(merged_options, sim_control)
|
263
308
|
self.prepare_simulator(merged_options, sim_control)
|
264
309
|
end
|
265
310
|
|
@@ -286,34 +331,55 @@ Please update your sources to pass an instance of RunLoop::Xcode))
|
|
286
331
|
|
287
332
|
uia_timeout = options[:uia_timeout] || RunLoop::Environment.uia_timeout || 10
|
288
333
|
|
289
|
-
|
290
|
-
|
334
|
+
RunLoop::Logging.log_debug(logger, "Preparation took #{Time.now-before} seconds")
|
335
|
+
|
336
|
+
before_instruments_launch = Time.now
|
337
|
+
|
338
|
+
fifo_retry_on = [RunLoop::Fifo::NoReaderConfiguredError,
|
339
|
+
RunLoop::Fifo::WriteTimedOut]
|
291
340
|
|
292
|
-
before = Time.now
|
293
341
|
begin
|
294
342
|
|
295
343
|
if options[:validate_channel]
|
296
344
|
options[:validate_channel].call(run_loop, 0, uia_timeout)
|
297
345
|
else
|
346
|
+
|
298
347
|
cmd = "UIALogger.logMessage('Listening for run loop commands')"
|
348
|
+
|
299
349
|
begin
|
350
|
+
|
300
351
|
fifo_timeout = options[:fifo_timeout] || 30
|
301
352
|
RunLoop::Fifo.write(repl_path, "0:#{cmd}", timeout: fifo_timeout)
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
353
|
+
|
354
|
+
rescue *fifo_retry_on => e
|
355
|
+
|
356
|
+
message = "Error while writing to fifo. #{e}"
|
357
|
+
RunLoop::Logging.log_debug(logger, message)
|
358
|
+
raise RunLoop::TimeoutError.new(message)
|
359
|
+
|
306
360
|
end
|
361
|
+
|
307
362
|
Timeout::timeout(timeout, RunLoop::TimeoutError) do
|
308
363
|
read_response(run_loop, 0, uia_timeout)
|
309
364
|
end
|
365
|
+
|
310
366
|
end
|
311
367
|
rescue RunLoop::TimeoutError => e
|
312
368
|
RunLoop::Logging.log_debug(logger, "Failed to launch. #{e}: #{e && e.message}")
|
313
|
-
|
369
|
+
|
370
|
+
message = %Q(
|
371
|
+
|
372
|
+
"Timed out waiting for UIAutomation run-loop #{e}.
|
373
|
+
|
374
|
+
Logfile: #{log_file}
|
375
|
+
|
376
|
+
#{File.read(log_file)}
|
377
|
+
|
378
|
+
)
|
379
|
+
raise RunLoop::TimeoutError, message
|
314
380
|
end
|
315
381
|
|
316
|
-
RunLoop::Logging.log_debug(logger, "Launching took #{Time.now-
|
382
|
+
RunLoop::Logging.log_debug(logger, "Launching took #{Time.now-before_instruments_launch} seconds")
|
317
383
|
|
318
384
|
dylib_path = self.dylib_path_from_options(merged_options)
|
319
385
|
|
@@ -324,6 +390,7 @@ Please update your sources to pass an instance of RunLoop::Xcode))
|
|
324
390
|
lldb.retriable_inject_dylib
|
325
391
|
end
|
326
392
|
|
393
|
+
RunLoop.log_debug("It took #{Time.now - before} seconds to launch the app")
|
327
394
|
run_loop
|
328
395
|
end
|
329
396
|
|
@@ -360,131 +427,148 @@ Please update your sources to pass an instance of RunLoop::Xcode))
|
|
360
427
|
def self.simulator_target?(run_options, sim_control=nil)
|
361
428
|
value = run_options[:device_target]
|
362
429
|
|
363
|
-
#
|
430
|
+
# Match the behavior of udid_and_bundle_for_launcher.
|
364
431
|
return true if value.nil? or value == ''
|
365
432
|
|
366
|
-
#
|
433
|
+
# 5.1 <= Xcode < 7.0
|
367
434
|
return true if value.downcase.include?('simulator')
|
368
435
|
|
369
|
-
|
436
|
+
# Not a physical device.
|
437
|
+
return false if value[DEVICE_UDID_REGEX, 0] != nil
|
438
|
+
|
439
|
+
# Check for named simulators and Xcode >= 7.0 simulators.
|
440
|
+
sim_control = run_options[:sim_control] || RunLoop::SimControl.new
|
441
|
+
xcode = sim_control.xcode
|
442
|
+
if xcode.version_gte_6?
|
443
|
+
simulator = sim_control.simulators.find do |sim|
|
444
|
+
sim.instruments_identifier(xcode) == value ||
|
445
|
+
sim.udid == value
|
446
|
+
end
|
447
|
+
!simulator.nil?
|
448
|
+
else
|
449
|
+
false
|
450
|
+
end
|
370
451
|
end
|
371
452
|
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
dylib_path
|
453
|
+
|
454
|
+
# Extracts the value of :inject_dylib from options Hash.
|
455
|
+
# @param options [Hash] arguments passed to {RunLoop.run}
|
456
|
+
# @return [String, nil] If the options contains :inject_dylibs and it is a
|
457
|
+
# path to a dylib that exists, return the path. Otherwise return nil or
|
458
|
+
# raise an error.
|
459
|
+
# @raise [RuntimeError] If :inject_dylib points to a path that does not exist.
|
460
|
+
# @raise [ArgumentError] If :inject_dylib is not a String.
|
461
|
+
def self.dylib_path_from_options(options)
|
462
|
+
inject_dylib = options.fetch(:inject_dylib, nil)
|
463
|
+
return nil if inject_dylib.nil?
|
464
|
+
unless inject_dylib.is_a? String
|
465
|
+
raise ArgumentError, "Expected :inject_dylib to be a path to a dylib, but found '#{inject_dylib}'"
|
466
|
+
end
|
467
|
+
dylib_path = File.expand_path(inject_dylib)
|
468
|
+
unless File.exist?(dylib_path)
|
469
|
+
raise "Cannot load dylib. The file '#{dylib_path}' does not exist."
|
390
470
|
end
|
471
|
+
dylib_path
|
472
|
+
end
|
391
473
|
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
474
|
+
# Returns the a default simulator to target. This default needs to be one
|
475
|
+
# that installed by default in the current Xcode version.
|
476
|
+
#
|
477
|
+
# For historical reasons, the most recent non-64b SDK should be used.
|
478
|
+
#
|
479
|
+
# @param [RunLoop::XCTools, RunLoop::XCode] xcode Used to detect the current xcode
|
480
|
+
# version.
|
481
|
+
def self.default_simulator(xcode=RunLoop::Xcode.new)
|
482
|
+
if xcode.is_a?(RunLoop::XCTools)
|
483
|
+
RunLoop.deprecated('1.5.0',
|
484
|
+
%q(
|
403
485
|
RunLoop::XCTools has been replaced with RunLoop::Xcode.
|
404
486
|
Please update your sources to pass an instance of RunLoop::Xcode))
|
405
|
-
|
487
|
+
end
|
406
488
|
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
489
|
+
if xcode.version_gte_71?
|
490
|
+
'iPhone 6s (9.1)'
|
491
|
+
elsif xcode.version_gte_7?
|
492
|
+
'iPhone 5s (9.0)'
|
493
|
+
elsif xcode.version_gte_64?
|
494
|
+
'iPhone 5s (8.4 Simulator)'
|
495
|
+
elsif xcode.version_gte_63?
|
496
|
+
'iPhone 5s (8.3 Simulator)'
|
497
|
+
elsif xcode.version_gte_62?
|
498
|
+
'iPhone 5s (8.2 Simulator)'
|
499
|
+
elsif xcode.version_gte_61?
|
500
|
+
'iPhone 5s (8.1 Simulator)'
|
501
|
+
elsif xcode.version_gte_6?
|
502
|
+
'iPhone 5s (8.0 Simulator)'
|
503
|
+
else
|
504
|
+
'iPhone Retina (4-inch) - Simulator - iOS 7.1'
|
422
505
|
end
|
506
|
+
end
|
423
507
|
|
424
|
-
|
425
|
-
|
508
|
+
def self.udid_and_bundle_for_launcher(device_target, options, sim_control=RunLoop::SimControl.new)
|
509
|
+
xcode = sim_control.xcode
|
426
510
|
|
427
|
-
|
511
|
+
bundle_dir_or_bundle_id = options[:app] || RunLoop::Environment.bundle_id || RunLoop::Environment.path_to_app_bundle
|
428
512
|
|
429
|
-
|
430
|
-
|
431
|
-
|
513
|
+
unless bundle_dir_or_bundle_id
|
514
|
+
raise 'key :app or environment variable APP_BUNDLE_PATH, BUNDLE_ID or APP must be specified as path to app bundle (simulator) or bundle id (device)'
|
515
|
+
end
|
432
516
|
|
433
|
-
|
517
|
+
udid = nil
|
434
518
|
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
519
|
+
if xcode.version_gte_51?
|
520
|
+
if device_target.nil? || device_target.empty? || device_target == 'simulator'
|
521
|
+
device_target = self.default_simulator(xcode)
|
522
|
+
end
|
523
|
+
udid = device_target
|
440
524
|
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
525
|
+
unless self.simulator_target?(options)
|
526
|
+
bundle_dir_or_bundle_id = options[:bundle_id] if options[:bundle_id]
|
527
|
+
end
|
528
|
+
else
|
529
|
+
#TODO: this can be removed - Xcode < 5.1.1 not supported.
|
530
|
+
if device_target == 'simulator'
|
447
531
|
|
448
|
-
|
449
|
-
|
450
|
-
|
532
|
+
unless File.exist?(bundle_dir_or_bundle_id)
|
533
|
+
raise "Unable to find app in directory #{bundle_dir_or_bundle_id} when trying to launch simulator"
|
534
|
+
end
|
451
535
|
|
452
536
|
|
453
|
-
|
454
|
-
|
537
|
+
device = options[:device] || :iphone
|
538
|
+
device = device && device.to_sym
|
455
539
|
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
else
|
461
|
-
uidevicefamily=2
|
462
|
-
end
|
463
|
-
system("#{plistbuddy} -c 'Delete :UIDeviceFamily' '#{plistfile}'")
|
464
|
-
system("#{plistbuddy} -c 'Add :UIDeviceFamily array' '#{plistfile}'")
|
465
|
-
system("#{plistbuddy} -c 'Add :UIDeviceFamily:0 integer #{uidevicefamily}' '#{plistfile}'")
|
540
|
+
plistbuddy='/usr/libexec/PlistBuddy'
|
541
|
+
plistfile="#{bundle_dir_or_bundle_id}/Info.plist"
|
542
|
+
if device == :iphone
|
543
|
+
uidevicefamily=1
|
466
544
|
else
|
467
|
-
|
468
|
-
bundle_dir_or_bundle_id = options[:bundle_id] if options[:bundle_id]
|
545
|
+
uidevicefamily=2
|
469
546
|
end
|
547
|
+
system("#{plistbuddy} -c 'Delete :UIDeviceFamily' '#{plistfile}'")
|
548
|
+
system("#{plistbuddy} -c 'Add :UIDeviceFamily array' '#{plistfile}'")
|
549
|
+
system("#{plistbuddy} -c 'Add :UIDeviceFamily:0 integer #{uidevicefamily}' '#{plistfile}'")
|
550
|
+
else
|
551
|
+
udid = device_target
|
552
|
+
bundle_dir_or_bundle_id = options[:bundle_id] if options[:bundle_id]
|
470
553
|
end
|
471
|
-
return udid, bundle_dir_or_bundle_id
|
472
554
|
end
|
555
|
+
return udid, bundle_dir_or_bundle_id
|
556
|
+
end
|
473
557
|
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
end
|
558
|
+
def self.create_uia_pipe(repl_path)
|
559
|
+
begin
|
560
|
+
Timeout::timeout(5, RunLoop::TimeoutError) do
|
561
|
+
loop do
|
562
|
+
begin
|
563
|
+
FileUtils.rm_f(repl_path)
|
564
|
+
return repl_path if system(%Q[mkfifo "#{repl_path}"])
|
565
|
+
rescue Errno::EINTR => e
|
566
|
+
#retry
|
567
|
+
sleep(0.1)
|
485
568
|
end
|
486
569
|
end
|
487
|
-
|
570
|
+
end
|
571
|
+
rescue RunLoop::TimeoutError => _
|
488
572
|
raise RunLoop::TimeoutError, 'Unable to create pipe (mkfifo failed)'
|
489
573
|
end
|
490
574
|
end
|