run_loop 1.2.9 → 1.3.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2231305525deb7ff8eef39cab42f66a592e0618d
4
- data.tar.gz: e02a550f4dfd50652a406e75ec7f8b5075393c7b
3
+ metadata.gz: 0a05a75fc51c334a7120e7d0930c4cb673302138
4
+ data.tar.gz: 17cd820907c0d174cc81ad7ff02f9a3b172198d9
5
5
  SHA512:
6
- metadata.gz: f2e693f21f81754350213e4e331d5c400639d59ce135b1c63419f1e6cc585bbdf1af916b09f49ae83bee725b5b6b62ff911a9bfc26541d1ebffc23eb0e1598f4
7
- data.tar.gz: 11c87e9d511a1e1ece647b493a24c604c0916d50f302166d80dbc126d92aa70b42eb1c7078ae90beaa0e1354c62c8b93d03cf59d08dbb4b8c75e5735bdf49615
6
+ metadata.gz: 198b2bd5e060074724dca694de25d4121ca42d7fca592118713798dff2374703c087f74c196b48a7d179babccabbc47e6cf6720452e19cbff85571227012cd90
7
+ data.tar.gz: 87e39e777923cb401a38a165654180ca5d9e5809e86f3fa3f17c591fc16246b4b3c501855f8f444074e625ec6b5beae23a3e9223c8e557442f6ce66d1411f8ed
data/bin/run-loop ADDED
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+ require 'run_loop/cli/cli'
3
+ require 'run_loop/cli/errors'
4
+ require 'run_loop/environment'
5
+
6
+ begin
7
+ RunLoop::CLI::Tool.start
8
+ exit 0
9
+ rescue RunLoop::CLI::ValidationError, Thor::RequiredArgumentMissingError, Thor::UndefinedCommandError => e
10
+ puts e.message
11
+ exit 64
12
+ rescue Thor::Error => e
13
+ puts e.message
14
+ if RunLoop::Environment.debug?
15
+ puts e.backtrace.join("\n") if e.backtrace
16
+ p e.class
17
+ end
18
+ exit 70
19
+ end
data/lib/run_loop.rb CHANGED
@@ -15,7 +15,8 @@ require 'run_loop/device'
15
15
  require 'run_loop/instruments'
16
16
  require 'run_loop/lipo'
17
17
  require 'run_loop/host_cache'
18
- require 'run_loop/monkey_patch'
18
+ require 'run_loop/patches/awesome_print'
19
+ require 'run_loop/patches/retriable'
19
20
  require 'run_loop/simctl/bridge'
20
21
 
21
22
  module RunLoop
@@ -0,0 +1,32 @@
1
+ require 'thor'
2
+ require 'run_loop'
3
+ require 'run_loop/cli/errors'
4
+ require 'run_loop/cli/instruments'
5
+
6
+ trap 'SIGINT' do
7
+ puts 'Trapped SIGINT - exiting'
8
+ exit 10
9
+ end
10
+
11
+ module RunLoop
12
+
13
+ module CLI
14
+
15
+ class Tool < Thor
16
+ include Thor::Actions
17
+
18
+ def self.exit_on_failure?
19
+ true
20
+ end
21
+
22
+ desc 'version', 'Prints version of the run_loop gem'
23
+ def version
24
+ puts RunLoop::VERSION
25
+ end
26
+
27
+ desc 'instruments', "Interact with Xcode's command-line instruments"
28
+ subcommand 'instruments', RunLoop::CLI::Instruments
29
+
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,11 @@
1
+ require 'thor'
2
+
3
+ module RunLoop
4
+ module CLI
5
+ class ValidationError < Thor::InvocationError
6
+ end
7
+
8
+ class NotImplementedError < Thor::InvocationError
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,150 @@
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 'instruments 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 'instruments 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
+ launch_options = {
98
+ :args => parse_app_launch_args(options),
99
+ :udid => detect_device_udid_from_options(options),
100
+ :bundle_dir_or_bundle_id => detect_bundle_id_or_bundle_path(options)
101
+ }
102
+ run_loop = RunLoop.run(launch_options)
103
+ puts JSON.generate(run_loop)
104
+ end
105
+
106
+ no_commands do
107
+ def parse_app_launch_args(options)
108
+ args = options[:args]
109
+ if args.nil?
110
+ []
111
+ else
112
+ args.split(',')
113
+ end
114
+ end
115
+
116
+ def detect_bundle_id_or_bundle_path(options)
117
+ app = options[:app]
118
+ ipa = options[:ipa]
119
+ bundle_id = options[:bundle_id]
120
+
121
+ if app && ipa
122
+ raise RunLoop::CLI::ValidationError,
123
+ "--app #{app} and --ipa #{ipa} are mutually exclusive arguments. Pass one or the other, not both."
124
+ end
125
+
126
+ if app && bundle_id
127
+ raise RunLoop::CLI::ValidationError,
128
+ "--app #{app} and --bundle-id #{bundle_id} are mutually exclusive arguments. Pass one or the other, not both."
129
+ end
130
+
131
+ if ipa && bundle_id
132
+ raise RunLoop::CLI::ValidationError,
133
+ "--ipa #{ipa} and --bundle-id #{bundle_id} are mutually exclusive arguments. Pass one or the other, not both."
134
+ end
135
+ app || bundle_id
136
+ end
137
+
138
+ def detect_device_udid_from_options(options)
139
+ device = options[:device]
140
+ app = options[:app]
141
+ if app && !device
142
+ RunLoop::Core.default_simulator
143
+ else
144
+ device
145
+ end
146
+ end
147
+ end
148
+ end
149
+ end
150
+ end
data/lib/run_loop/core.rb CHANGED
@@ -177,8 +177,13 @@ module RunLoop
177
177
  file.puts code
178
178
  end
179
179
 
180
- # Compute udid and bundle_dir / bundle_id from options and target depending on Xcode version
181
- udid, bundle_dir_or_bundle_id = self.udid_and_bundle_for_launcher(device_target, options, sim_control)
180
+ udid = options[:udid]
181
+ bundle_dir_or_bundle_id = options[:bundle_dir_or_bundle_id]
182
+
183
+ if !(udid && bundle_dir_or_bundle_id)
184
+ # Compute udid and bundle_dir / bundle_id from options and target depending on Xcode version
185
+ udid, bundle_dir_or_bundle_id = self.udid_and_bundle_for_launcher(device_target, options, sim_control)
186
+ end
182
187
 
183
188
  args = options.fetch(:args, [])
184
189
 
@@ -79,7 +79,10 @@ module RunLoop
79
79
  end
80
80
 
81
81
  def retriable_inject_dylib(options={})
82
- merged_options = RETRIABLE_OPTIONS.merge(options)
82
+ default_options = {:tries => 3,
83
+ :interval => 10,
84
+ :timeout => 10}
85
+ merged_options = default_options.merge(options)
83
86
 
84
87
  debug_logging = RunLoop::Environment.debug?
85
88
 
@@ -89,37 +92,25 @@ module RunLoop
89
92
  if elapsed_time && next_interval
90
93
  puts "LLDB: attempt #{try} failed in '#{elapsed_time}'; will retry in '#{next_interval}'"
91
94
  else
92
- puts "LLDB: attempt #{try} failed; will retry in '#{merged_options[:interval]}'"
95
+ puts "LLDB: attempt #{try} failed; will retry in #{merged_options[:interval]}"
93
96
  end
94
97
  end
95
98
  RunLoop::LLDB.kill_lldb_processes
96
99
  RunLoop::ProcessWaiter.new('lldb').wait_for_none
97
100
  end
98
101
 
99
- # For some reason, :timeout does not work here - the lldb process can
100
- # hang indefinitely. Seems to work when
101
- Retriable.retriable({:tries => merged_options[:retries],
102
- # Retriable 2.0
103
- :interval => merged_options[:interval],
104
- :base_interval => merged_options[:interval],
105
- :on_retry => on_retry}) do
106
- #unless inject_dylib_with_timeout merged_options[:timeout]
102
+ tries = merged_options[:tries]
103
+ interval = merged_options[:interval]
104
+ retry_opts = RunLoop::RetryOpts.tries_and_interval(tries, interval, {:on_retry => on_retry})
105
+
106
+ # For some reason, :timeout does not work here;
107
+ # the lldb process can hang indefinitely.
108
+ Retriable.retriable(retry_opts) do
107
109
  unless inject_dylib_with_timeout merged_options[:timeout]
108
110
  raise RuntimeError, "Could not inject dylib"
109
111
  end
110
112
  end
111
113
  true
112
114
  end
113
-
114
- private
115
-
116
- RETRIABLE_OPTIONS =
117
- {
118
- :retries => 3,
119
- :timeout => 10,
120
- # Retriable 2.0 replaces :interval with :base_interval
121
- :interval => 2,
122
- :base_interval => 2
123
- }
124
115
  end
125
116
  end
@@ -39,7 +39,12 @@ module RunLoop
39
39
 
40
40
  # Returns the value of BUNDLE_ID
41
41
  def self.bundle_id
42
- ENV['BUNDLE_ID']
42
+ value = ENV['BUNDLE_ID']
43
+ if !value || value == ''
44
+ nil
45
+ else
46
+ value
47
+ end
43
48
  end
44
49
 
45
50
  # Returns to the path to the app bundle (simulator builds).
@@ -48,7 +53,12 @@ module RunLoop
48
53
  #
49
54
  # Use of APP_BUNDLE_PATH is deprecated and will be removed.
50
55
  def self.path_to_app_bundle
51
- ENV['APP_BUNDLE_PATH'] || ENV['APP']
56
+ value = ENV['APP_BUNDLE_PATH'] || ENV['APP']
57
+ if !value || value == ''
58
+ nil
59
+ else
60
+ value
61
+ end
52
62
  end
53
63
 
54
64
  # Returns the value of DEVELOPER_DIR
@@ -56,7 +66,12 @@ module RunLoop
56
66
  # @note Never call this directly. Always create an XCTool instance
57
67
  # and allow it to derive the path to the Xcode toolchain.
58
68
  def self.developer_dir
59
- ENV['DEVELOPER_DIR']
69
+ value = ENV['DEVELOPER_DIR']
70
+ if !value || value == ''
71
+ nil
72
+ else
73
+ value
74
+ end
60
75
  end
61
76
  end
62
77
  end
@@ -24,7 +24,7 @@ module RunLoop
24
24
  # @return [String] Expanded path to the default cache directory.
25
25
  def self.default_directory
26
26
  uid = RunLoop::Environment.uid
27
- File.expand_path("/tmp/com.xamarin.calabash.run-loop/host-cache/#{uid}")
27
+ File.expand_path("/tmp/com.xamarin.calabash.run-loop_host-cache_#{uid}")
28
28
  end
29
29
 
30
30
  # The default cache.
@@ -0,0 +1,24 @@
1
+ require 'retriable'
2
+
3
+ module RunLoop
4
+ # A class to bridge the gap between retriable 1.x and 2.0.
5
+ class RetryOpts
6
+ def self.tries_and_interval(tries, interval, other_retry_options={})
7
+ retriable_version = RunLoop::Version.new(Retriable::VERSION)
8
+
9
+ if other_retry_options[:tries]
10
+ raise RuntimeError, ':tries is not a valid key for other_retry_options'
11
+ elsif other_retry_options[:interval]
12
+ raise RuntimeError, ':interval is not a valid key for other_retry_options'
13
+ elsif other_retry_options[:intervals]
14
+ raise RuntimeError, ':intervals is not a valid key for other_retry_options'
15
+ end
16
+
17
+ if retriable_version >= RunLoop::Version.new('2.0.0')
18
+ other_retry_options.merge({:intervals => Array.new(tries, interval)})
19
+ else
20
+ other_retry_options.merge({:tries => tries, :interval => interval})
21
+ end
22
+ end
23
+ end
24
+ end
@@ -1,5 +1,5 @@
1
1
  module RunLoop
2
- VERSION = '1.2.9'
2
+ VERSION = '1.3.0'
3
3
 
4
4
  # A model of a software release version that can be used to compare two versions.
5
5
  #
@@ -70,7 +70,6 @@ module RunLoop
70
70
  @xcode_gte_63 ||= xcode_version >= v63
71
71
  end
72
72
 
73
-
74
73
  # Are we running Xcode 6.2 or above?
75
74
  #
76
75
  # @return [Boolean] `true` if the current Xcode version is >= 6.2
@@ -139,7 +138,7 @@ module RunLoop
139
138
  # @return [Boolean] True if the Xcode version is beta.
140
139
  def xcode_is_beta?
141
140
  @xcode_is_beta ||= lambda {
142
- (xcode_developer_dir =~ /Xcode-Beta.app/) != nil
141
+ (xcode_developer_dir =~ /Xcode-[Bb]eta.app/) != nil
143
142
  }.call
144
143
  end
145
144
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: run_loop
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.9
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Karl Krukow
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-16 00:00:00.000000000 Z
11
+ date: 2015-04-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -33,7 +33,7 @@ dependencies:
33
33
  version: 1.3.3.1
34
34
  - - "<"
35
35
  - !ruby/object:Gem::Version
36
- version: '2.0'
36
+ version: '2.1'
37
37
  type: :runtime
38
38
  prerelease: false
39
39
  version_requirements: !ruby/object:Gem::Requirement
@@ -43,7 +43,7 @@ dependencies:
43
43
  version: 1.3.3.1
44
44
  - - "<"
45
45
  - !ruby/object:Gem::Version
46
- version: '2.0'
46
+ version: '2.1'
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: awesome_print
49
49
  requirement: !ruby/object:Gem::Requirement
@@ -72,6 +72,46 @@ dependencies:
72
72
  - - "~>"
73
73
  - !ruby/object:Gem::Version
74
74
  version: '2.2'
75
+ - !ruby/object:Gem::Dependency
76
+ name: thor
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: 0.18.1
82
+ - - "<"
83
+ - !ruby/object:Gem::Version
84
+ version: '1.0'
85
+ type: :runtime
86
+ prerelease: false
87
+ version_requirements: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: 0.18.1
92
+ - - "<"
93
+ - !ruby/object:Gem::Version
94
+ version: '1.0'
95
+ - !ruby/object:Gem::Dependency
96
+ name: luffa
97
+ requirement: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - "~>"
100
+ - !ruby/object:Gem::Version
101
+ version: '1.0'
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: 1.0.4
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - "~>"
110
+ - !ruby/object:Gem::Version
111
+ version: '1.0'
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: 1.0.4
75
115
  - !ruby/object:Gem::Dependency
76
116
  name: bundler
77
117
  requirement: !ruby/object:Gem::Requirement
@@ -188,16 +228,22 @@ dependencies:
188
228
  name: stub_env
189
229
  requirement: !ruby/object:Gem::Requirement
190
230
  requirements:
191
- - - '='
231
+ - - ">="
232
+ - !ruby/object:Gem::Version
233
+ version: 1.0.1
234
+ - - "<"
192
235
  - !ruby/object:Gem::Version
193
- version: '0.2'
236
+ version: '2.0'
194
237
  type: :development
195
238
  prerelease: false
196
239
  version_requirements: !ruby/object:Gem::Requirement
197
240
  requirements:
198
- - - '='
241
+ - - ">="
199
242
  - !ruby/object:Gem::Version
200
- version: '0.2'
243
+ version: 1.0.1
244
+ - - "<"
245
+ - !ruby/object:Gem::Version
246
+ version: '2.0'
201
247
  - !ruby/object:Gem::Dependency
202
248
  name: pry
203
249
  requirement: !ruby/object:Gem::Requirement
@@ -226,17 +272,21 @@ dependencies:
226
272
  - - ">="
227
273
  - !ruby/object:Gem::Version
228
274
  version: '0'
229
- description: calabash-cucumber drives tests for native iOS apps. RunLoop provides
230
- a number of tools associated with running Calabash tests.
275
+ description:
231
276
  email:
232
277
  - karl.krukow@xamarin.com
233
- executables: []
278
+ executables:
279
+ - run-loop
234
280
  extensions: []
235
281
  extra_rdoc_files: []
236
282
  files:
237
283
  - LICENSE
284
+ - bin/run-loop
238
285
  - lib/run_loop.rb
239
286
  - lib/run_loop/app.rb
287
+ - lib/run_loop/cli/cli.rb
288
+ - lib/run_loop/cli/errors.rb
289
+ - lib/run_loop/cli/instruments.rb
240
290
  - lib/run_loop/core.rb
241
291
  - lib/run_loop/device.rb
242
292
  - lib/run_loop/dylib_injector.rb
@@ -247,7 +297,8 @@ files:
247
297
  - lib/run_loop/lipo.rb
248
298
  - lib/run_loop/lldb.rb
249
299
  - lib/run_loop/logging.rb
250
- - lib/run_loop/monkey_patch.rb
300
+ - lib/run_loop/patches/awesome_print.rb
301
+ - lib/run_loop/patches/retriable.rb
251
302
  - lib/run_loop/plist_buddy.rb
252
303
  - lib/run_loop/process_terminator.rb
253
304
  - lib/run_loop/process_waiter.rb
@@ -255,7 +306,6 @@ files:
255
306
  - lib/run_loop/simctl/bridge.rb
256
307
  - lib/run_loop/version.rb
257
308
  - lib/run_loop/xctools.rb
258
- - scripts/calabash.lldb.erb
259
309
  - scripts/calabash_script_uia.js
260
310
  - scripts/json2-min.js
261
311
  - scripts/json2.js
@@ -290,6 +340,7 @@ rubyforge_project:
290
340
  rubygems_version: 2.4.5
291
341
  signing_key:
292
342
  specification_version: 4
293
- summary: Tools related to running Calabash iOS tests
343
+ summary: The bridge between Calabash iOS and Xcode command-line tools like instruments
344
+ and simctl.
294
345
  test_files: []
295
346
  has_rdoc:
@@ -1,4 +0,0 @@
1
- process attach -n '<%= cf_bundle_executable %>'
2
- expr (void*)dlopen("<%= dylib_path_for_target %>", 0x2)
3
- detach
4
- exit