calabash-android 0.6.1.pre2 → 0.7.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: 08bb9ff234caf41305763096416cc59b342740b4
4
- data.tar.gz: 3ae92f07d7ab7f15ee772a43001dae902f114307
3
+ metadata.gz: 8b3ade59bc8400b324a6dec237662e305d450e29
4
+ data.tar.gz: e5619b9fa36eae19c2202ba726b7ef3d7f04268e
5
5
  SHA512:
6
- metadata.gz: 0785a23d49cf7078cb50523cbde97de466992b9a41c09dddb94e02c23e9e353314444c10623fd2d1010e087235a2169881bf3978aecda25053655da471799041
7
- data.tar.gz: 35b30d8847c497209079d4546744a32c6a44af8b4f79f044ce43a67bfed393edf6ec6457001f70c4d21cba32b53e3953897f7daf47a13c100ede392210b76089
6
+ metadata.gz: 37c23641f575d0ff281d61aaea3a60a8fe2e0d3d40f19cdc8ccea6e82256a3b9619ebae0d0f192a357c07f104e45ee31773344f24add9743f064dbc076d77392
7
+ data.tar.gz: 146b66bb1ad78917230a26cabf627556bb80aae44074bb218d1b39556aefe9d1b7592bdc7d19b4db77a340ea2786daada7ddd934ebf4b66a7e9c5e7190c81d4f
@@ -2,15 +2,12 @@
2
2
 
3
3
  require 'fileutils'
4
4
  require 'rbconfig'
5
- require 'calabash-android/helpers'
6
- require 'calabash-android/java_keystore'
7
- require 'calabash-android/env'
8
5
 
9
6
  # for ruby 1.9.1 and earlier
10
7
  unless defined? RbConfig.ruby
11
- def RbConfig.ruby
12
- File.join(RbConfig::CONFIG["bindir"], RbConfig::CONFIG["ruby_install_name"] + RbConfig::CONFIG["EXEEXT"])
13
- end
8
+ def RbConfig.ruby
9
+ File.join(RbConfig::CONFIG["bindir"], RbConfig::CONFIG["ruby_install_name"] + RbConfig::CONFIG["EXEEXT"])
10
+ end
14
11
  end
15
12
 
16
13
 
@@ -32,11 +29,6 @@ end
32
29
 
33
30
 
34
31
  require File.join(File.dirname(__FILE__), "calabash-android-helpers")
35
- require File.join(File.dirname(__FILE__), "calabash-android-generate")
36
- require File.join(File.dirname(__FILE__), "calabash-android-build")
37
- require File.join(File.dirname(__FILE__), "calabash-android-run")
38
- require File.join(File.dirname(__FILE__), "calabash-android-setup")
39
- require File.join(File.dirname(__FILE__), "calabash-android-console")
40
32
 
41
33
  @features_dir = File.join(FileUtils.pwd, "features")
42
34
  @support_dir = File.join(@features_dir, "support")
@@ -44,79 +36,100 @@ require File.join(File.dirname(__FILE__), "calabash-android-console")
44
36
  @script_dir = File.join(File.dirname(__FILE__), '..', 'scripts')
45
37
 
46
38
  def is_apk_file?(file_path)
47
- file_path.end_with? ".apk" and File.exist? file_path
39
+ file_path.end_with? ".apk" and File.exist? file_path
48
40
  end
49
41
 
50
42
  def relative_to_full_path(file_path)
51
- File.expand_path(file_path)
43
+ File.expand_path(file_path)
52
44
  end
53
45
 
54
46
  if ARGV.length == 0
55
- print_usage
47
+ print_usage
56
48
  else
57
- cmd = ARGV.shift
58
-
59
- case cmd
60
- when 'help'
61
- print_help
62
- when 'build'
63
- Env.exit_if_env_not_set_up
64
-
65
- if ARGV.empty?
66
- puts "Please specify the app you want to build a test server for"
67
- exit 1
68
- elsif !File.exist?(ARGV.first)
69
- puts "Could not find file '#{ARGV.first}'"
70
- exit 1
71
- elsif !is_apk_file?(ARGV.first)
72
- puts "'#{ARGV.first}' is not a valid android application"
73
- exit 1
74
- else
75
- while not ARGV.empty? and is_apk_file?(ARGV.first)
76
- calabash_build(relative_to_full_path(ARGV.shift))
77
- end
78
- end
79
- when 'run'
80
- Env.exit_if_env_not_set_up
81
- if ARGV.empty? or not is_apk_file?(ARGV.first)
82
- puts "The first parameter must be the path to the apk file."
83
- exit 1
84
- else
85
- exit calabash_run(relative_to_full_path(ARGV.shift))
49
+ cmd = ARGV.shift
50
+
51
+ case cmd
52
+ when 'help'
53
+ print_help
54
+ when 'build'
55
+ require 'calabash-android/helpers'
56
+ require 'calabash-android/java_keystore'
57
+ require 'calabash-android/env'
58
+ require File.join(File.dirname(__FILE__), "calabash-android-build")
59
+
60
+ if ARGV.empty?
61
+ puts "Please specify the app you want to build a test server for"
62
+ exit 1
63
+ elsif !File.exist?(ARGV.first)
64
+ puts "Could not find file '#{ARGV.first}'"
65
+ exit 1
66
+ elsif !is_apk_file?(ARGV.first)
67
+ puts "'#{ARGV.first}' is not a valid android application"
68
+ exit 1
69
+ else
70
+ while not ARGV.empty? and is_apk_file?(ARGV.first)
71
+ calabash_build(relative_to_full_path(ARGV.shift))
72
+ end
73
+ end
74
+ when 'run'
75
+ require 'calabash-android/helpers'
76
+ require 'calabash-android/java_keystore'
77
+ require 'calabash-android/env'
78
+ require File.join(File.dirname(__FILE__), "calabash-android-run")
79
+
80
+ if ARGV.empty? or not is_apk_file?(ARGV.first)
81
+ puts "The first parameter must be the path to the apk file."
82
+ exit 1
83
+ else
84
+ exit calabash_run(relative_to_full_path(ARGV.shift))
85
+ end
86
+ when 'gen'
87
+ require 'calabash-android/helpers'
88
+ require 'calabash-android/java_keystore'
89
+ require 'calabash-android/env'
90
+ require File.join(File.dirname(__FILE__), "calabash-android-generate")
91
+
92
+ calabash_scaffold
93
+ when 'console'
94
+ require 'calabash-android/helpers'
95
+ require 'calabash-android/java_keystore'
96
+ require 'calabash-android/env'
97
+ require File.join(File.dirname(__FILE__), "calabash-android-console")
98
+
99
+ if ARGV.empty? or not is_apk_file?(ARGV.first)
100
+ puts "The first parameter must be the path to the apk file."
101
+ exit 1
102
+ else
103
+ calabash_console(relative_to_full_path(ARGV.shift))
104
+ end
105
+ when 'setup'
106
+ require 'calabash-android/helpers'
107
+ require 'calabash-android/java_keystore'
108
+ require 'calabash-android/env'
109
+ require File.join(File.dirname(__FILE__), "calabash-android-setup")
110
+
111
+ calabash_setup
112
+ when 'resign'
113
+ require 'calabash-android/helpers'
114
+ require 'calabash-android/java_keystore'
115
+ require 'calabash-android/env'
116
+
117
+ if ARGV.empty?
118
+ puts "Please specify the app you want to resign"
119
+ exit 1
120
+ elsif !File.exist?(ARGV.first)
121
+ puts "Could not find file '#{ARGV.first}'"
122
+ exit 1
123
+ elsif !is_apk_file?(ARGV.first)
124
+ puts "'#{ARGV.first}' is not a valid android application"
125
+ exit 1
126
+ else
127
+ resign_apk(File.expand_path(ARGV.first))
128
+ end
129
+ when 'version'
130
+ puts Calabash::Android::VERSION
131
+ else
132
+ puts "Invalid command '#{cmd}'"
133
+ print_usage
86
134
  end
87
- when 'gen'
88
- calabash_scaffold
89
- when 'console'
90
- Env.exit_if_env_not_set_up
91
-
92
- if ARGV.empty? or not is_apk_file?(ARGV.first)
93
- puts "The first parameter must be the path to the apk file."
94
- exit 1
95
- else
96
- calabash_console(relative_to_full_path(ARGV.shift))
97
- end
98
- when 'setup'
99
- Env.exit_if_env_not_set_up
100
- calabash_setup
101
- when 'resign'
102
- Env.exit_if_env_not_set_up
103
-
104
- if ARGV.empty?
105
- puts "Please specify the app you want to resign"
106
- exit 1
107
- elsif !File.exist?(ARGV.first)
108
- puts "Could not find file '#{ARGV.first}'"
109
- exit 1
110
- elsif !is_apk_file?(ARGV.first)
111
- puts "'#{ARGV.first}' is not a valid android application"
112
- exit 1
113
- else
114
- resign_apk(File.expand_path(ARGV.first))
115
- end
116
- when 'version'
117
- puts Calabash::Android::VERSION
118
- else
119
- puts "Invalid command '#{cmd}'"
120
- print_usage
121
- end
122
135
  end
@@ -22,7 +22,7 @@ def calabash_build(app)
22
22
 
23
23
  puts ""
24
24
  puts "Notice that resigning an app might break some functionality."
25
- puts "Getting a copy of the certificate used when the app was build will in general be more reliable."
25
+ puts "Getting a copy of the certificate used when the app was built will in general be more reliable."
26
26
 
27
27
  exit 1
28
28
  end
@@ -47,7 +47,7 @@ def calabash_build(app)
47
47
  raise "Could not replace test package name in manifest"
48
48
  end
49
49
 
50
- unless system %Q{"#{Env.tools_dir}/aapt" package -M AndroidManifest.xml -I "#{android_platform}/android.jar" -F dummy.apk}
50
+ unless system %Q{"#{Calabash::Android::Dependencies.aapt_path}" package -M AndroidManifest.xml -I "#{android_platform}/android.jar" -F dummy.apk}
51
51
  raise "Could not create dummy.apk"
52
52
  end
53
53
 
@@ -0,0 +1,525 @@
1
+ require 'rexml/document'
2
+ require 'luffa'
3
+ require 'timeout'
4
+
5
+ if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
6
+ require 'win32/registry'
7
+ end
8
+
9
+ module Calabash
10
+ module Android
11
+ module Dependencies
12
+ private
13
+
14
+ class ScanningTimedOutError < RuntimeError; end
15
+
16
+ def self.set_android_dependencies(android_dependencies)
17
+ @@android_dependencies = android_dependencies
18
+ end
19
+
20
+ def self.set_java_dependencies(java_dependencies)
21
+ @@java_dependencies = java_dependencies
22
+ end
23
+
24
+ def self.android_dependencies(key)
25
+ setup unless defined?(@@android_dependencies)
26
+
27
+ if @@android_dependencies.has_key?(key)
28
+ file = @@android_dependencies[key]
29
+
30
+ unless File.exists?(file)
31
+ raise "No such file '#{file}'"
32
+ end
33
+
34
+ file
35
+ else
36
+ raise "No such dependency '#{key}'"
37
+ end
38
+ end
39
+
40
+ def self.java_dependencies(key)
41
+ setup unless defined?(@@java_dependencies)
42
+
43
+ if key == :ant_path
44
+ ant_executable
45
+ elsif @@java_dependencies.has_key?(key)
46
+ file = @@java_dependencies[key]
47
+
48
+ unless File.exists?(file)
49
+ raise "No such file '#{file}'"
50
+ end
51
+
52
+ file
53
+ else
54
+ raise "No such dependency '#{key}'"
55
+ end
56
+ end
57
+
58
+ public
59
+
60
+ def self.adb_path
61
+ android_dependencies(:adb_path)
62
+ end
63
+
64
+ def self.aapt_path
65
+ android_dependencies(:aapt_path)
66
+ end
67
+
68
+ def self.zipalign_path
69
+ android_dependencies(:zipalign_path)
70
+ end
71
+
72
+ def self.android_jar_path
73
+ android_dependencies(:android_jar_path)
74
+ end
75
+
76
+ def self.java_path
77
+ java_dependencies(:java_path)
78
+ end
79
+
80
+ def self.keytool_path
81
+ java_dependencies(:keytool_path)
82
+ end
83
+
84
+ def self.jarsigner_path
85
+ java_dependencies(:jarsigner_path)
86
+ end
87
+
88
+ def self.ant_path
89
+ java_dependencies(:ant_path)
90
+ end
91
+
92
+ def self.setup
93
+ if ENV['CI_NO_ANDROID_RUNTIME'] == '1'
94
+ @@android_dependencies = {}
95
+ @@java_dependencies = {}
96
+ return
97
+ end
98
+
99
+ @@halt_scanning = false
100
+ @@halt_scanning_thread = nil
101
+
102
+ if ENV['ANDROID_HOME']
103
+ android_sdk_location = ENV['ANDROID_HOME']
104
+ Logging.log_debug("Setting Android SDK location to $ANDROID_HOME")
105
+ else
106
+ android_sdk_location = detect_android_sdk_location
107
+ end
108
+
109
+ if android_sdk_location.nil?
110
+ Logging.log_error 'Could not find an Android SDK please make sure it is installed.'
111
+ Logging.log_error 'You can read about how Calabash is searching for an Android SDK and how you can help here:'
112
+ Logging.log_error 'https://github.com/calabash/calabash-android/blob/master/documentation/installation.md#prerequisites'
113
+
114
+ raise 'Could not find an Android SDK'
115
+ end
116
+
117
+ Logging.log_debug("Android SDK location set to '#{android_sdk_location}'")
118
+
119
+ @@halt_scanning_thread = Thread.new do
120
+ sleep 60
121
+ @@halt_scanning = true
122
+ end
123
+
124
+ begin
125
+ set_android_dependencies(locate_android_dependencies(android_sdk_location))
126
+ rescue ScanningTimedOutError => e
127
+ Logging.log_error 'Timed out locating Android dependency'
128
+ Logging.log_error 'You can read about how Calabash is searching for an Android SDK and how you can help here:'
129
+ Logging.log_error 'https://github.com/calabash/calabash-android/blob/master/documentation/installation.md#prerequisites'
130
+
131
+ raise e.message
132
+ rescue Environment::InvalidEnvironmentError => e
133
+ Logging.log_error 'Could not locate Android dependency'
134
+ Logging.log_error 'You can read about how Calabash is searching for an Android SDK and how you can help here:'
135
+ Logging.log_error 'https://github.com/calabash/calabash-android/blob/master/documentation/installation.md#prerequisites'
136
+
137
+ raise e
138
+ end
139
+
140
+ if ENV['JAVA_HOME']
141
+ java_sdk_home = ENV['JAVA_HOME']
142
+ Logging.log_debug("Setting Java SDK location to $JAVA_HOME")
143
+ else
144
+ java_sdk_home = detect_java_sdk_location
145
+ end
146
+
147
+ Logging.log_debug("Java SDK location set to '#{java_sdk_home}'")
148
+
149
+ Thread.kill(@@halt_scanning_thread) if @@halt_scanning_thread
150
+ @@halt_scanning = false
151
+
152
+ @@halt_scanning_thread = Thread.new do
153
+ sleep 60
154
+ @@halt_scanning = true
155
+ end
156
+
157
+ begin
158
+ set_java_dependencies(locate_java_dependencies(java_sdk_home))
159
+ rescue ScanningTimedOutError => e
160
+ Logging.log_error 'Timed out locating Java dependency'
161
+ Logging.log_error "You can read about how Calabash is searching for a JDK and how you can help here:"
162
+ Logging.log_error "https://github.com/calabash/calabash-android/blob/master/documentation/installation.md#prerequisites"
163
+
164
+ raise e.message
165
+ rescue Environment::InvalidJavaSDKHome => e
166
+ Logging.log_error "Could not find Java Development Kit please make sure it is installed."
167
+ Logging.log_error "You can read about how Calabash is searching for a JDK and how you can help here:"
168
+ Logging.log_error "https://github.com/calabash/calabash-android/blob/master/documentation/installation.md#prerequisites"
169
+
170
+ raise e
171
+ rescue Environment::InvalidEnvironmentError => e
172
+ Logging.log_error "Could not find Java dependency"
173
+ Logging.log_error "You can read about how Calabash is searching for a JDK and how you can help here:"
174
+ Logging.log_error "https://github.com/calabash/calabash-android/blob/master/documentation/installation.md#prerequisites"
175
+
176
+ raise e
177
+ end
178
+
179
+ Thread.kill(@@halt_scanning_thread) if @@halt_scanning_thread
180
+ end
181
+
182
+ private
183
+
184
+ def self.tools_directory
185
+ tools_directories = tools_directories(ENV['ANDROID_HOME'])
186
+
187
+ File.join(ENV['ANDROID_HOME'], tools_directories.first)
188
+ end
189
+
190
+ def self.tools_directories(android_sdk_location)
191
+ build_tools_files = list_files(File.join(android_sdk_location, 'build-tools')).select {|file| File.directory?(file)}
192
+
193
+ build_tools_directories =
194
+ build_tools_files.select do |dir|
195
+ begin
196
+ Luffa::Version.new(File.basename(dir))
197
+ true
198
+ rescue ArgumentError
199
+ false
200
+ end
201
+ end.sort do |a, b|
202
+ Luffa::Version.compare(Luffa::Version.new(File.basename(a)), Luffa::Version.new(File.basename(b)))
203
+ end.reverse.map{|dir| File.join('build-tools', File.basename(dir))}
204
+
205
+ if build_tools_directories.empty?
206
+ unless build_tools_files.reverse.first.nil?
207
+ build_tools_directories = [File.join('build-tools', File.basename(build_tools_files.reverse.first))]
208
+ end
209
+ end
210
+
211
+ build_tools_directories + ['platform-tools', 'tools']
212
+ end
213
+
214
+ def self.platform_directory(android_sdk_location)
215
+ files = list_files(File.join(android_sdk_location, 'platforms'))
216
+ .select {|file| File.directory?(file)}
217
+
218
+ sorted_files = files.sort_by {|item| '%08s' % item.split('-').last}.reverse
219
+
220
+ File.join('platforms', File.basename(sorted_files.first))
221
+ end
222
+
223
+ def self.locate_android_dependencies(android_sdk_location)
224
+ adb_path = scan_for_path(android_sdk_location, adb_executable, ['platform-tools'])
225
+ aapt_path = scan_for_path(android_sdk_location, aapt_executable, tools_directories(android_sdk_location))
226
+ zipalign_path = scan_for_path(android_sdk_location, zipalign_executable, tools_directories(android_sdk_location))
227
+
228
+ if adb_path.nil?
229
+ raise Environment::InvalidEnvironmentError,
230
+ "Could not find '#{adb_executable}' in '#{android_sdk_location}'"
231
+ end
232
+
233
+ if aapt_path.nil?
234
+ raise Environment::InvalidEnvironmentError,
235
+ "Could not find '#{aapt_executable}' in '#{android_sdk_location}'"
236
+ end
237
+
238
+ if zipalign_path.nil?
239
+ raise Environment::InvalidEnvironmentError,
240
+ "Could not find '#{zipalign_executable}' in '#{android_sdk_location}'"
241
+ end
242
+
243
+ Logging.log_debug("Set aapt path to '#{aapt_path}'")
244
+ Logging.log_debug("Set zipalign path to '#{zipalign_path}'")
245
+ Logging.log_debug("Set adb path to '#{adb_path}'")
246
+
247
+ android_jar_path = scan_for_path(File.join(android_sdk_location, 'platforms'), 'android.jar', [File.basename(platform_directory(android_sdk_location))])
248
+
249
+ if android_jar_path.nil?
250
+ raise Environment::InvalidEnvironmentError,
251
+ "Could not find 'android.jar' in '#{File.join(android_sdk_location, 'platforms')}'"
252
+ end
253
+
254
+ Logging.log_debug("Set android jar path to '#{android_jar_path}'")
255
+
256
+ {
257
+ aapt_path: aapt_path,
258
+ zipalign_path: zipalign_path,
259
+ adb_path: adb_path,
260
+ android_jar_path: android_jar_path
261
+ }
262
+ end
263
+
264
+ def self.locate_java_dependencies(java_sdk_location)
265
+ # For the Java dependencies, we will use the PATH elements of they exist
266
+ on_path = find_executable_on_path(java_executable)
267
+
268
+ if on_path
269
+ Logging.log_debug('Found java on PATH')
270
+ java_path = on_path
271
+ else
272
+ if java_sdk_location.nil? || java_sdk_location.empty?
273
+ raise Environment::InvalidJavaSDKHome,
274
+ "Could not locate '#{java_executable}' on path, and Java SDK Home is invalid."
275
+ end
276
+
277
+ java_path = scan_for_path(java_sdk_location, java_executable, ['bin'])
278
+ end
279
+
280
+ Logging.log_debug("Set java path to '#{java_path}'")
281
+
282
+ on_path = find_executable_on_path(keytool_executable)
283
+
284
+ if on_path
285
+ Logging.log_debug('Found keytool on PATH')
286
+ keytool_path = on_path
287
+ else
288
+ if java_sdk_location.nil? || java_sdk_location.empty?
289
+ raise Environment::InvalidJavaSDKHome,
290
+ "Could not locate '#{keytool_executable}' on path, and Java SDK Home is invalid."
291
+ end
292
+
293
+ keytool_path = scan_for_path(java_sdk_location, keytool_executable, ['bin'])
294
+ end
295
+
296
+ Logging.log_debug("Set keytool path to '#{keytool_path}'")
297
+
298
+ on_path = find_executable_on_path(jarsigner_executable)
299
+
300
+ if on_path
301
+ Logging.log_debug('Found jarsigner on PATH')
302
+ jarsigner_path = on_path
303
+ else
304
+ if java_sdk_location.nil? || java_sdk_location.empty?
305
+ raise Environment::InvalidJavaSDKHome,
306
+ "Could not locate '#{jarsigner_executable}' on path, and Java SDK Home is invalid."
307
+ end
308
+
309
+ jarsigner_path = scan_for_path(java_sdk_location, jarsigner_executable, ['bin'])
310
+ end
311
+
312
+ Logging.log_debug("Set jarsigner path to '#{jarsigner_path}'")
313
+
314
+ if java_path.nil?
315
+ raise Environment::InvalidEnvironmentError,
316
+ "Could not find '#{java_executable}' on PATH or in '#{java_sdk_location}'"
317
+ end
318
+
319
+ if keytool_path.nil?
320
+ raise Environment::InvalidEnvironmentError,
321
+ "Could not find '#{keytool_executable}' on PATH or in '#{java_sdk_location}'"
322
+ end
323
+
324
+ if jarsigner_path.nil?
325
+ raise Environment::InvalidEnvironmentError,
326
+ "Could not find '#{jarsigner_executable}' on PATH or in '#{java_sdk_location}'"
327
+ end
328
+
329
+ {
330
+ java_path: java_path,
331
+ keytool_path: keytool_path,
332
+ jarsigner_path: jarsigner_path
333
+ }
334
+ end
335
+
336
+ def self.halt_scanning?
337
+ @@halt_scanning
338
+ end
339
+
340
+ def self.scan_for_path(path, file_name, expected_sub_folders = nil)
341
+ if self.halt_scanning?
342
+ Logging.log_error("Timed out looking for '#{file_name}', currently looking in '#{path}'")
343
+ raise ScanningTimedOutError, "Timed out looking for '#{file_name}'"
344
+ end
345
+
346
+ # Optimization for expected folders
347
+ if expected_sub_folders && !expected_sub_folders.empty?
348
+ expected_sub_folders.each do |expected_sub_folder|
349
+ result = scan_for_path(File.join(path, expected_sub_folder), file_name)
350
+
351
+ return result if result
352
+ end
353
+
354
+ Logging.log_warn("Did not find '#{file_name}' in any standard directory of '#{path}'. Calabash will therefore take longer to load")
355
+ Logging.log_debug(" - Expected to find '#{file_name}' in any of:")
356
+
357
+ expected_sub_folders.each do |expected_sub_folder|
358
+ Logging.log_debug(" - #{File.join(path, expected_sub_folder)}")
359
+ end
360
+ end
361
+
362
+ files = list_files(path).sort.reverse
363
+
364
+ if files.reject{|file| File.directory?(file)}.
365
+ map{|file| File.basename(file)}.include?(file_name)
366
+ return File.join(path, file_name)
367
+ else
368
+ files.select{|file| File.directory?(file)}.each do |dir|
369
+ result = scan_for_path(dir, file_name)
370
+
371
+ return result if result
372
+ end
373
+ end
374
+
375
+ nil
376
+ end
377
+
378
+ def self.detect_android_sdk_location
379
+ if File.exist?(monodroid_config_file)
380
+ sdk_location = read_attribute_from_monodroid_config('android-sdk', 'path')
381
+
382
+ if sdk_location
383
+ Logging.log_debug("Setting Android SDK location from '#{monodroid_config_file}'")
384
+
385
+ return sdk_location
386
+ end
387
+ end
388
+
389
+ if File.exist?('~/Library/Developer/Xamarin/android-sdk-mac_x86/')
390
+ return '~/Library/Developer/Xamarin/android-sdk-mac_x86/'
391
+ end
392
+
393
+ if File.exist?('C:\\Android\\android-sdk')
394
+ return 'C:\\Android\\android-sdk'
395
+ end
396
+
397
+ if is_windows?
398
+ from_registry = read_registry(::Win32::Registry::HKEY_CURRENT_USER, "Software\\Novell\\Mono for Android", 'AndroidSdkDirectory')
399
+
400
+ if from_registry && File.exist?(from_registry)
401
+ Logging.log_debug("Setting Android SDK location from HKEY_CURRENT_USER Software\\Novell\\Mono for Android")
402
+ return from_registry
403
+ end
404
+
405
+ from_registry = read_registry(::Win32::Registry::HKEY_LOCAL_MACHINE, 'Software\\Android SDK Tools', 'Path')
406
+
407
+ if from_registry && File.exist?(from_registry)
408
+ Logging.log_debug("Setting Android SDK location from HKEY_LOCAL_MACHINE Software\\Android SDK Tools")
409
+ return from_registry
410
+ end
411
+ end
412
+
413
+ nil
414
+ end
415
+
416
+ def self.detect_java_sdk_location
417
+ if File.exist?(monodroid_config_file)
418
+ sdk_location = read_attribute_from_monodroid_config('java-sdk', 'path')
419
+
420
+ if sdk_location
421
+ Logging.log_debug("Setting Java SDK location from '#{monodroid_config_file}'")
422
+
423
+ return sdk_location
424
+ end
425
+ end
426
+
427
+ java_versions = ['1.9', '1.8', '1.7', '1.6']
428
+
429
+ if is_windows?
430
+ java_versions.each do |java_version|
431
+ key = "SOFTWARE\\JavaSoft\\Java Development Kit\\#{java_version}"
432
+ from_registry = read_registry(::Win32::Registry::HKEY_LOCAL_MACHINE, key, 'JavaHome')
433
+
434
+ if from_registry && File.exist?(from_registry)
435
+ Logging.log_debug("Setting Java SDK location from HKEY_LOCAL_MACHINE #{key}")
436
+ return from_registry
437
+ end
438
+ end
439
+ end
440
+
441
+ nil
442
+ end
443
+
444
+ def self.monodroid_config_file
445
+ File.expand_path('~/.config/xbuild/monodroid-config.xml')
446
+ end
447
+
448
+ def self.read_attribute_from_monodroid_config(element, attribute)
449
+ element = REXML::Document.new(IO.read(monodroid_config_file)).elements["//#{element}"]
450
+
451
+ if element
452
+ element.attributes[attribute]
453
+ else
454
+ nil
455
+ end
456
+ end
457
+
458
+ def self.find_executable_on_path(executable)
459
+ path_elements.each do |x|
460
+ f = File.join(x, executable)
461
+ return f if File.exists?(f)
462
+ end
463
+
464
+ nil
465
+ end
466
+
467
+ def self.path_elements
468
+ return [] unless ENV['PATH']
469
+ ENV['PATH'].split (/[:;]/)
470
+ end
471
+
472
+ def self.zipalign_executable
473
+ is_windows? ? 'zipalign.exe' : 'zipalign'
474
+ end
475
+
476
+ def self.jarsigner_executable
477
+ is_windows? ? 'jarsigner.exe' : 'jarsigner'
478
+ end
479
+
480
+ def self.java_executable
481
+ is_windows? ? 'java.exe' : 'java'
482
+ end
483
+
484
+ def self.keytool_executable
485
+ is_windows? ? 'keytool.exe' : 'keytool'
486
+ end
487
+
488
+ def self.adb_executable
489
+ is_windows? ? 'adb.exe' : 'adb'
490
+ end
491
+
492
+ def self.aapt_executable
493
+ is_windows? ? 'aapt.exe' : 'aapt'
494
+ end
495
+
496
+ def self.ant_executable
497
+ is_windows? ? 'ant.exe' : 'ant'
498
+ end
499
+
500
+ def self.is_windows?
501
+ (RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/)
502
+ end
503
+
504
+ def self.read_registry(root_key, key, value)
505
+ begin
506
+ root_key.open(key)[value]
507
+ rescue
508
+ nil
509
+ end
510
+ end
511
+
512
+ def self.list_files(path)
513
+ # Dir.glob does not accept backslashes, even on windows. We have to
514
+ # substitute all backwards slashes to forward.
515
+ # C:\foo becomes C:/foo
516
+
517
+ if is_windows?
518
+ Dir.glob(File.join(path, '*').gsub('\\', '/'))
519
+ else
520
+ Dir.glob(File.join(path, '*'))
521
+ end
522
+ end
523
+ end
524
+ end
525
+ end
@@ -1,8 +1,11 @@
1
1
  module Calabash
2
2
  module Android
3
-
4
3
  # @!visibility private
5
4
  class Environment
5
+ # @!visibility private
6
+ class InvalidEnvironmentError < RuntimeError; end
7
+ # @!visibility private
8
+ class InvalidJavaSDKHome < RuntimeError; end
6
9
 
7
10
  # @!visibility private
8
11
  # Returns true if running on Windows
@@ -4,6 +4,10 @@ require 'tempfile'
4
4
  require 'escape'
5
5
  require 'rbconfig'
6
6
  require 'calabash-android/java_keystore'
7
+ require 'calabash-android/environment'
8
+ require 'calabash-android/logging'
9
+ require 'calabash-android/dependencies'
10
+ require 'calabash-android/version'
7
11
 
8
12
  def package_name(app)
9
13
  unless File.exist?(app)
@@ -33,7 +37,7 @@ def main_activity(app)
33
37
  rescue => e
34
38
  log("Could not find launchable activity, trying to parse raw AndroidManifest. #{e.message}")
35
39
 
36
- manifest_data = `"#{Env.tools_dir}/aapt" dump xmltree "#{app}" AndroidManifest.xml`
40
+ manifest_data = `"#{Calabash::Android::Dependencies.aapt_path}" dump xmltree "#{app}" AndroidManifest.xml`
37
41
  regex = /^\s*A:[\s*]android:name\(\w+\)\=\"android.intent.category.LAUNCHER\"/
38
42
  lines = manifest_data.lines.collect(&:strip)
39
43
  indicator_line = nil
@@ -77,7 +81,7 @@ def main_activity(app)
77
81
  end
78
82
 
79
83
  def aapt_dump(app, key)
80
- lines = `"#{Env.tools_dir}/aapt" dump badging "#{app}"`.lines.collect(&:strip)
84
+ lines = `"#{Calabash::Android::Dependencies.aapt_path}" dump badging "#{app}"`.lines.collect(&:strip)
81
85
  lines.select { |l| l.start_with?("#{key}:") }
82
86
  end
83
87
 
@@ -97,6 +101,8 @@ def build_test_server_if_needed(app_path)
97
101
  exit 1
98
102
  else
99
103
  puts "No test server found for this combination of app and calabash version. Recreating test server."
104
+ require 'calabash-android/operations'
105
+ require File.join(File.dirname(__FILE__), '..', '..', 'bin', 'calabash-android-build')
100
106
  calabash_build(app_path)
101
107
  end
102
108
  end
@@ -115,7 +121,7 @@ def resign_apk(app_path)
115
121
  end
116
122
 
117
123
  def unsign_apk(path)
118
- meta_files = `"#{Env.tools_dir}/aapt" list "#{path}"`.lines.collect(&:strip).grep(/^META-INF\//)
124
+ meta_files = `"#{Calabash::Android::Dependencies.aapt_path}" list "#{path}"`.lines.collect(&:strip).grep(/^META-INF\//)
119
125
 
120
126
  signing_file_names = ['.mf', '.rsa', '.dsa', '.ec', '.sf']
121
127
 
@@ -137,12 +143,12 @@ def unsign_apk(path)
137
143
  if files_to_remove.empty?
138
144
  log "App wasn't signed. Will not try to unsign it."
139
145
  else
140
- system("\"#{Env.tools_dir}/aapt\" remove \"#{path}\" #{files_to_remove.join(" ")}")
146
+ system("\"#{Calabash::Android::Dependencies.aapt_path}\" remove \"#{path}\" #{files_to_remove.join(" ")}")
141
147
  end
142
148
  end
143
149
 
144
150
  def zipalign_apk(inpath, outpath)
145
- cmd = %Q("#{Env.zipalign_path}" -f 4 "#{inpath}" "#{outpath}")
151
+ cmd = %Q("#{Calabash::Android::Dependencies.zipalign_path}" -f 4 "#{inpath}" "#{outpath}")
146
152
  log "Zipaligning using: #{cmd}"
147
153
  system(cmd)
148
154
  end
@@ -177,7 +183,7 @@ def fingerprint_from_apk(app_path)
177
183
  raise "No signature files found in META-INF. Cannot proceed." if signature_files.empty?
178
184
  raise "More than one signature file (DSA or RSA) found in META-INF. Cannot proceed." if signature_files.length > 1
179
185
 
180
- cmd = "#{Env.keytool_path} -v -printcert -J\"-Dfile.encoding=utf-8\" -file \"#{signature_files.first}\""
186
+ cmd = "#{Calabash::Android::Dependencies.keytool_path} -v -printcert -J\"-Dfile.encoding=utf-8\" -file \"#{signature_files.first}\""
181
187
  log cmd
182
188
  fingerprints = `#{cmd}`
183
189
  md5_fingerprint = extract_md5_fingerprint(fingerprints)
@@ -6,13 +6,13 @@ class JavaKeystore
6
6
  raise "No such keystore file '#{location}'" unless File.exists?(File.expand_path(location))
7
7
  log "Reading keystore data from keystore file '#{File.expand_path(location)}'"
8
8
 
9
- keystore_data = system_with_stdout_on_success(Env.keytool_path, '-list', '-v', '-alias', keystore_alias, '-keystore', location, '-storepass', password, '-J"-Dfile.encoding=utf-8"', '-J"-Duser.language=en-US"')
9
+ keystore_data = system_with_stdout_on_success(Calabash::Android::Dependencies.keytool_path, '-list', '-v', '-alias', keystore_alias, '-keystore', location, '-storepass', password, '-J"-Dfile.encoding=utf-8"', '-J"-Duser.language=en-US"')
10
10
 
11
11
  if keystore_data.nil?
12
12
  if keystore_alias.empty?
13
13
  log "Could not obtain keystore data. Will try to extract alias automatically"
14
14
 
15
- keystore_data = system_with_stdout_on_success(Env.keytool_path, '-list', '-v', '-keystore', location, '-storepass', password, '-J"-Dfile.encoding=utf-8"', '-J"-Duser.language=en-US"')
15
+ keystore_data = system_with_stdout_on_success(Calabash::Android::Dependencies.keytool_path, '-list', '-v', '-keystore', location, '-storepass', password, '-J"-Dfile.encoding=utf-8"', '-J"-Duser.language=en-US"')
16
16
  aliases = keystore_data.scan(/Alias name\:\s*(.*)/).flatten
17
17
 
18
18
  if aliases.length == 0
@@ -56,7 +56,7 @@ class JavaKeystore
56
56
  log "Signing using the signature algorithm: '#{signing_algorithm}'"
57
57
  log "Signing using the digest algorithm: '#{digest_algorithm}'"
58
58
 
59
- unless system_with_stdout_on_success(Env.jarsigner_path, '-sigfile', 'CERT', '-sigalg', signing_algorithm, '-digestalg', digest_algorithm, '-signedjar', dest_path, '-storepass', password, '-keystore', location, apk_path, keystore_alias)
59
+ unless system_with_stdout_on_success(Calabash::Android::Dependencies.jarsigner_path, '-sigfile', 'CERT', '-sigalg', signing_algorithm, '-digestalg', digest_algorithm, '-signedjar', dest_path, '-storepass', password, '-keystore', location, apk_path, keystore_alias)
60
60
  raise "Could not sign app: #{apk_path}"
61
61
  end
62
62
  end
@@ -20,12 +20,14 @@ require 'calabash-android/dot_dir'
20
20
  require 'calabash-android/logging'
21
21
  require 'calabash-android/store/preferences'
22
22
  require 'calabash-android/usage_tracker'
23
+ require 'calabash-android/dependencies'
23
24
  require 'retriable'
24
25
  require 'cucumber'
25
26
  require 'date'
26
27
  require 'time'
27
28
  require 'shellwords'
28
29
 
30
+ Calabash::Android::Dependencies.setup
29
31
 
30
32
  module Calabash module Android
31
33
 
@@ -558,7 +560,7 @@ module Calabash module Android
558
560
  end
559
561
 
560
562
  def adb_command
561
- "#{Env.adb_path} -s #{serial}"
563
+ "\"#{Calabash::Android::Dependencies.adb_path}\" -s #{serial}"
562
564
  end
563
565
 
564
566
  def default_serial
@@ -595,7 +597,7 @@ module Calabash module Android
595
597
  end
596
598
 
597
599
  def connected_devices
598
- lines = `#{Env.adb_path} devices`.split("\n")
600
+ lines = `"#{Calabash::Android::Dependencies.adb_path}" devices`.split("\n")
599
601
  start_index = lines.index{ |x| x =~ /List of devices attached/ } + 1
600
602
  lines[start_index..-1].collect { |l| l.split("\t").first }
601
603
  end
@@ -1,5 +1,5 @@
1
1
  module Calabash
2
2
  module Android
3
- VERSION = "0.6.1.pre2"
3
+ VERSION = "0.7.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: calabash-android
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1.pre2
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonas Maturana Larsen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-03 00:00:00.000000000 Z
11
+ date: 2016-03-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cucumber
@@ -134,6 +134,20 @@ dependencies:
134
134
  - - "~>"
135
135
  - !ruby/object:Gem::Version
136
136
  version: 0.0.4
137
+ - !ruby/object:Gem::Dependency
138
+ name: luffa
139
+ requirement: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - ">="
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ type: :runtime
145
+ prerelease: false
146
+ version_requirements: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - ">="
149
+ - !ruby/object:Gem::Version
150
+ version: '0'
137
151
  - !ruby/object:Gem::Dependency
138
152
  name: rake
139
153
  requirement: !ruby/object:Gem::Requirement
@@ -318,6 +332,7 @@ files:
318
332
  - lib/calabash-android/color_helper.rb
319
333
  - lib/calabash-android/cucumber.rb
320
334
  - lib/calabash-android/defaults.rb
335
+ - lib/calabash-android/dependencies.rb
321
336
  - lib/calabash-android/deprecated_actions.map
322
337
  - lib/calabash-android/dot_dir.rb
323
338
  - lib/calabash-android/drag_helpers.rb
@@ -374,9 +389,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
374
389
  version: '0'
375
390
  required_rubygems_version: !ruby/object:Gem::Requirement
376
391
  requirements:
377
- - - ">"
392
+ - - ">="
378
393
  - !ruby/object:Gem::Version
379
- version: 1.3.1
394
+ version: '0'
380
395
  requirements: []
381
396
  rubyforge_project:
382
397
  rubygems_version: 2.4.5.1