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,160 @@
1
+ require 'thor'
2
+ require 'run_loop'
3
+ require 'run_loop/cli/errors'
4
+
5
+ module RunLoop
6
+ module CLI
7
+ class Instruments < Thor
8
+
9
+ attr_accessor :signal
10
+
11
+ desc 'quit', 'Send a kill signal to all instruments processes.'
12
+
13
+ method_option 'signal',
14
+ :desc => 'The kill signal to send.',
15
+ :aliases => '-s',
16
+ :required => false,
17
+ :default => 'TERM',
18
+ :type => :string
19
+
20
+ method_option 'debug',
21
+ :desc => 'Enable debug logging.',
22
+ :aliases => '-v',
23
+ :required => false,
24
+ :default => false,
25
+ :type => :boolean
26
+
27
+
28
+ def quit
29
+ signal = options[:signal]
30
+ ENV['DEBUG'] = '1' if options[:debug]
31
+ instruments = RunLoop::Instruments.new
32
+ instruments.instruments_pids.each do |pid|
33
+ terminator = RunLoop::ProcessTerminator.new(pid, signal, 'instruments')
34
+ unless terminator.kill_process
35
+ terminator = RunLoop::ProcessTerminator.new(pid, 'KILL', 'instruments')
36
+ terminator.kill_process
37
+ end
38
+ end
39
+ end
40
+
41
+
42
+ desc 'launch [--app | [--ipa | --bundle-id]] [OPTIONS]', 'Launch an app with instruments.'
43
+
44
+ # This is the description we want, but Thor doesn't handle newlines well(?).
45
+ # long_desc <<EOF
46
+ # # Launch App.app on a simulator.
47
+ # $ be run-loop instruments launch --app /path/to/App.app
48
+ #
49
+ # # Launch App.ipa on a device; bundle id will be extracted.
50
+ # $ be run-loop instruments launch --ipa /path/to/App.ipa
51
+ #
52
+ # # Launch the app with bundle id on a device.
53
+ # $ be run-loop instruments launch --bundle-id com.example.MyApp-cal
54
+ #
55
+ # You can pass arguments to application as a comma separated list.
56
+ # --args -NSShowNonLocalizedStrings,YES,-AppleLanguages,(de)
57
+ # --args -com.apple.CoreData.SQLDebug,3'
58
+ # EOF
59
+
60
+ method_option 'device',
61
+ :desc => 'The device UDID or simulator identifier.',
62
+ :aliases => '-d',
63
+ :required => false,
64
+ :type => :string
65
+
66
+ method_option 'app',
67
+ :desc => 'Path to a .app bundle to launch on simulator.',
68
+ :aliases => '-a',
69
+ :required => false,
70
+ :type => :string
71
+
72
+ method_option 'bundle-id',
73
+ :desc => 'Bundle id of app to launch on device.',
74
+ :aliases => '-b',
75
+ :required => false,
76
+ :type => :string
77
+
78
+ method_option 'template',
79
+ :desc => 'Path to an automation template.',
80
+ :aliases => '-t',
81
+ :required => false,
82
+ :type => :string
83
+
84
+ method_option 'args',
85
+ :desc => 'Arguments to pass to the app.',
86
+ :required => false,
87
+ :type => :string
88
+
89
+ method_option 'debug',
90
+ :desc => 'Enable debug logging.',
91
+ :aliases => '-v',
92
+ :required => false,
93
+ :default => false,
94
+ :type => :boolean
95
+
96
+ def launch
97
+
98
+ debug = options[:debug]
99
+ original_value = ENV['DEBUG']
100
+
101
+ ENV['DEBUG'] = '1' if debug
102
+
103
+ begin
104
+ launch_options = {
105
+ :args => parse_app_launch_args(options),
106
+ :udid => detect_device_udid_from_options(options),
107
+ :app => detect_bundle_id_or_bundle_path(options)
108
+ }
109
+ run_loop = RunLoop.run(launch_options)
110
+ puts JSON.generate(run_loop)
111
+ ensure
112
+ ENV['DEBUG'] = original_value if debug
113
+ end
114
+ end
115
+
116
+ no_commands do
117
+ def parse_app_launch_args(options)
118
+ args = options[:args]
119
+ if args.nil?
120
+ []
121
+ else
122
+ args.split(',')
123
+ end
124
+ end
125
+
126
+ def detect_bundle_id_or_bundle_path(options)
127
+ app = options[:app]
128
+ ipa = options[:ipa]
129
+ bundle_id = options[:bundle_id]
130
+
131
+ if app && ipa
132
+ raise RunLoop::CLI::ValidationError,
133
+ "--app #{app} and --ipa #{ipa} are mutually exclusive arguments. Pass one or the other, not both."
134
+ end
135
+
136
+ if app && bundle_id
137
+ raise RunLoop::CLI::ValidationError,
138
+ "--app #{app} and --bundle-id #{bundle_id} are mutually exclusive arguments. Pass one or the other, not both."
139
+ end
140
+
141
+ if ipa && bundle_id
142
+ raise RunLoop::CLI::ValidationError,
143
+ "--ipa #{ipa} and --bundle-id #{bundle_id} are mutually exclusive arguments. Pass one or the other, not both."
144
+ end
145
+ app || bundle_id
146
+ end
147
+
148
+ def detect_device_udid_from_options(options)
149
+ device = options[:device]
150
+ app = options[:app]
151
+ if app && !device
152
+ RunLoop::Core.default_simulator
153
+ else
154
+ device
155
+ end
156
+ end
157
+ end
158
+ end
159
+ end
160
+ end
@@ -0,0 +1,31 @@
1
+ require "thor"
2
+ require "run_loop"
3
+ require "run_loop/cli/errors"
4
+
5
+ module RunLoop
6
+ module CLI
7
+ class Locale < Thor
8
+
9
+ desc "print-alert-regexes", "Print privacy alert regular expressions"
10
+
11
+ def print_alert_regexes
12
+ dir = File.expand_path(File.dirname(__FILE__))
13
+ scripts_dir = File.join(dir, "..", "..", "..", "scripts")
14
+ on_alert = File.join(scripts_dir, "lib", "on_alert.js")
15
+
16
+ lines = []
17
+ File.read(on_alert).force_encoding("UTF-8").split($-0).each do |line|
18
+ if line[/\[\".+\", \/.+\/\]/, 0]
19
+ line.chomp!
20
+ if line[-1,1] == ","
21
+ line = line[0, line.length - 1]
22
+ end
23
+ lines << line
24
+ end
25
+ end
26
+
27
+ puts lines.join(",#{$-0}")
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,257 @@
1
+ require 'thor'
2
+ require 'run_loop'
3
+ require 'run_loop/cli/errors'
4
+
5
+ module RunLoop
6
+ module CLI
7
+ class Simctl < Thor
8
+
9
+ attr_reader :simctl
10
+
11
+ desc 'tail', 'Tail the log file of the booted simulator'
12
+ def tail
13
+ tail_booted
14
+ end
15
+
16
+ no_commands do
17
+ def tail_booted
18
+ device = booted_device
19
+ if device.nil?
20
+ version = xcode.version
21
+ puts "No simulator for active Xcode (version #{version}) is booted."
22
+ else
23
+ log_file = device.simulator_log_file_path
24
+ exec('tail', *['-F', log_file])
25
+ end
26
+ end
27
+ end
28
+
29
+ desc 'booted', 'Prints details about the booted simulator'
30
+ def booted
31
+ device = booted_device
32
+ if device.nil?
33
+ version = xcode.version
34
+ puts "No simulator for active Xcode (version #{version}) is booted."
35
+ else
36
+ puts device
37
+ end
38
+ end
39
+
40
+ desc 'doctor', 'EXPERIMENTAL: Prepare the CoreSimulator environment for testing'
41
+
42
+ method_option 'debug',
43
+ :desc => 'Enable debug logging.',
44
+ :aliases => '-v',
45
+ :required => false,
46
+ :default => false,
47
+ :type => :boolean
48
+
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
+ manage_processes
60
+
61
+ if device
62
+ RunLoop::Environment.with_debugging(debug) do
63
+ RunLoop::CoreSimulator.erase(device)
64
+ launch_simulator(device, xcode)
65
+ end
66
+ else
67
+ RunLoop::Environment.with_debugging(debug) do
68
+ erase_and_launch_each_simulator
69
+ end
70
+ end
71
+
72
+ end
73
+
74
+ no_commands do
75
+ def erase_and_launch_each_simulator
76
+ simctl.simulators.each do |simulator|
77
+ RunLoop::CoreSimulator.erase(simulator)
78
+ launch_simulator(simulator, xcode)
79
+ end
80
+ end
81
+
82
+ def launch_simulator(simulator, xcode)
83
+ core_sim = RunLoop::CoreSimulator.new(simulator, nil,
84
+ {:xcode => xcode})
85
+ core_sim.launch_simulator
86
+ end
87
+ end
88
+
89
+ desc 'manage-processes', 'Manage CoreSimulator processes by quiting stale processes'
90
+
91
+ method_option 'debug',
92
+ :desc => 'Enable debug logging.',
93
+ :aliases => '-v',
94
+ :required => false,
95
+ :default => false,
96
+ :type => :boolean
97
+
98
+ def manage_processes
99
+ debug = options[:debug]
100
+ original_value = ENV['DEBUG']
101
+
102
+ ENV['DEBUG'] = '1' if debug
103
+
104
+ begin
105
+ RunLoop::CoreSimulator.terminate_core_simulator_processes
106
+ process_name = "com.apple.CoreSimulator.CoreSimulatorService"
107
+ RunLoop::ProcessWaiter.new(process_name).pids.each do |pid|
108
+ kill_options = { :timeout => 0.5 }
109
+ RunLoop::ProcessTerminator.new(pid, 'KILL', process_name, kill_options)
110
+ end
111
+ ensure
112
+ ENV['DEBUG'] = original_value if debug
113
+ end
114
+ end
115
+
116
+ no_commands do
117
+ def simctl
118
+ @simctl ||= RunLoop::Simctl.new
119
+ end
120
+
121
+ def xcode
122
+ @xcode ||= RunLoop::Xcode.new
123
+ end
124
+
125
+ def xcrun
126
+ @xcrun ||= RunLoop::Xcrun.new
127
+ end
128
+
129
+ def booted_device
130
+ simctl.simulators.detect(nil) do |device|
131
+ device.state == 'Booted'
132
+ end
133
+ end
134
+ end
135
+
136
+ desc 'install --app [OPTIONS]', 'Installs an app on a device.'
137
+
138
+ method_option 'app',
139
+ :desc => 'Path to a .app bundle to launch on simulator.',
140
+ :aliases => '-a',
141
+ :required => true,
142
+ :type => :string
143
+
144
+ method_option 'device',
145
+ :desc => 'The simulator UDID or name.',
146
+ :aliases => '-d',
147
+ :required => false,
148
+ :type => :string
149
+
150
+ method_option 'debug',
151
+ :desc => 'Enable debug logging.',
152
+ :aliases => '-v',
153
+ :required => false,
154
+ :default => false,
155
+ :type => :boolean
156
+
157
+ method_option 'reset-app-sandbox',
158
+ :desc => 'If the app is already installed, erase the app data.',
159
+ :aliases => '-r',
160
+ :default => false,
161
+ :type => :boolean
162
+
163
+ method_option 'force',
164
+ :desc => 'Force a re-install the existing app. Deprecated 1.5.6.',
165
+ :aliases => '-f',
166
+ :required => false,
167
+ :default => false,
168
+ :type => :boolean
169
+
170
+ def install
171
+ debug = options[:debug]
172
+
173
+ device = expect_device(options)
174
+ app = expect_app(options, device)
175
+
176
+ core_sim = RunLoop::CoreSimulator.new(device, app)
177
+
178
+ RunLoop::Environment.with_debugging(debug) do
179
+ if options['reset-app-sandbox']
180
+
181
+ if core_sim.app_is_installed?
182
+ RunLoop.log_debug('Resetting the app sandbox')
183
+ core_sim.uninstall_app_and_sandbox
184
+ else
185
+ RunLoop.log_debug('App is not installed; skipping sandbox reset')
186
+ end
187
+ end
188
+ core_sim.install
189
+ end
190
+ end
191
+
192
+ no_commands do
193
+ def expect_device(options)
194
+ device_from_options = options[:device]
195
+ simulators = simctl.simulators
196
+ if device_from_options.nil?
197
+ default_name = RunLoop::Core.default_simulator
198
+ device = simulators.find do |sim|
199
+ sim.instruments_identifier(xcode) == default_name
200
+ end
201
+
202
+ if device.nil?
203
+ raise RunLoop::CLI::ValidationError,
204
+ "Could not find a simulator with name that matches '#{device_from_options}'"
205
+ end
206
+ else
207
+ device = simulators.find do |sim|
208
+ sim.udid == device_from_options ||
209
+ sim.instruments_identifier(xcode) == device_from_options
210
+ end
211
+
212
+ if device.nil?
213
+ raise RunLoop::CLI::ValidationError,
214
+ "Could not find a simulator with name or UDID that matches '#{device_from_options}'"
215
+ end
216
+ end
217
+ device
218
+ end
219
+
220
+ def expect_app(options, device_obj)
221
+ app_bundle_path = options[:app]
222
+ unless File.exist?(app_bundle_path)
223
+ raise RunLoop::CLI::ValidationError, "Expected '#{app_bundle_path}' to exist."
224
+ end
225
+
226
+ unless File.directory?(app_bundle_path)
227
+ raise RunLoop::CLI::ValidationError,
228
+ "Expected '#{app_bundle_path}' to be a directory."
229
+ end
230
+
231
+ unless File.extname(app_bundle_path) == '.app'
232
+ raise RunLoop::CLI::ValidationError,
233
+ "Expected '#{app_bundle_path}' to end in .app."
234
+ end
235
+
236
+ app = RunLoop::App.new(app_bundle_path)
237
+
238
+ begin
239
+ app.bundle_identifier
240
+ app.executable_name
241
+ rescue RuntimeError => e
242
+ raise RunLoop::CLI::ValidationError, e.message
243
+ end
244
+
245
+ lipo = RunLoop::Lipo.new(app.path)
246
+ begin
247
+ lipo.expect_compatible_arch(device_obj)
248
+ rescue RunLoop::IncompatibleArchitecture => e
249
+ raise RunLoop::CLI::ValidationError, e.message
250
+ end
251
+
252
+ app
253
+ end
254
+ end
255
+ end
256
+ end
257
+ end
@@ -0,0 +1,139 @@
1
+ require "thor"
2
+ require "run_loop"
3
+ require "run_loop/cli/errors"
4
+
5
+ module RunLoop
6
+ module CLI
7
+ class TCC < Thor
8
+
9
+ desc "services", "Print known services"
10
+
11
+ def services
12
+ RunLoop::TCC::PRIVACY_SERVICES.each do |key, _|
13
+ puts key
14
+ end
15
+ end
16
+
17
+ desc "open", "Open the TCC.db of a device in an editor EXPERIMENTAL"
18
+
19
+ method_option "device",
20
+ :desc => "Device name or identifier.",
21
+ :aliases => "-d",
22
+ :required => true,
23
+ :type => :string
24
+
25
+ def open
26
+ device = expect_device(options)
27
+
28
+ tcc_db = device.simulator_tcc_db
29
+
30
+ return false if tcc_db.nil?
31
+
32
+ args = ['open', tcc_db]
33
+
34
+ pid = Process.spawn(*args)
35
+ Process.detach(pid)
36
+ pid
37
+ end
38
+
39
+ desc "allow", "Prevent a Privacy Alert from appearing (Sim only)"
40
+
41
+ method_option "device",
42
+ :desc => "Device name or identifier. If undefined, operation will be on all devices",
43
+ :aliases => "-d",
44
+ :required => false,
45
+ :type => :string
46
+
47
+ method_option "app",
48
+ :desc => "App bundle id to allow service on",
49
+ :aliases => "-a",
50
+ :required => true,
51
+ :type => :string
52
+
53
+ method_option "service",
54
+ :desc => "Service to allow. If undefined, all known services will be allowed",
55
+ :aliases => "-s",
56
+ :required => false,
57
+ :type => :string
58
+
59
+ method_option 'debug',
60
+ :desc => 'Enable debug logging.',
61
+ :aliases => '-v',
62
+ :required => false,
63
+ :default => false,
64
+ :type => :boolean
65
+
66
+ def allow
67
+ debug = options[:debug]
68
+
69
+ device = options[:device]
70
+ if device
71
+ devices = [expect_device(options)]
72
+ else
73
+ devices = sim_control.simulators
74
+ end
75
+
76
+ service = options[:service]
77
+
78
+ if service
79
+ services = [service]
80
+ else
81
+ services = RunLoop::TCC::PRIVACY_SERVICES.map do |key, _|
82
+ key
83
+ end
84
+ end
85
+
86
+ app = options[:app]
87
+
88
+ RunLoop::Environment.with_debugging(debug) do
89
+ devices.each do |_device|
90
+ tcc = RunLoop::TCC.new(_device, app)
91
+ services.each do |_service|
92
+ tcc.allow_service(_service)
93
+ end
94
+ end
95
+ end
96
+ true
97
+ end
98
+
99
+ no_commands do
100
+ def expect_device(options)
101
+ device_from_options = options[:device]
102
+ simulators = sim_control.simulators
103
+ if device_from_options.nil?
104
+ default_name = RunLoop::Core.default_simulator
105
+ device = simulators.find do |sim|
106
+ sim.instruments_identifier(xcode) == default_name
107
+ end
108
+
109
+ if device.nil?
110
+ raise RunLoop::CLI::ValidationError,
111
+ "Could not find a simulator with name that matches '#{device_from_options}'"
112
+ end
113
+ else
114
+ device = simulators.find do |sim|
115
+ sim.udid == device_from_options ||
116
+ sim.instruments_identifier(xcode) == device_from_options
117
+ end
118
+
119
+ if device.nil?
120
+ raise RunLoop::CLI::ValidationError,
121
+ "Could not find a simulator with name or UDID that matches '#{device_from_options}'"
122
+ end
123
+ end
124
+ device
125
+ end
126
+
127
+ def sim_control
128
+ @sim_control ||= RunLoop::SimControl.new
129
+ end
130
+
131
+ def xcode
132
+ @xcode ||= RunLoop::Xcode.new
133
+ end
134
+ end
135
+
136
+ end
137
+ end
138
+ end
139
+
@@ -0,0 +1,76 @@
1
+ module RunLoop
2
+ # @!visibility private
3
+ # A wrapper around codesign command line tool
4
+ class Codesign
5
+
6
+ # @!visibility private
7
+ DEV_REGEX = /Authority=iPhone Developer:/
8
+
9
+ # @!visibility private
10
+ APP_STORE_REGEX = /Authority=Apple iPhone OS Application Signing/
11
+
12
+ # @!visibility private
13
+ DISTR_REGEX = /Authority=iPhone Distribution:/
14
+
15
+ # @!visibility private
16
+ NOT_SIGNED_REGEX = /code object is not signed at all/
17
+
18
+ # @!visibility private
19
+ def self.info(path)
20
+ self.expect_path_exists(path)
21
+ self.run_codesign_command(["--display", "--verbose=4", path])
22
+ end
23
+
24
+ # @!visibility private
25
+ #
26
+ # True if the asset is signed.
27
+ def self.signed?(path)
28
+ info = self.info(path)
29
+ info[NOT_SIGNED_REGEX, 0] == nil
30
+ end
31
+
32
+ # @!visibility private
33
+ #
34
+ # True if the asset is signed with anything other than a dev cert.
35
+ def self.distribution?(path)
36
+ info = self.info(path)
37
+
38
+ info[NOT_SIGNED_REGEX, 0] == nil &&
39
+ info[DEV_REGEX, 0] == nil
40
+ end
41
+
42
+ # @!visibility private
43
+ #
44
+ # True if the asset is signed with a dev cert
45
+ def self.developer?(path)
46
+ info = self.info(path)
47
+ info[DEV_REGEX, 0] != nil
48
+ end
49
+
50
+ private
51
+
52
+ def self.expect_path_exists(path)
53
+ if !File.exist?(path)
54
+ raise ArgumentError,
55
+ %Q{There is no file or directory at path:
56
+
57
+ #{path}
58
+ }
59
+ end
60
+ end
61
+
62
+ def self.run_codesign_command(args)
63
+ if !args.is_a?(Array)
64
+ raise ArgumentError, "Expected args: '#{args}' to be an Array"
65
+ end
66
+
67
+ xcrun = RunLoop::Xcrun.new
68
+ cmd = ["codesign"] + args
69
+ options = {:log_cmd => true}
70
+ hash = xcrun.run_command_in_context(cmd, options)
71
+
72
+ hash[:out]
73
+ end
74
+ end
75
+ end
76
+