run_loop_tcc 2.1.3

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.
Files changed (87) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/bin/run-loop +19 -0
  4. data/lib/run_loop/abstract.rb +18 -0
  5. data/lib/run_loop/app.rb +372 -0
  6. data/lib/run_loop/cache/cache.rb +68 -0
  7. data/lib/run_loop/cli/cli.rb +48 -0
  8. data/lib/run_loop/cli/codesign.rb +24 -0
  9. data/lib/run_loop/cli/errors.rb +11 -0
  10. data/lib/run_loop/cli/instruments.rb +160 -0
  11. data/lib/run_loop/cli/locale.rb +31 -0
  12. data/lib/run_loop/cli/simctl.rb +257 -0
  13. data/lib/run_loop/cli/tcc.rb +139 -0
  14. data/lib/run_loop/codesign.rb +76 -0
  15. data/lib/run_loop/core.rb +902 -0
  16. data/lib/run_loop/core_simulator.rb +960 -0
  17. data/lib/run_loop/detect_aut/detect.rb +185 -0
  18. data/lib/run_loop/detect_aut/errors.rb +126 -0
  19. data/lib/run_loop/detect_aut/xamarin_studio.rb +46 -0
  20. data/lib/run_loop/detect_aut/xcode.rb +157 -0
  21. data/lib/run_loop/device.rb +722 -0
  22. data/lib/run_loop/device_agent/app/CBX-Runner.app.zip +0 -0
  23. data/lib/run_loop/device_agent/bin/xctestctl +0 -0
  24. data/lib/run_loop/device_agent/cbxrunner.rb +156 -0
  25. data/lib/run_loop/device_agent/frameworks/Frameworks.zip +0 -0
  26. data/lib/run_loop/device_agent/frameworks.rb +65 -0
  27. data/lib/run_loop/device_agent/ipa/CBX-Runner.app.zip +0 -0
  28. data/lib/run_loop/device_agent/launcher.rb +51 -0
  29. data/lib/run_loop/device_agent/xcodebuild.rb +91 -0
  30. data/lib/run_loop/device_agent/xctestctl.rb +109 -0
  31. data/lib/run_loop/directory.rb +179 -0
  32. data/lib/run_loop/dnssd.rb +148 -0
  33. data/lib/run_loop/dot_dir.rb +87 -0
  34. data/lib/run_loop/dylib_injector.rb +145 -0
  35. data/lib/run_loop/encoding.rb +56 -0
  36. data/lib/run_loop/environment.rb +361 -0
  37. data/lib/run_loop/fifo.rb +40 -0
  38. data/lib/run_loop/host_cache.rb +128 -0
  39. data/lib/run_loop/http/error.rb +15 -0
  40. data/lib/run_loop/http/request.rb +44 -0
  41. data/lib/run_loop/http/retriable_client.rb +166 -0
  42. data/lib/run_loop/http/server.rb +17 -0
  43. data/lib/run_loop/instruments.rb +436 -0
  44. data/lib/run_loop/ipa.rb +142 -0
  45. data/lib/run_loop/l10n.rb +93 -0
  46. data/lib/run_loop/language.rb +63 -0
  47. data/lib/run_loop/lipo.rb +132 -0
  48. data/lib/run_loop/lldb.rb +52 -0
  49. data/lib/run_loop/locale.rb +101 -0
  50. data/lib/run_loop/logging.rb +111 -0
  51. data/lib/run_loop/otool.rb +76 -0
  52. data/lib/run_loop/patches/awesome_print.rb +17 -0
  53. data/lib/run_loop/physical_device/life_cycle.rb +268 -0
  54. data/lib/run_loop/plist_buddy.rb +189 -0
  55. data/lib/run_loop/process_terminator.rb +128 -0
  56. data/lib/run_loop/process_waiter.rb +117 -0
  57. data/lib/run_loop/regex.rb +19 -0
  58. data/lib/run_loop/shell.rb +103 -0
  59. data/lib/run_loop/sim_control.rb +1264 -0
  60. data/lib/run_loop/simctl.rb +275 -0
  61. data/lib/run_loop/sqlite.rb +61 -0
  62. data/lib/run_loop/strings.rb +88 -0
  63. data/lib/run_loop/tcc/TCC.db +0 -0
  64. data/lib/run_loop/tcc/tcc.rb +240 -0
  65. data/lib/run_loop/template.rb +61 -0
  66. data/lib/run_loop/version.rb +182 -0
  67. data/lib/run_loop/xcode.rb +318 -0
  68. data/lib/run_loop/xcrun.rb +107 -0
  69. data/lib/run_loop/xcuitest.rb +550 -0
  70. data/lib/run_loop.rb +230 -0
  71. data/plists/simctl/com.apple.UIAutomation.plist +0 -0
  72. data/plists/simctl/com.apple.UIAutomationPlugIn.plist +0 -0
  73. data/scripts/calabash_script_uia.js +28184 -0
  74. data/scripts/lib/json2.min.js +26 -0
  75. data/scripts/lib/log.js +26 -0
  76. data/scripts/lib/on_alert.js +224 -0
  77. data/scripts/read-cmd.sh +2 -0
  78. data/scripts/run_dismiss_location.js +89 -0
  79. data/scripts/run_loop_basic.js +34 -0
  80. data/scripts/run_loop_fast_uia.js +188 -0
  81. data/scripts/run_loop_host.js +117 -0
  82. data/scripts/run_loop_shared_element.js +125 -0
  83. data/scripts/timeout3 +23 -0
  84. data/scripts/udidetect +0 -0
  85. data/vendor-licenses/FBSimulatorControl.LICENSE +30 -0
  86. data/vendor-licenses/xctestctl.LICENSE +32 -0
  87. metadata +443 -0
@@ -0,0 +1,142 @@
1
+ module RunLoop
2
+ # A model of the an .ipa - a application binary for iOS devices.
3
+ class Ipa
4
+
5
+ # The path to this .ipa.
6
+ # @!attribute [r] path
7
+ # @return [String] A path to this .ipa.
8
+ attr_reader :path
9
+
10
+ # Create a new ipa instance.
11
+ # @param [String] path_to_ipa The path the .ipa file.
12
+ # @return [Calabash::Ipa] A new ipa instance.
13
+ # @raise [RuntimeError] If the file does not exist.
14
+ # @raise [RuntimeError] If the file does not end in .ipa.
15
+ def initialize(path_to_ipa)
16
+ unless File.exist? path_to_ipa
17
+ raise "Expected an ipa at '#{path_to_ipa}'"
18
+ end
19
+
20
+ unless path_to_ipa.end_with?('.ipa')
21
+ raise "Expected '#{path_to_ipa}' to be an .ipa"
22
+ end
23
+ @path = path_to_ipa
24
+ end
25
+
26
+ # @!visibility private
27
+ def to_s
28
+ cf_bundle_version = bundle_version
29
+ cf_bundle_short_version = short_bundle_version
30
+
31
+ if cf_bundle_version && cf_bundle_short_version
32
+ version = "#{cf_bundle_version.to_s}/#{cf_bundle_short_version}"
33
+ elsif cf_bundle_version
34
+ version = cf_bundle_version.to_s
35
+ elsif cf_bundle_short_version
36
+ version = cf_bundle_short_version
37
+ else
38
+ version = ""
39
+ end
40
+
41
+ "#<IPA #{bundle_identifier} #{version} #{path}>"
42
+ end
43
+
44
+ # @!visibility private
45
+ def inspect
46
+ to_s
47
+ end
48
+
49
+ # The bundle identifier of this ipa.
50
+ # @return [String] A string representation of this ipa's CFBundleIdentifier
51
+ def bundle_identifier
52
+ app.bundle_identifier
53
+ end
54
+
55
+ # Inspects the app's Info.plist for the executable name.
56
+ # @return [String] The value of CFBundleExecutable.
57
+ def executable_name
58
+ app.executable_name
59
+ end
60
+
61
+ # Returns the arches for the binary.
62
+ def arches
63
+ app.arches
64
+ end
65
+
66
+ # Inspects the app's executables for the server version
67
+ # @return[RunLoop::Version] a version instance
68
+ def calabash_server_version
69
+ app.calabash_server_version
70
+ end
71
+
72
+ # @!visibility private
73
+ def codesign_info
74
+ app.codesign_info
75
+ end
76
+
77
+ # @!visibility private
78
+ def developer_signed?
79
+ app.developer_signed?
80
+ end
81
+
82
+ # @!visibility private
83
+ def distribution_signed?
84
+ app.distribution_signed?
85
+ end
86
+
87
+ # @!visibility private
88
+ def marketing_version
89
+ app.marketing_version
90
+ end
91
+
92
+ # See #marketing_version
93
+ alias_method :short_bundle_version, :marketing_version
94
+
95
+ # @!visibility private
96
+ def build_version
97
+ app.build_version
98
+ end
99
+
100
+ # See #build_version
101
+ alias_method :bundle_version, :build_version
102
+
103
+ private
104
+
105
+ # @!visibility private
106
+ def tmpdir
107
+ @tmpdir ||= Dir.mktmpdir
108
+ end
109
+
110
+ # @!visibility private
111
+ def payload_dir
112
+ @payload_dir ||= lambda do
113
+ FileUtils.cp(path, tmpdir)
114
+ zip_path = File.join(tmpdir, File.basename(path))
115
+ Dir.chdir(tmpdir) do
116
+ system('unzip', *['-q', zip_path])
117
+ end
118
+ File.join(tmpdir, 'Payload')
119
+ end.call
120
+ end
121
+
122
+ # @!visibility private
123
+ def bundle_dir
124
+ @bundle_dir ||= lambda do
125
+ Dir.glob(File.join(payload_dir, '*')).detect do |f|
126
+ File.directory?(f) && f.end_with?('.app')
127
+ end
128
+ end.call
129
+ end
130
+
131
+ # @!visibility private
132
+ def app
133
+ @app ||= RunLoop::App.new(bundle_dir)
134
+ end
135
+
136
+ # @!visibility private
137
+ def plist_buddy
138
+ @plist_buddy ||= RunLoop::PlistBuddy.new
139
+ end
140
+ end
141
+ end
142
+
@@ -0,0 +1,93 @@
1
+ module RunLoop
2
+ class L10N
3
+
4
+ # Find the localized name for a given key_code
5
+ #
6
+ # @example
7
+ # lookup_localization_name('delete.key', 'da') => 'Slet'
8
+ #
9
+ # @param [String] key_code the localization signifier, e.g. 'delete.key'
10
+ # @param [String] localized_lang an iso language code returned by calabash ios server
11
+ #
12
+ # @return [String] the localized name
13
+ def lookup_localization_name(key_code, localized_lang)
14
+ lookup_table_dir = lang_dir(localized_lang)
15
+ return nil unless lookup_table_dir
16
+
17
+ key_name_lookup_table(lookup_table_dir)[key_code]
18
+ end
19
+
20
+ UIKIT_AXBUNDLE_PATH_CORE_SIM = 'Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/AccessibilityBundles/UIKit.axbundle/'
21
+
22
+ LANG_CODE_TO_LANG_NAME_MAP = {
23
+ 'en' => 'English',
24
+ 'nl' => 'Dutch',
25
+ 'fr' => 'French',
26
+ 'de' => 'German',
27
+ 'es' => 'Spanish',
28
+ 'it' => 'Italian',
29
+ 'jp' => 'Japanese'
30
+ }
31
+
32
+ # @!visibility private
33
+ def to_s
34
+ "#<L10N #{uikit_bundle_l10n_path}>"
35
+ end
36
+
37
+ # @!visibility private
38
+ def inspect
39
+ to_s
40
+ end
41
+
42
+ # maps the ios keyboard localization to a language directory where we can
43
+ # find a key-code -> localized-label mapping
44
+ def lang_dir(localized_lang)
45
+ l10n_path = uikit_bundle_l10n_path
46
+
47
+ ## 2 char + _ + sub localization
48
+ # en_GB.lproj
49
+ lang_dir_name = "#{localized_lang}.lproj".sub('-','_')
50
+ if File.exists?(File.join(l10n_path, lang_dir_name))
51
+ return lang_dir_name
52
+ end
53
+
54
+ # 2 char iso language code
55
+ # vi.lproj
56
+ two_char_country_code = localized_lang.split('-')[0]
57
+ lang_dir_name = "#{two_char_country_code}.lproj"
58
+ if File.exists?(File.join(l10n_path, lang_dir_name))
59
+ return lang_dir_name
60
+ end
61
+
62
+ # Full name
63
+ # e.g. Dutch.lproj
64
+ lang_dir_name = "#{LANG_CODE_TO_LANG_NAME_MAP[two_char_country_code]}.lproj"
65
+ if is_full_name?(two_char_country_code) &&
66
+ File.exists?(File.join(l10n_path, lang_dir_name))
67
+ return lang_dir_name
68
+ end
69
+ nil
70
+ end
71
+
72
+ def uikit_bundle_l10n_path
73
+ File.join(xcode.developer_dir, UIKIT_AXBUNDLE_PATH_CORE_SIM)
74
+ end
75
+
76
+ def is_full_name?(two_letter_country_code)
77
+ LANG_CODE_TO_LANG_NAME_MAP.has_key?(two_letter_country_code)
78
+ end
79
+
80
+ def key_name_lookup_table(lang_dir_name)
81
+ path = File.join(uikit_bundle_l10n_path, lang_dir_name, 'Accessibility.strings')
82
+ JSON.parse(`plutil -convert json #{path} -o -`)
83
+ end
84
+
85
+ # @!visibility private
86
+ attr_reader :xcode
87
+
88
+ # @!visibility private
89
+ def xcode
90
+ @xcode ||= RunLoop::Xcode.new
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,63 @@
1
+ module RunLoop
2
+ # @!visibility private
3
+ class Language
4
+
5
+ # @!visibility private
6
+ # Is the lang_code valid for this device?
7
+ def self.valid_code_for_device?(lang_code, device)
8
+ valid_codes = self.codes_for_device(device)
9
+ if valid_codes.nil?
10
+ false
11
+ else
12
+ valid_codes.include?(lang_code)
13
+ end
14
+ end
15
+
16
+ # @!visibility private
17
+ # Returns a list of known language codes for a device based on iOS version
18
+ #
19
+ # @param [RunLoop::Device] device
20
+ #
21
+ # @return [Array<String>] an array of language codes for the device
22
+ #
23
+ # @raise [ArgumentError] if there are no codes for a device version
24
+ def self.codes_for_device(device)
25
+ major_version = device.version.major
26
+ key = RunLoop::Version.new("#{major_version}.0")
27
+ LANGUAGE_CODES[key]
28
+ end
29
+
30
+ private
31
+
32
+ # @!visibility private
33
+ #
34
+ # Generated with:
35
+ #
36
+ # NSArray *identifiers = [[NSLocale availableLocaleIdentifiers]
37
+ # sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
38
+ # NSMutableOrderedSet *set = [NSMutableOrderedSet new];
39
+ # for (NSString *localeId in identifiers) {
40
+ # NSString *langCode = [NSLocale canonicalLanguageIdentifierFromString:localeId];
41
+ # [set addObject:langCode];
42
+ # }
43
+ #
44
+ # for (NSString *langCode in set) {
45
+ # printf("\"%s\",", [langCode cStringUsingEncoding:NSUTF8StringEncoding]);
46
+ # }
47
+ LANGUAGE_CODES = {
48
+ RunLoop::Version.new("10.0") => [
49
+ "af","af-NA","af-ZA","agq","agq-CM","ak","ak-GH","am","am-ET","ar","ar-001","ar-AE","ar-BH","ar-DJ","ar-DZ","ar-EG","ar-EH","ar-ER","ar-IL","ar-IQ","ar-JO","ar-KM","ar-KW","ar-LB","ar-LY","ar-MA","ar-MR","ar-OM","ar-PS","ar-QA","ar-SA","ar-SD","ar-SO","ar-SS","ar-SY","ar-TD","ar-TN","ar-YE","ars","as","as-IN","asa","asa-TZ","ast","ast-ES","az","az-Cyrl","az-Cyrl-AZ","az-AZ","bas","bas-CM","be","be-BY","bem","bem-ZM","bez","bez-TZ","bg","bg-BG","bm","bm-ML","bn","bn-BD","bn-IN","bo","bo-CN","bo-IN","br","br-FR","brx","brx-IN","bs","bs-Cyrl","bs-Cyrl-BA","bs-BA","ca","ca-AD","ca-ES","ca-FR","ca-IT","ce","ce-RU","cgg","cgg-UG","chr","chr-US","ckb","ckb-IQ","ckb-IR","cs","cs-CZ","cy","cy-GB","da","da-DK","da-GL","dav","dav-KE","de","de-AT","de-BE","de-CH","de-DE","de-LI","de-LU","dje","dje-NE","dsb","dsb-DE","dua","dua-CM","dyo","dyo-SN","dz","dz-BT","ebu","ebu-KE","ee","ee-GH","ee-TG","el","el-CY","el-GR","en","en-001","en-150","en-AD","en-AG","en-AI","en-AL","en-AS","en-AT","en-AU","en-BA","en-BB","en-BE","en-BI","en-BM","en-BR","en-BS","en-BW","en-BZ","en-CA","en-CC","en-CH","en-CK","en-CM","en-CN","en-CX","en-CY","en-CZ","en-DE","en-DG","en-DK","en-DM","en-EE","en-ER","en-ES","en-FI","en-FJ","en-FK","en-FM","en-FR","en-GB","en-GD","en-GG","en-GH","en-GI","en-GM","en-GR","en-GU","en-GY","en-HK","en-HR","en-HU","en-IE","en-IL","en-IM","en-IN","en-IO","en-IS","en-IT","en-JE","en-JM","en-JP","en-KE","en-KI","en-KN","en-KR","en-KY","en-LC","en-LR","en-LS","en-LT","en-LU","en-LV","en-ME","en-MG","en-MH","en-MO","en-MP","en-MS","en-MT","en-MU","en-MV","en-MW","en-MY","en-NA","en-NF","en-NG","en-NL","en-NO","en-NR","en-NU","en-NZ","en-PG","en-PH","en-PK","en-PL","en-PN","en-PR","en-PT","en-PW","en-RO","en-RU","en-RW","en-SB","en-SC","en-SD","en-SE","en-SG","en-SH","en-SI","en-SK","en-SL","en-SS","en-SX","en-SZ","en-TC","en-TK","en-TO","en-TR","en-TT","en-TV","en-TW","en-TZ","en-UG","en-UM","en-US","en-US-POSIX","en-VC","en-VG","en-VI","en-VU","en-WS","en-ZA","en-ZM","en-ZW","eo","es","es-419","es-AR","es-BO","es-CL","es-CO","es-CR","es-CU","es-DO","es-EA","es-EC","es-ES","es-GQ","es-GT","es-HN","es-IC","es-MX","es-NI","es-PA","es-PE","es-PH","es-PR","es-PY","es-SV","es-US","es-UY","es-VE","et","et-EE","eu","eu-ES","ewo","ewo-CM","fa","fa-AF","fa-IR","ff","ff-CM","ff-GN","ff-MR","ff-SN","fi","fi-FI","fil","fil-PH","fo","fo-DK","fo-FO","fr","fr-BE","fr-BF","fr-BI","fr-BJ","fr-BL","fr-CA","fr-CD","fr-CF","fr-CG","fr-CH","fr-CI","fr-CM","fr-DJ","fr-DZ","fr-FR","fr-GA","fr-GF","fr-GN","fr-GP","fr-GQ","fr-HT","fr-KM","fr-LU","fr-MA","fr-MC","fr-MF","fr-MG","fr-ML","fr-MQ","fr-MR","fr-MU","fr-NC","fr-NE","fr-PF","fr-PM","fr-RE","fr-RW","fr-SC","fr-SN","fr-SY","fr-TD","fr-TG","fr-TN","fr-VU","fr-WF","fr-YT","fur","fur-IT","fy","fy-NL","ga","ga-IE","gd","gd-GB","gl","gl-ES","gsw","gsw-CH","gsw-FR","gsw-LI","gu","gu-IN","guz","guz-KE","gv","gv-IM","ha","ha-GH","ha-NE","ha-NG","haw","haw-US","he","he-IL","hi","hi-IN","hr","hr-BA","hr-HR","hsb","hsb-DE","hu","hu-HU","hy","hy-AM","id","id-ID","ig","ig-NG","ii","ii-CN","is","is-IS","it","it-CH","it-IT","it-SM","iu","iu-CA","ja","ja-JP","jgo","jgo-CM","jmc","jmc-TZ","ka","ka-GE","kab","kab-DZ","kam","kam-KE","kde","kde-TZ","kea","kea-CV","khq","khq-ML","ki","ki-KE","kk","kk-KZ","kkj","kkj-CM","kl","kl-GL","kln","kln-KE","km","km-KH","kn","kn-IN","ko","ko-KP","ko-KR","kok","kok-IN","ks","ks-IN","ksb","ksb-TZ","ksf","ksf-CM","ksh","ksh-DE","kw","kw-GB","ky","ky-KG","lag","lag-TZ","lb","lb-LU","lg","lg-UG","lkt","lkt-US","ln","ln-AO","ln-CD","ln-CF","ln-CG","lo","lo-LA","lrc","lrc-IQ","lrc-IR","lt","lt-LT","lu","lu-CD","luo","luo-KE","luy","luy-KE","lv","lv-LV","mas","mas-KE","mas-TZ","mer","mer-KE","mfe","mfe-MU","mg","mg-MG","mgh","mgh-MZ","mgo","mgo-CM","mk","mk-MK","ml","ml-IN","mn","mn-MN","mr","mr-IN","ms","ms-Arab","ms-Arab-BN","ms-Arab-MY","ms-BN","ms-MY","ms-SG","mt","mt-MT","mua","mua-CM","my","my-MM","mzn","mzn-IR","naq","naq-NA","nb","nb-NO","nb-SJ","nd","nd-ZW","ne","ne-IN","ne-NP","nl","nl-AW","nl-BE","nl-BQ","nl-CW","nl-NL","nl-SR","nl-SX","nmg","nmg-CM","nn","nn-NO","nnh","nnh-CM","nus","nus-SS","nyn","nyn-UG","om","om-ET","om-KE","or","or-IN","os","os-GE","os-RU","pa","pa-Arab","pa-Arab-PK","pa-IN","pl","pl-PL","ps","ps-AF","pt","pt-AO","pt-BR","pt-CV","pt-GW","pt-MO","pt-MZ","pt-PT","pt-ST","pt-TL","qu","qu-BO","qu-EC","qu-PE","rm","rm-CH","rn","rn-BI","ro","ro-MD","ro-RO","rof","rof-TZ","ru","ru-BY","ru-KG","ru-KZ","ru-MD","ru-RU","ru-UA","rw","rw-RW","rwk","rwk-TZ","sah","sah-RU","saq","saq-KE","sbp","sbp-TZ","se","se-FI","se-NO","se-SE","seh","seh-MZ","ses","ses-ML","sg","sg-CF","shi","shi-MA","shi-Tfng","shi-Tfng-MA","si","si-LK","sk","sk-SK","sl","sl-SI","smn","smn-FI","sn","sn-ZW","so","so-DJ","so-ET","so-KE","so-SO","sq","sq-AL","sq-MK","sq-XK","sr","sr-BA","sr-ME","sr-RS","sr-XK","sr-Latn","sr-Latn-BA","sr-Latn-ME","sr-Latn-RS","sr-Latn-XK","sv","sv-AX","sv-FI","sv-SE","sw","sw-CD","sw-KE","sw-TZ","sw-UG","ta","ta-IN","ta-LK","ta-MY","ta-SG","te","te-IN","teo","teo-KE","teo-UG","tg","tg-TJ","th","th-TH","ti","ti-ER","ti-ET","tk","tk-TM","to","to-TO","tr","tr-CY","tr-TR","twq","twq-NE","tzm","tzm-MA","ug","ug-CN","uk","uk-UA","ur","ur-IN","ur-PK","uz","uz-Arab","uz-Arab-AF","uz-UZ","uz-Latn","uz-Latn-UZ","vai","vai-Latn","vai-Latn-LR","vai-LR","vi","vi-VN","vun","vun-TZ","wae","wae-CH","xog","xog-UG","yav","yav-CM","yi","yi-001","yo","yo-BJ","yo-NG","yue","yue-HK","zgh","zgh-MA","zh","zh-Hans","zh-Hans-CN","zh-Hans-HK","zh-Hans-MO","zh-Hans-SG","zh-Hant","zh-Hant-HK","zh-Hant-MO","zh-Hant-TW","zu","zu-ZA"
50
+ ],
51
+
52
+ RunLoop::Version.new("9.0") => [
53
+ "af","af-NA","af-ZA","agq","agq-CM","ak","ak-GH","am","am-ET","ar","ar-001","ar-AE","ar-BH","ar-DJ","ar-DZ","ar-EG","ar-EH","ar-ER","ar-IL","ar-IQ","ar-JO","ar-KM","ar-KW","ar-LB","ar-LY","ar-MA","ar-MR","ar-OM","ar-PS","ar-QA","ar-SA","ar-SD","ar-SO","ar-SS","ar-SY","ar-TD","ar-TN","ar-YE","as","as-IN","asa","asa-TZ","az","az-Cyrl","az-Cyrl-AZ","az-AZ","bas","bas-CM","be","be-BY","bem","bem-ZM","bez","bez-TZ","bg","bg-BG","bm","bm-ML","bn","bn-BD","bn-IN","bo","bo-CN","bo-IN","br","br-FR","brx","brx-IN","bs","bs-Cyrl","bs-Cyrl-BA","bs-BA","ca","ca-AD","ca-ES","ca-FR","ca-IT","cgg","cgg-UG","chr","chr-US","ckb","ckb-IQ","ckb-IR","cs","cs-CZ","cy","cy-GB","da","da-DK","da-GL","dav","dav-KE","de","de-AT","de-BE","de-CH","de-DE","de-LI","de-LU","dje","dje-NE","dsb","dsb-DE","dua","dua-CM","dyo","dyo-SN","dz","dz-BT","ebu","ebu-KE","ee","ee-GH","ee-TG","el","el-CY","el-GR","en","en-001","en-150","en-AD","en-AG","en-AI","en-AL","en-AS","en-AT","en-AU","en-BA","en-BB","en-BE","en-BM","en-BS","en-BW","en-BZ","en-CA","en-CC","en-CH","en-CK","en-CM","en-CX","en-CY","en-CZ","en-DE","en-DG","en-DK","en-DM","en-EE","en-ER","en-ES","en-FI","en-FJ","en-FK","en-FM","en-FR","en-GB","en-GD","en-GG","en-GH","en-GI","en-GM","en-GR","en-GU","en-GY","en-HK","en-HR","en-HU","en-IE","en-IL","en-IM","en-IN","en-IO","en-IS","en-IT","en-JE","en-JM","en-KE","en-KI","en-KN","en-KY","en-LC","en-LR","en-LS","en-LT","en-LU","en-LV","en-ME","en-MG","en-MH","en-MO","en-MP","en-MS","en-MT","en-MU","en-MW","en-MY","en-NA","en-NF","en-NG","en-NL","en-NO","en-NR","en-NU","en-NZ","en-PG","en-PH","en-PK","en-PL","en-PN","en-PR","en-PT","en-PW","en-RO","en-RU","en-RW","en-SB","en-SC","en-SD","en-SE","en-SG","en-SH","en-SI","en-SK","en-SL","en-SS","en-SX","en-SZ","en-TC","en-TK","en-TO","en-TR","en-TT","en-TV","en-TZ","en-UG","en-UM","en-US","en-US-POSIX","en-VC","en-VG","en-VI","en-VU","en-WS","en-ZA","en-ZM","en-ZW","eo","es","es-419","es-AR","es-BO","es-CL","es-CO","es-CR","es-CU","es-DO","es-EA","es-EC","es-ES","es-GQ","es-GT","es-HN","es-IC","es-MX","es-NI","es-PA","es-PE","es-PH","es-PR","es-PY","es-SV","es-US","es-UY","es-VE","et","et-EE","eu","eu-ES","ewo","ewo-CM","fa","fa-AF","fa-IR","ff","ff-CM","ff-GN","ff-MR","ff-SN","fi","fi-FI","fil","fil-PH","fo","fo-FO","fr","fr-BE","fr-BF","fr-BI","fr-BJ","fr-BL","fr-CA","fr-CD","fr-CF","fr-CG","fr-CH","fr-CI","fr-CM","fr-DJ","fr-DZ","fr-FR","fr-GA","fr-GF","fr-GN","fr-GP","fr-GQ","fr-HT","fr-KM","fr-LU","fr-MA","fr-MC","fr-MF","fr-MG","fr-ML","fr-MQ","fr-MR","fr-MU","fr-NC","fr-NE","fr-PF","fr-PM","fr-RE","fr-RW","fr-SC","fr-SN","fr-SY","fr-TD","fr-TG","fr-TN","fr-VU","fr-WF","fr-YT","fur","fur-IT","fy","fy-NL","ga","ga-IE","gd","gd-GB","gl","gl-ES","gsw","gsw-CH","gsw-FR","gsw-LI","gu","gu-IN","guz","guz-KE","gv","gv-IM","ha","ha-GH","ha-NE","ha-NG","haw","haw-US","he","he-IL","hi","hi-IN","hr","hr-BA","hr-HR","hsb","hsb-DE","hu","hu-HU","hy","hy-AM","id","id-ID","ig","ig-NG","ii","ii-CN","is","is-IS","it","it-CH","it-IT","it-SM","iu","iu-Cans","iu-Cans-CA","ja","ja-JP","jgo","jgo-CM","jmc","jmc-TZ","ka","ka-GE","kab","kab-DZ","kam","kam-KE","kde","kde-TZ","kea","kea-CV","khq","khq-ML","ki","ki-KE","kk","kk-KZ","kkj","kkj-CM","kl","kl-GL","kln","kln-KE","km","km-KH","kn","kn-IN","ko","ko-KP","ko-KR","kok","kok-IN","ks","ks-Arab","ks-Arab-IN","ksb","ksb-TZ","ksf","ksf-CM","ksh","ksh-DE","kw","kw-GB","ky","ky-KG","lag","lag-TZ","lb","lb-LU","lg","lg-UG","lkt","lkt-US","ln","ln-AO","ln-CD","ln-CF","ln-CG","lo","lo-LA","lt","lt-LT","lu","lu-CD","luo","luo-KE","luy","luy-KE","lv","lv-LV","mas","mas-KE","mas-TZ","mer","mer-KE","mfe","mfe-MU","mg","mg-MG","mgh","mgh-MZ","mgo","mgo-CM","mk","mk-MK","ml","ml-IN","mn","mn-MN","mr","mr-IN","ms","ms-Arab","ms-Arab-BN","ms-Arab-MY","ms-BN","ms-MY","ms-SG","mt","mt-MT","mua","mua-CM","my","my-MM","naq","naq-NA","nb","nb-NO","nb-SJ","nd","nd-ZW","ne","ne-IN","ne-NP","nl","nl-AW","nl-BE","nl-BQ","nl-CW","nl-NL","nl-SR","nl-SX","nmg","nmg-CM","nn","nn-NO","nnh","nnh-CM","nus","nus-SD","nyn","nyn-UG","om","om-ET","om-KE","or","or-IN","os","os-GE","os-RU","pa","pa-Arab","pa-Arab-PK","pa-IN","pl","pl-PL","ps","ps-AF","pt","pt-AO","pt-BR","pt-CV","pt-GW","pt-MO","pt-MZ","pt-PT","pt-ST","pt-TL","qu","qu-BO","qu-EC","qu-PE","rm","rm-CH","rn","rn-BI","ro","ro-MD","ro-RO","rof","rof-TZ","ru","ru-BY","ru-KG","ru-KZ","ru-MD","ru-RU","ru-UA","rw","rw-RW","rwk","rwk-TZ","sah","sah-RU","saq","saq-KE","sbp","sbp-TZ","se","se-FI","se-NO","se-SE","seh","seh-MZ","ses","ses-ML","sg","sg-CF","shi","shi-MA","shi-Tfng","shi-Tfng-MA","si","si-LK","sk","sk-SK","sl","sl-SI","smn","smn-FI","sn","sn-ZW","so","so-DJ","so-ET","so-KE","so-SO","sq","sq-AL","sq-MK","sq-XK","sr","sr-BA","sr-ME","sr-RS","sr-XK","sr-Latn","sr-Latn-BA","sr-Latn-ME","sr-Latn-RS","sr-Latn-XK","sv","sv-AX","sv-FI","sv-SE","sw","sw-CD","sw-KE","sw-TZ","sw-UG","ta","ta-IN","ta-LK","ta-MY","ta-SG","te","te-IN","teo","teo-KE","teo-UG","tg","tg-TJ","th","th-TH","ti","ti-ER","ti-ET","tk","tk-TM","to","to-TO","tr","tr-CY","tr-TR","twq","twq-NE","tzm","tzm-MA","ug","ug-Arab","ug-Arab-CN","uk","uk-UA","ur","ur-IN","ur-PK","uz","uz-Arab","uz-Arab-AF","uz-UZ","uz-Latn","uz-Latn-UZ","vai","vai-Latn","vai-Latn-LR","vai-LR","vi","vi-VN","vun","vun-TZ","wae","wae-CH","xog","xog-UG","yav","yav-CM","yi","yi-001","yo","yo-BJ","yo-NG","zgh","zgh-MA","zh","zh-Hans","zh-Hans-CN","zh-Hans-HK","zh-Hans-MO","zh-Hans-SG","zh-Hant","zh-Hant-HK","zh-Hant-MO","zh-Hant-TW","zu","zu-ZA",
54
+ ],
55
+
56
+ RunLoop::Version.new("8.0") => [
57
+ "af","af-NA","af-ZA","agq","agq-CM","ak","ak-GH","am","am-ET","ar","ar-001","ar-AE","ar-BH","ar-DJ","ar-DZ","ar-EG","ar-EH","ar-ER","ar-IL","ar-IQ","ar-JO","ar-KM","ar-KW","ar-LB","ar-LY","ar-MA","ar-MR","ar-OM","ar-PS","ar-QA","ar-SA","ar-SD","ar-SO","ar-SS","ar-SY","ar-TD","ar-TN","ar-YE","as","as-IN","asa","asa-TZ","az","az-Cyrl","az-Cyrl-AZ","az-AZ","bas","bas-CM","be","be-BY","bem","bem-ZM","bez","bez-TZ","bg","bg-BG","bm","bm-ML","bn","bn-BD","bn-IN","bo","bo-CN","bo-IN","br","br-FR","brx","brx-IN","bs","bs-Cyrl","bs-Cyrl-BA","bs-BA","ca","ca-AD","ca-ES","ca-FR","ca-IT","cgg","cgg-UG","chr","chr-US","ckb","cs","cs-CZ","cy","cy-GB","da","da-DK","da-GL","dav","dav-KE","de","de-AT","de-BE","de-CH","de-DE","de-LI","de-LU","dje","dje-NE","dua","dua-CM","dyo","dyo-SN","dz","dz-BT","ebu","ebu-KE","ee","ee-GH","ee-TG","el","el-CY","el-GR","en","en-001","en-150","en-AD","en-AG","en-AI","en-AL","en-AS","en-AT","en-AU","en-BA","en-BB","en-BE","en-BM","en-BS","en-BW","en-BZ","en-CA","en-CC","en-CH","en-CK","en-CM","en-CX","en-CY","en-CZ","en-DE","en-DG","en-DK","en-DM","en-EE","en-ER","en-ES","en-FI","en-FJ","en-FK","en-FM","en-FR","en-GB","en-GD","en-GG","en-GH","en-GI","en-GM","en-GU","en-GY","en-HK","en-HR","en-HU","en-IE","en-IM","en-IN","en-IO","en-IS","en-IT","en-JE","en-JM","en-KE","en-KI","en-KN","en-KY","en-LC","en-LR","en-LS","en-LT","en-LU","en-LV","en-ME","en-MG","en-MH","en-MO","en-MP","en-MS","en-MT","en-MU","en-MW","en-NA","en-NF","en-NG","en-NL","en-NO","en-NR","en-NU","en-NZ","en-PG","en-PH","en-PK","en-PL","en-PN","en-PR","en-PT","en-PW","en-RO","en-RU","en-RW","en-SB","en-SC","en-SD","en-SE","en-SG","en-SH","en-SI","en-SK","en-SL","en-SS","en-SX","en-SZ","en-TC","en-TK","en-TO","en-TR","en-TT","en-TV","en-TZ","en-UG","en-UM","en-US","en-US-POSIX","en-VC","en-VG","en-VI","en-VU","en-WS","en-ZA","en-ZM","en-ZW","eo","es","es-419","es-AR","es-BO","es-CL","es-CO","es-CR","es-CU","es-DO","es-EA","es-EC","es-ES","es-GQ","es-GT","es-HN","es-IC","es-MX","es-NI","es-PA","es-PE","es-PH","es-PR","es-PY","es-SV","es-US","es-UY","es-VE","et","et-EE","eu","eu-ES","ewo","ewo-CM","fa","fa-AF","fa-IR","ff","ff-SN","fi","fi-FI","fil","fil-PH","fo","fo-FO","fr","fr-BE","fr-BF","fr-BI","fr-BJ","fr-BL","fr-CA","fr-CD","fr-CF","fr-CG","fr-CH","fr-CI","fr-CM","fr-DJ","fr-DZ","fr-FR","fr-GA","fr-GF","fr-GN","fr-GP","fr-GQ","fr-HT","fr-KM","fr-LU","fr-MA","fr-MC","fr-MF","fr-MG","fr-ML","fr-MQ","fr-MR","fr-MU","fr-NC","fr-NE","fr-PF","fr-PM","fr-RE","fr-RW","fr-SC","fr-SN","fr-SY","fr-TD","fr-TG","fr-TN","fr-VU","fr-WF","fr-YT","ga","ga-IE","gl","gl-ES","gsw","gsw-CH","gsw-LI","gu","gu-IN","guz","guz-KE","gv","gv-IM","ha","ha-GH","ha-NE","ha-NG","haw","haw-US","he","he-IL","hi","hi-IN","hr","hr-BA","hr-HR","hu","hu-HU","hy","hy-AM","id","id-ID","ig","ig-NG","ii","ii-CN","is","is-IS","it","it-CH","it-IT","it-SM","iu","iu-Cans","iu-Cans-CA","ja","ja-JP","jgo","jgo-CM","jmc","jmc-TZ","ka","ka-GE","kab","kab-DZ","kam","kam-KE","kde","kde-TZ","kea","kea-CV","khq","khq-ML","ki","ki-KE","kk","kk-KZ","kkj","kkj-CM","kl","kl-GL","kln","kln-KE","km","km-KH","kn","kn-IN","ko","ko-KP","ko-KR","kok","kok-IN","ks","ks-Arab","ks-Arab-IN","ksb","ksb-TZ","ksf","ksf-CM","kw","kw-GB","ky","ky-KG","lag","lag-TZ","lg","lg-UG","lkt","lkt-US","ln","ln-AO","ln-CD","ln-CF","ln-CG","lo","lo-LA","lt","lt-LT","lu","lu-CD","luo","luo-KE","luy","luy-KE","lv","lv-LV","mas","mas-KE","mas-TZ","mer","mer-KE","mfe","mfe-MU","mg","mg-MG","mgh","mgh-MZ","mgo","mgo-CM","mk","mk-MK","ml","ml-IN","mn","mn-MN","mr","mr-IN","ms","ms-Arab","ms-Arab-BN","ms-Arab-MY","ms-BN","ms-MY","ms-SG","mt","mt-MT","mua","mua-CM","my","my-MM","naq","naq-NA","nb","nb-NO","nb-SJ","nd","nd-ZW","ne","ne-IN","ne-NP","nl","nl-AW","nl-BE","nl-BQ","nl-CW","nl-NL","nl-SR","nl-SX","nmg","nmg-CM","nn","nn-NO","nnh","nnh-CM","nus","nus-SD","nyn","nyn-UG","om","om-ET","om-KE","or","or-IN","pa","pa-Arab","pa-Arab-PK","pa-IN","pl","pl-PL","ps","ps-AF","pt","pt-AO","pt-BR","pt-CV","pt-GW","pt-MO","pt-MZ","pt-PT","pt-ST","pt-TL","rm","rm-CH","rn","rn-BI","ro","ro-MD","ro-RO","rof","rof-TZ","ru","ru-BY","ru-KG","ru-KZ","ru-MD","ru-RU","ru-UA","rw","rw-RW","rwk","rwk-TZ","saq","saq-KE","sbp","sbp-TZ","seh","seh-MZ","ses","ses-ML","sg","sg-CF","shi","shi-MA","shi-Tfng","shi-Tfng-MA","si","si-LK","sk","sk-SK","sl","sl-SI","sn","sn-ZW","so","so-DJ","so-ET","so-KE","so-SO","sq","sq-AL","sq-MK","sq-XK","sr","sr-BA","sr-ME","sr-RS","sr-XK","sr-Latn","sr-Latn-BA","sr-Latn-ME","sr-Latn-RS","sr-Latn-XK","sv","sv-AX","sv-FI","sv-SE","sw","sw-KE","sw-TZ","sw-UG","swc","swc-CD","ta","ta-IN","ta-LK","ta-MY","ta-SG","te","te-IN","teo","teo-KE","teo-UG","tg","tg-TJ","th","th-TH","ti","ti-ER","ti-ET","tk","tk-TM","to","to-TO","tr","tr-CY","tr-TR","twq","twq-NE","tzm","tzm-MA","ug","ug-Arab","ug-Arab-CN","uk","uk-UA","ur","ur-IN","ur-PK","uz","uz-Arab","uz-Arab-AF","uz-UZ","uz-Latn","uz-Latn-UZ","vai","vai-Latn","vai-Latn-LR","vai-LR","vi","vi-VN","vun","vun-TZ","xog","xog-UG","yav","yav-CM","yo","yo-BJ","yo-NG","zgh","zgh-MA","zh","zh-Hans","zh-Hans-CN","zh-Hans-HK","zh-Hans-MO","zh-Hans-SG","zh-Hant","zh-Hant-HK","zh-Hant-MO","zh-Hant-TW","zu","zu-ZA",
58
+ ]
59
+ }.freeze
60
+
61
+ end
62
+ end
63
+
@@ -0,0 +1,132 @@
1
+ require 'open3'
2
+
3
+ module RunLoop
4
+
5
+ # An error class for signaling an incompatible architecture.
6
+ class IncompatibleArchitecture < StandardError
7
+ end
8
+
9
+ # A class for interacting with the lipo command-line tool to verify that an
10
+ # executable is valid for the test target (device or simulator).
11
+ #
12
+ # @note All lipo commands are run in the context of `xcrun`.
13
+ class Lipo
14
+
15
+ # The path to the application bundle we are inspecting.
16
+ # @!attribute [wr] bundle_path
17
+ # @return [String] The path to the application bundle (.app).
18
+ attr_accessor :bundle_path
19
+
20
+ def initialize(bundle_path)
21
+ @bundle_path = bundle_path
22
+ @plist_buddy = RunLoop::PlistBuddy.new
23
+ end
24
+
25
+ # @!visibility private
26
+ def to_s
27
+ "#<Lipo #{bundle_path}>"
28
+ end
29
+
30
+ # @!visibility private
31
+ def inspect
32
+ to_s
33
+ end
34
+
35
+ # Inspect the `CFBundleExecutable` in the app bundle path with `lipo` and
36
+ # compare the result with the target device's instruction set.
37
+ #
38
+ # **Simulators**
39
+ #
40
+ # If the target is a simulator and the binary contains an i386 slice, the
41
+ # app will launch on the 64-bit simulators.
42
+ #
43
+ # If the target is a simulator and the binary contains _only_ an x86_64
44
+ # slice, the app will not launch on these simulators:
45
+ #
46
+ # ```
47
+ # iPhone 4S, iPad 2, iPhone 5, and iPad Retina.
48
+ # ```
49
+ #
50
+ # All other simulators are 64-bit.
51
+ #
52
+ # **Devices**
53
+ #
54
+ # @see {https://www.innerfence.com/howto/apple-ios-devices-dates-versions-instruction-sets}
55
+ #
56
+ # ```
57
+ # armv7 <== 3gs, 4s, iPad 2, iPad mini, iPad 3, iPod 3, iPod 4, iPod 5
58
+ # armv7s <== 5, 5c, iPad 4
59
+ # arm64 <== 5s, 6, 6 Plus, Air, Air 2, iPad Mini Retina, iPad Mini 3
60
+ # ```
61
+ #
62
+ # @note At the moment, we are focusing on simulator compatibility. Since we
63
+ # don't have an automated way of installing an .ipa on local device, we
64
+ # don't require an .ipa path. Without an .ipa path, we cannot verify the
65
+ # architectures. Further, we would need to adopt a third-party tool like
66
+ # ideviceinfo to find the target device's instruction set.
67
+ # @param [RunLoop::Device] device The test target.
68
+ # @raise [RuntimeError] Raises an error if the device is a physical device.
69
+ # @raise [RunLoop::IncompatibleArchitecture] Raises an error if the instruction set of the target
70
+ # device is not compatible with the executable in the application.
71
+ def expect_compatible_arch(device)
72
+ if device.physical_device?
73
+ raise 'Ensuring compatible arches for physical devices is NYI'
74
+ else
75
+ arches = self.info
76
+ # An i386 binary will run on any simulator.
77
+ return true if arches.include?('i386')
78
+
79
+ instruction_set = device.instruction_set
80
+ unless arches.include?(instruction_set)
81
+ raise RunLoop::IncompatibleArchitecture,
82
+ ['Binary at:',
83
+ binary_path,
84
+ 'does not contain a compatible architecture for target device.',
85
+ "Expected '#{instruction_set}' but found #{arches}."].join("\n")
86
+ end
87
+ end
88
+ end
89
+
90
+ # Returns a list of architecture in the binary.
91
+ # @return [Array<String>] A list of architecture.
92
+ # @raise [RuntimeError] If the output of lipo cannot be parsed.
93
+ def info
94
+ execute_lipo("-info \"#{binary_path}\"") do |stdout, stderr, wait_thr|
95
+ output = stdout.read.strip
96
+ begin
97
+ output.split(':')[-1].strip.split
98
+ rescue StandardError => e
99
+ msg = ['Expected to be able to parse the output of lipo.',
100
+ "cmd: 'lipo -info \"#{binary_path}\"'",
101
+ "stdout: '#{output}'",
102
+ "stderr: '#{stderr.read.strip}'",
103
+ "exit code: '#{wait_thr.value}'",
104
+ e.message]
105
+ raise msg.join("\n")
106
+ end
107
+ end
108
+ end
109
+
110
+ private
111
+
112
+ # Caller is responsible for correctly escaping arguments.
113
+ # For example, the caller must proper quote `"` paths to avoid errors
114
+ # when dealing with paths that contain spaces.
115
+ # @todo #execute_lipo should take an [] of arguments
116
+ def execute_lipo(argument)
117
+ command = "xcrun lipo #{argument}"
118
+ Open3.popen3(command) do |_, stdout, stderr, wait_thr|
119
+ yield stdout, stderr, wait_thr
120
+ end
121
+ end
122
+
123
+ def plist_path
124
+ File.join(@bundle_path, 'Info.plist');
125
+ end
126
+
127
+ def binary_path
128
+ binary_relative_path = @plist_buddy.plist_read('CFBundleExecutable', plist_path)
129
+ File.join(@bundle_path, binary_relative_path)
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,52 @@
1
+ module RunLoop
2
+
3
+ # A class for interacting with the lldb command-line tool
4
+ class LLDB
5
+
6
+ # Returns a list of lldb pids.
7
+ # @return [Array<Integer>] An array of integer pids.
8
+ def self.lldb_pids
9
+ ps_output = `#{LLDB_FIND_PIDS_CMD}`.strip
10
+ lines = ps_output.lines("\n").map { |line| line.strip }
11
+ lldb_processes = lines.select { |line| self.is_lldb_process?(line) }
12
+ lldb_processes.map do |ps_description|
13
+ tokens = ps_description.strip.split(' ').map { |token| token.strip }
14
+ pid = tokens.fetch(0, nil)
15
+ if pid.nil?
16
+ nil
17
+ else
18
+ pid.to_i
19
+ end
20
+ end.compact.sort
21
+ end
22
+
23
+ # @!visibility private
24
+ # Is the process described an lldb process?
25
+ #
26
+ # @param [String] ps_details Details about a process as returned by `ps`
27
+ # @return [Boolean] True if the details describe an lldb process.
28
+ def self.is_lldb_process?(ps_details)
29
+ return false if ps_details.nil?
30
+ ps_details[/Contents\/Developer\/usr\/bin\/lldb/, 0] != nil
31
+ end
32
+
33
+ # Attempts to gracefully kill all running lldb processes.
34
+ def self.kill_lldb_processes
35
+ self.lldb_pids.each do |pid|
36
+ self.kill_with_signal(pid, 'KILL')
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ # @!visibility private
43
+ LLDB_FIND_PIDS_CMD = 'ps x -o pid,command | grep -v grep | grep lldb'
44
+
45
+ # @!visibility private
46
+ def self.kill_with_signal(pid, signal)
47
+ options = {:timeout => 1.0, :delay => 0.1}
48
+ RunLoop::ProcessTerminator.new(pid, signal, 'lldb', options).kill_process
49
+ end
50
+
51
+ end
52
+ end