Skip to content

Commit 1e45668

Browse files
Allow using @rules_apple//apple/build_settings:ios_device with running on simulator (#2778)
Sometimes it’s nice to target a specific simulator. Signed-off-by: Brentley Jones <github@brentleyjones.com>
1 parent 7ec28f7 commit 1e45668

4 files changed

Lines changed: 39 additions & 11 deletions

File tree

apple/build_settings/build_settings.bzl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ Enables Bazel's tree artifacts for Apple bundle rules (instead of archives).
4242
doc = """
4343
The identifier, ECID, serial number, UDID, user-provided name, or DNS name
4444
of the device for running an iOS application.
45-
You can get a list of devices by running 'xcrun devicectl list devices`.
45+
46+
You can get a list of devices by running `xcrun devicectl list devices` (for
47+
physical devices) or `xcrun simctl list devices` (for simulators).
4648
""",
4749
default = "",
4850
),

apple/internal/ios_rules.bzl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,9 @@ def _ios_application_impl(ctx):
496496
rule_descriptor = rule_descriptor,
497497
runner_template = ctx.file._simulator_runner_template,
498498
simulator_device = ctx.fragments.objc.ios_simulator_device,
499+
simulator_identifier = (
500+
apple_xplat_toolchain_info.build_settings.ios_device
501+
),
499502
simulator_version = ctx.fragments.objc.ios_simulator_version,
500503
)
501504

apple/internal/run_support.bzl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ def _register_simulator_executable(
3131
rule_descriptor,
3232
runner_template,
3333
simulator_device = None,
34+
simulator_identifier = None,
3435
simulator_version = None):
3536
"""Registers an action that runs the bundled app in the iOS simulator.
3637
@@ -45,10 +46,12 @@ def _register_simulator_executable(
4546
rule_descriptor: The rule descriptor for the given rule.
4647
runner_template: The simulator runner template as a `File`.
4748
simulator_device: The type of device (e.g. 'iPhone 6') to use when running on the simulator.
49+
simulator_identifier: The identifier of the simulator (<uuid>).
4850
simulator_version: The SDK version of the simulator to use when running on the simulator.
4951
"""
5052

5153
sim_device = str(simulator_device or "")
54+
sim_identifier = str(simulator_identifier or "")
5255
sim_os_version = str(simulator_version or "")
5356
minimum_os = str(platform_prerequisites.minimum_os)
5457
platform_type = str(platform_prerequisites.platform_type)
@@ -72,6 +75,7 @@ def _register_simulator_executable(
7275
"%minimum_os%": minimum_os,
7376
"%platform_type%": platform_type,
7477
"%sim_device%": sim_device,
78+
"%sim_identifier%": sim_identifier,
7579
"%sim_os_version%": sim_os_version,
7680
},
7781
)

apple/internal/templates/apple_simulator.template.py

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -231,15 +231,17 @@ def discover_best_compatible_simulator(
231231
simctl_path: str,
232232
minimum_os: str,
233233
sim_device: str,
234+
sim_identifier: str,
234235
sim_os_version: str,
235-
) -> (Optional[DeviceType], Optional[Device]):
236+
) -> tuple[Optional[DeviceType], Optional[Device]]:
236237
"""Discovers the best compatible simulator device type and device.
237238
238239
Args:
239240
platform_type: The Apple platform type for the given *_application() target.
240241
simctl_path: The path to the `simctl` binary.
241242
minimum_os: The minimum OS version required by the *_application() target.
242-
sim_device: Optional name of the device (e.g. "iPhone 8 Plus").
243+
sim_device: Optional name of the device type (e.g. "iPhone 8 Plus").
244+
sim_identifier: The identifier of the simulator (<uuid>).
243245
sim_os_version: Optional version of the Apple platform runtime (e.g.
244246
"13.2").
245247
@@ -298,6 +300,12 @@ def discover_best_compatible_simulator(
298300
for device in devices:
299301
if not device["isAvailable"]:
300302
continue
303+
if sim_identifier:
304+
if device["udid"] != sim_identifier:
305+
continue
306+
compatible_device = Device(device, None)
307+
compatible_devices.append(compatible_device)
308+
break
301309
compatible_device = None
302310
for device_type in compatible_device_types:
303311
if device["deviceTypeIdentifier"] == device_type["identifier"]:
@@ -308,7 +316,7 @@ def discover_best_compatible_simulator(
308316
compatible_devices.append(compatible_device)
309317
compatible_devices.sort()
310318
logger.debug("Found %d compatible devices.", len(compatible_devices))
311-
if compatible_device_types:
319+
if not sim_identifier and compatible_device_types:
312320
best_compatible_device_type = compatible_device_types[-1]
313321
else:
314322
best_compatible_device_type = None
@@ -325,6 +333,7 @@ def persistent_simulator(
325333
simctl_path: str,
326334
minimum_os: str,
327335
sim_device: str,
336+
sim_identifier: str,
328337
sim_os_version: str,
329338
) -> str:
330339
"""Finds or creates a persistent compatible Apple simulator.
@@ -336,7 +345,8 @@ def persistent_simulator(
336345
platform_type: The Apple platform type for the given *_application() target.
337346
simctl_path: The path to the `simctl` binary.
338347
minimum_os: The minimum OS version required by the *_application() target.
339-
sim_device: Optional name of the device (e.g. "iPhone 8 Plus").
348+
sim_device: Optional name of the device type (e.g. "iPhone 8 Plus").
349+
sim_identifier: The identifier of the simulator (<uuid>).
340350
sim_os_version: Optional version of the Apple platform runtime (e.g.
341351
"13.2").
342352
@@ -352,6 +362,7 @@ def persistent_simulator(
352362
simctl_path=simctl_path,
353363
minimum_os=minimum_os,
354364
sim_device=sim_device,
365+
sim_identifier=sim_identifier,
355366
sim_os_version=sim_os_version,
356367
)
357368
)
@@ -377,9 +388,10 @@ def persistent_simulator(
377388
logger.debug("Created new simulator: %s", udid)
378389
return udid
379390
raise Exception(
380-
f"Could not find or create a simulator for the {platform_type} platform"
381-
f"compatible with minimum OS version {minimum_os} (device name "
382-
f"{sim_device}, OS version {sim_os_version})"
391+
f"Could not find or create a simulator for the {platform_type} platform "
392+
f"compatible with minimum OS version {minimum_os} (uuid "
393+
f"'{sim_identifier}', device name '{sim_device}', OS version "
394+
f"'{sim_os_version}')"
383395
)
384396

385397

@@ -622,15 +634,17 @@ def apple_simulator(
622634
simctl_path: str,
623635
minimum_os: str,
624636
sim_device: str,
637+
sim_identifier: str,
625638
sim_os_version: str,
626639
) -> AppleSimulatorUDID:
627-
"""Finds either a temporary or persistent Apple simulator based on args.
640+
"""Finds or creates a persistent compatible Apple simulator.
628641
629642
Args:
630643
platform_type: The Apple platform type for the given *_application() target.
631644
simctl_path: The path to the `simctl` binary.
632645
minimum_os: The minimum OS version required by the *_application() target.
633-
sim_device: Optional name of the device (e.g. "iPhone 8 Plus").
646+
sim_device: Optional name of the device type (e.g. "iPhone 8 Plus").
647+
sim_identifier: The identifier of the simulator (<uuid>).
634648
sim_os_version: Optional version of the Apple platform runtime (e.g.
635649
"13.2").
636650
@@ -651,6 +665,7 @@ def apple_simulator(
651665
simctl_path=simctl_path,
652666
minimum_os=minimum_os,
653667
sim_device=sim_device,
668+
sim_identifier=sim_identifier,
654669
sim_os_version=sim_os_version,
655670
)
656671

@@ -779,6 +794,7 @@ def main(
779794
minimum_os: str,
780795
platform_type: str,
781796
sim_device: str,
797+
sim_identifier: str,
782798
sim_os_version: str,
783799
):
784800
"""Main entry point to `bazel run` for *_application() targets.
@@ -788,7 +804,8 @@ def main(
788804
application_output_path: Path to the output of an *_application().
789805
minimum_os: The minimum OS version required by the *_application() target.
790806
platform_type: The Apple platform type for the given *_application() target.
791-
sim_device: The name of the device (e.g. "iPhone 8 Plus").
807+
sim_device: The name of the device type (e.g. "iPhone 8 Plus").
808+
sim_identifier: The identifier of the simulator (<uuid>).
792809
sim_os_version: The version of the Apple platform runtime (e.g. "13.2").
793810
"""
794811
xcode_select_result = subprocess.run(
@@ -805,6 +822,7 @@ def main(
805822
simctl_path=simctl_path,
806823
minimum_os=minimum_os,
807824
sim_device=sim_device,
825+
sim_identifier=sim_identifier,
808826
sim_os_version=sim_os_version,
809827
) as simulator_udid:
810828
run_app_in_simulator(
@@ -825,6 +843,7 @@ def main(
825843
minimum_os="%minimum_os%",
826844
platform_type="%platform_type%",
827845
sim_device="%sim_device%",
846+
sim_identifier="%sim_identifier%",
828847
sim_os_version="%sim_os_version%",
829848
)
830849
except subprocess.CalledProcessError as e:

0 commit comments

Comments
 (0)