run_ios_simulator.py 3.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. from __future__ import print_function
  2. import argparse
  3. import json
  4. import os
  5. import subprocess
  6. import sys
  7. def just_do_it():
  8. parser = argparse.ArgumentParser()
  9. parser.add_argument("--action", choices=["create", "spawn", "kill"])
  10. parser.add_argument("--simctl", help="simctl binary path")
  11. parser.add_argument("--profiles", help="profiles path")
  12. parser.add_argument("--device-dir", help="devices directory")
  13. parser.add_argument("--device-name", help="temp device name")
  14. args, tail = parser.parse_known_args()
  15. if args.action == 'create':
  16. action_create(args.simctl, args.profiles, args.device_dir, args.device_name, tail)
  17. elif args.action == "spawn":
  18. action_spawn(args.simctl, args.profiles, args.device_dir, args.device_name, tail)
  19. elif args.action == "kill":
  20. action_kill(args.simctl, args.profiles, args.device_dir, args.device_name)
  21. def action_create(simctl, profiles, device_dir, name, args):
  22. parser = argparse.ArgumentParser()
  23. parser.add_argument("--device-type", default="com.apple.CoreSimulator.SimDeviceType.iPhone-X")
  24. parser.add_argument("--device-runtime", default="com.apple.CoreSimulator.SimRuntime.iOS-12-1")
  25. args = parser.parse_args(args)
  26. all_devices = list(get_all_devices(simctl, profiles, device_dir))
  27. if filter(lambda x: x["name"] == name, all_devices):
  28. raise Exception("Device named {} already exists".format(name))
  29. subprocess.check_call(
  30. [simctl, "--profiles", profiles, "--set", device_dir, "create", name, args.device_type, args.device_runtime]
  31. )
  32. created = filter(lambda x: x["name"] == name, get_all_devices(simctl, profiles, device_dir))
  33. if not created:
  34. raise Exception("Creation error: temp device named {} not found".format(name))
  35. created = created[0]
  36. if created["availability"] != "(available)":
  37. raise Exception(
  38. "Creation error: temp device {} status is {} ((available) expected)".format(name, created["availability"])
  39. )
  40. def action_spawn(simctl, profiles, device_dir, name, args):
  41. device = filter(lambda x: x["name"] == name, get_all_devices(simctl, profiles, device_dir))
  42. if not device:
  43. raise Exception("Can't spawn process: device named {} not found".format(name))
  44. if len(device) > 1:
  45. raise Exception("Can't spawn process: too many devices named {} found".format(name))
  46. device = device[0]
  47. os.execv(simctl, [simctl, "--profiles", profiles, "--set", device_dir, "spawn", device["udid"]] + args)
  48. def action_kill(simctl, profiles, device_dir, name):
  49. device = filter(lambda x: x["name"] == name, get_all_devices(simctl, profiles, device_dir))
  50. if not device:
  51. print("Device named {} not found; do nothing".format(name), file=sys.stderr)
  52. return
  53. if len(device) > 1:
  54. raise Exception("Can't remove: too many devices named {}:\n{}".format(name, '\n'.join(i for i in device)))
  55. device = device[0]
  56. os.execv(simctl, [simctl, "--profiles", profiles, "--set", device_dir, "delete", device["udid"]])
  57. def get_all_devices(simctl, profiles, device_dir):
  58. p = subprocess.Popen(
  59. [simctl, "--profiles", profiles, "--set", device_dir, "list", "--json", "devices"], stdout=subprocess.PIPE
  60. )
  61. out, _ = p.communicate()
  62. rc = p.wait()
  63. if rc:
  64. raise Exception("Devices list command return code is {}\nstdout:\n{}".format(rc, out))
  65. raw_object = json.loads(out)
  66. if "devices" not in raw_object:
  67. raise Exception("Devices not found in\n{}".format(json.dumps(raw_object)))
  68. raw_object = raw_object["devices"]
  69. for os_name, devices in raw_object.items():
  70. for device in devices:
  71. device["os_name"] = os_name
  72. yield device
  73. if __name__ == '__main__':
  74. just_do_it()