run_loop 1.2.9 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
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