ruboto 0.10.1 → 0.10.2.rc.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.
- data/Gemfile +1 -1
- data/Gemfile.lock +1 -1
- data/Rakefile +110 -34
- data/assets/rakelib/ruboto.rake +181 -76
- data/assets/src/org/ruboto/JRubyAdapter.java +7 -3
- data/assets/src/org/ruboto/ScriptLoader.java +12 -4
- data/assets/src/ruboto/widget.rb +43 -34
- data/bin/ruboto +9 -4
- data/lib/ruboto/sdk_versions.rb +11 -2
- data/lib/ruboto/util/build.rb +1 -1
- data/lib/ruboto/util/update.rb +104 -32
- data/lib/ruboto/version.rb +1 -1
- data/test/activity/call_super_activity.rb +2 -3
- data/test/activity/dir_and_file_activity.rb +18 -0
- data/test/activity/dir_and_file_activity_test.rb +20 -0
- data/test/activity/image_button_and_button_activity.rb +4 -5
- data/test/activity/json_activity.rb +21 -0
- data/test/activity/json_activity_test.rb +17 -0
- data/test/activity/location_activity.rb +30 -0
- data/test/activity/location_activity_test.rb +17 -0
- data/test/activity/margins_activity.rb +0 -1
- data/test/activity/option_menu_activity.rb +0 -1
- data/test/activity/psych_activity.rb +8 -2
- data/test/activity/ssl_activity.rb +31 -0
- data/test/activity/ssl_activity_test.rb +22 -0
- data/test/activity/stack_activity.rb +0 -1
- data/test/activity/stack_activity_test.rb +4 -5
- data/test/activity/subclass_activity.rb +0 -1
- data/test/activity/view_constants_activity.rb +0 -1
- data/test/app_test_methods.rb +19 -6
- data/test/minimal_app_test.rb +10 -10
- data/test/rake_test.rb +8 -8
- data/test/ruboto_gen_test.rb +18 -12
- data/test/ruboto_update_test.rb +16 -10
- data/test/test_helper.rb +16 -35
- metadata +21 -9
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
data/Rakefile
CHANGED
@@ -11,7 +11,7 @@ PLATFORM_PROJECT = File.expand_path('tmp/RubotoCore', File.dirname(__FILE__))
|
|
11
11
|
PLATFORM_DEBUG_APK = "#{PLATFORM_PROJECT}/bin/RubotoCore-debug.apk"
|
12
12
|
PLATFORM_DEBUG_APK_BAK = "#{PLATFORM_PROJECT}/bin/RubotoCore-debug.apk.bak"
|
13
13
|
PLATFORM_RELEASE_APK = "#{PLATFORM_PROJECT}/bin/RubotoCore-release.apk"
|
14
|
-
PLATFORM_CURRENT_RELEASE_APK =
|
14
|
+
PLATFORM_CURRENT_RELEASE_APK = File.expand_path('tmp/RubotoCore-release.apk', File.dirname(__FILE__))
|
15
15
|
MANIFEST_FILE = "AndroidManifest.xml"
|
16
16
|
GEM_FILE = "ruboto-#{Ruboto::VERSION}.gem"
|
17
17
|
GEM_SPEC_FILE = 'ruboto.gemspec'
|
@@ -87,8 +87,8 @@ task :release_docs do
|
|
87
87
|
user = ask('login : ') { |q| q.echo = true }
|
88
88
|
pass = ask('password: ') { |q| q.echo = '*' }
|
89
89
|
rescue
|
90
|
-
print 'user name: '
|
91
|
-
print ' password: '
|
90
|
+
print 'user name: '; user = STDIN.gets.chomp
|
91
|
+
print ' password: '; pass = STDIN.gets.chomp
|
92
92
|
end
|
93
93
|
require 'uri'
|
94
94
|
require 'net/http'
|
@@ -106,12 +106,12 @@ task :release_docs do
|
|
106
106
|
req.basic_auth(user, pass)
|
107
107
|
res = https.start { |http| http.request(req) }
|
108
108
|
milestones = YAML.load(res.body).sort_by { |i| Date.parse(i['due_on']) }
|
109
|
-
puts milestones.map{|m| "#{'%2d' % m['number']} #{m['title']}"}.join("\n")
|
109
|
+
puts milestones.map { |m| "#{'%2d' % m['number']} #{m['title']}" }.join("\n")
|
110
110
|
|
111
111
|
if defined? ask
|
112
112
|
milestone = ask('milestone: ', Integer) { |q| q.echo = true }
|
113
113
|
else
|
114
|
-
print 'milestone: '
|
114
|
+
print 'milestone: '; milestone = STDIN.gets.chomp
|
115
115
|
end
|
116
116
|
|
117
117
|
uri = URI("#{base_uri}/issues?milestone=#{milestone}&state=closed&per_page=1000")
|
@@ -123,9 +123,9 @@ task :release_docs do
|
|
123
123
|
milestone_description = issues[0] ? issues[0]['milestone']['description'] : "No issues for milestone #{milestone}"
|
124
124
|
categories = {'Features' => 'feature', 'Bugfixes' => 'bug', 'Internal' => 'internal', 'Support' => 'support', 'Documentation' => 'documentation', 'Pull requests' => nil, 'Other' => nil}
|
125
125
|
grouped_issues = issues.group_by do |i|
|
126
|
-
labels = i['labels'].map { |l| l['name']}
|
126
|
+
labels = i['labels'].map { |l| l['name'] }
|
127
127
|
cat = nil
|
128
|
-
categories.each do |k,v|
|
128
|
+
categories.each do |k, v|
|
129
129
|
if labels.include? v
|
130
130
|
cat = k
|
131
131
|
break
|
@@ -198,7 +198,7 @@ task :stats do
|
|
198
198
|
https.use_ssl = true
|
199
199
|
https.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
200
200
|
|
201
|
-
counts_per_month = Hash.new{|h, k| h[k] = Hash.new{|mh,mk| mh[mk] = 0 }}
|
201
|
+
counts_per_month = Hash.new { |h, k| h[k] = Hash.new { |mh, mk| mh[mk] = 0 } }
|
202
202
|
total = 0
|
203
203
|
|
204
204
|
%w{ruboto-core ruboto}.each do |gem|
|
@@ -213,20 +213,20 @@ task :stats do
|
|
213
213
|
req = Net::HTTP::Get.new(downloads_uri.request_uri)
|
214
214
|
res = https.start { |http| http.request(req) }
|
215
215
|
counts = YAML.load(res.body)
|
216
|
-
counts.delete_if{|date_str,count| count == 0}
|
216
|
+
counts.delete_if { |date_str, count| count == 0 }
|
217
217
|
counts.each do |date_str, count|
|
218
218
|
date = Date.parse(date_str)
|
219
219
|
counts_per_month[date.year][date.month] += count
|
220
220
|
total += count
|
221
221
|
end
|
222
|
-
print '.'
|
222
|
+
print '.'; STDOUT.flush
|
223
223
|
end
|
224
224
|
puts
|
225
225
|
end
|
226
226
|
|
227
227
|
puts "\nDownloads statistics per month:"
|
228
228
|
years = counts_per_month.keys
|
229
|
-
puts "\n #{years.map{|year| '%6s:' % year}.join(' ')}"
|
229
|
+
puts "\n #{years.map { |year| '%6s:' % year }.join(' ')}"
|
230
230
|
(1..12).each do |month|
|
231
231
|
print "#{'%2d' % month}:"
|
232
232
|
years.each do |year|
|
@@ -240,7 +240,7 @@ task :stats do
|
|
240
240
|
|
241
241
|
puts "\nRubyGems download statistics per month:"
|
242
242
|
years = counts_per_month.keys
|
243
|
-
puts ' ' + years.map{|year| '%-12s' % year}.join
|
243
|
+
puts ' ' + years.map { |year| '%-12s' % year }.join
|
244
244
|
(0..20).each do |l|
|
245
245
|
print (l % 10 == 0) ? '%4d' % ((20-l) * 100) : ' '
|
246
246
|
years.each do |year|
|
@@ -254,7 +254,7 @@ task :stats do
|
|
254
254
|
end
|
255
255
|
puts
|
256
256
|
end
|
257
|
-
puts ' ' + years.map{|year| '%-12s' % year}.join
|
257
|
+
puts ' ' + years.map { |year| '%-12s' % year }.join
|
258
258
|
|
259
259
|
puts "\nTotal: #{total}\n\n"
|
260
260
|
end
|
@@ -275,11 +275,15 @@ task :release => [:clean, :gem] do
|
|
275
275
|
sh "git push"
|
276
276
|
end
|
277
277
|
|
278
|
-
desc "Run the tests"
|
278
|
+
desc "Run the tests. Select which test files to load with 'rake test TEST=test_file_pattern'"
|
279
279
|
task :test do
|
280
280
|
FileUtils.rm_rf Dir['tmp/RubotoTestApp_template*']
|
281
|
-
|
282
|
-
|
281
|
+
test_pattern = ARGV.grep(/^TEST=.*$/)
|
282
|
+
ARGV.delete_if { |a| test_pattern.include? a }
|
283
|
+
test_pattern.map! { |t| t[5..-1] }
|
284
|
+
$: << File.expand_path('test', File.dirname(__FILE__))
|
285
|
+
(test_pattern.any? ? test_pattern : ['test/*_test.rb']).map { |d| Dir[d] }.flatten.each do |f|
|
286
|
+
require f.chomp('.rb')[5..-1]
|
283
287
|
end
|
284
288
|
end
|
285
289
|
|
@@ -305,13 +309,10 @@ namespace :platform do
|
|
305
309
|
task PLATFORM_DEBUG_APK do
|
306
310
|
Rake::Task[PLATFORM_PROJECT].invoke
|
307
311
|
Dir.chdir(PLATFORM_PROJECT) do
|
308
|
-
if File.exists?(
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
else
|
313
|
-
FileUtils.rm PLATFORM_DEBUG_APK
|
314
|
-
end
|
312
|
+
if File.exists?(PLATFORM_DEBUG_APK_BAK)
|
313
|
+
FileUtils.cp PLATFORM_DEBUG_APK_BAK, PLATFORM_DEBUG_APK
|
314
|
+
else
|
315
|
+
FileUtils.rm PLATFORM_DEBUG_APK
|
315
316
|
end
|
316
317
|
sh 'rake debug'
|
317
318
|
end
|
@@ -342,14 +343,9 @@ namespace :platform do
|
|
342
343
|
end
|
343
344
|
end
|
344
345
|
|
345
|
-
desc '
|
346
|
-
task :current =>
|
347
|
-
|
348
|
-
if File.size(PLATFORM_CURRENT_RELEASE_APK) != File.size(PLATFORM_DEBUG_APK)
|
349
|
-
FileUtils.cp PLATFORM_DEBUG_APK, PLATFORM_DEBUG_APK_BAK
|
350
|
-
FileUtils.cp PLATFORM_CURRENT_RELEASE_APK, PLATFORM_DEBUG_APK
|
351
|
-
end
|
352
|
-
end
|
346
|
+
desc 'Install the current RubotoCore platform release apk'
|
347
|
+
task :current => PLATFORM_CURRENT_RELEASE_APK do
|
348
|
+
install_apk
|
353
349
|
end
|
354
350
|
|
355
351
|
desc 'Install the Ruboto Core platform debug apk'
|
@@ -360,9 +356,89 @@ namespace :platform do
|
|
360
356
|
end
|
361
357
|
|
362
358
|
desc 'Uninstall the Ruboto Core platform debug apk'
|
363
|
-
task :uninstall
|
364
|
-
|
365
|
-
|
359
|
+
task :uninstall do
|
360
|
+
uninstall_apk
|
361
|
+
end
|
362
|
+
|
363
|
+
private
|
364
|
+
|
365
|
+
def package
|
366
|
+
'org.ruboto.core'
|
367
|
+
end
|
368
|
+
|
369
|
+
def install_apk
|
370
|
+
failure_pattern = /^Failure \[(.*)\]/
|
371
|
+
success_pattern = /^Success/
|
372
|
+
case package_installed?
|
373
|
+
when true
|
374
|
+
puts "Package #{package} already installed."
|
375
|
+
return
|
376
|
+
when false
|
377
|
+
puts "Package #{package} already installed, but of different size. Replacing package."
|
378
|
+
output = `adb install -r #{PLATFORM_CURRENT_RELEASE_APK} 2>&1`
|
379
|
+
if $? == 0 && output !~ failure_pattern && output =~ success_pattern
|
380
|
+
clear_update
|
381
|
+
return
|
382
|
+
end
|
383
|
+
case $1
|
384
|
+
when 'INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES'
|
385
|
+
puts 'Found package signed with different certificate. Uninstalling it and retrying install.'
|
386
|
+
else
|
387
|
+
puts "'adb install' returned an unknown error: (#$?) #{$1 ? "[#$1}]" : output}."
|
388
|
+
puts "Uninstalling #{package} and retrying install."
|
389
|
+
end
|
390
|
+
uninstall_apk
|
391
|
+
end
|
392
|
+
puts "Installing package #{package}"
|
393
|
+
begin
|
394
|
+
output = nil
|
395
|
+
timeout 180 do
|
396
|
+
output = `adb install #{PLATFORM_CURRENT_RELEASE_APK} 2>&1`
|
397
|
+
end
|
398
|
+
rescue TimeoutError
|
399
|
+
puts 'Install of current RubotoCore timed out. Retrying.'
|
400
|
+
retry
|
401
|
+
end
|
402
|
+
puts output
|
403
|
+
raise "Install failed (#{$?}) #{$1 ? "[#$1}]" : output}" if $? != 0 || output =~ failure_pattern || output !~ success_pattern
|
404
|
+
end
|
405
|
+
|
406
|
+
def uninstall_apk
|
407
|
+
return if package_installed?.nil?
|
408
|
+
puts "Uninstalling package #{package}"
|
409
|
+
system "adb uninstall #{package}"
|
410
|
+
if $? != 0 && package_installed?
|
411
|
+
puts "Uninstall failed exit code #{$?}"
|
412
|
+
exit $?
|
366
413
|
end
|
367
414
|
end
|
415
|
+
|
416
|
+
def package_installed?
|
417
|
+
package_name = package
|
418
|
+
['', '-0', '-1', '-2'].each do |i|
|
419
|
+
path = "/data/app/#{package_name}#{i}.apk"
|
420
|
+
o = `adb shell ls -l #{path}`.chomp
|
421
|
+
if o =~ /^-rw-r--r-- system\s+system\s+(\d+) \d{4}-\d{2}-\d{2} \d{2}:\d{2} #{File.basename(path)}$/
|
422
|
+
apk_file = PLATFORM_CURRENT_RELEASE_APK
|
423
|
+
if !File.exists?(apk_file) || $1.to_i == File.size(apk_file)
|
424
|
+
return true
|
425
|
+
else
|
426
|
+
return false
|
427
|
+
end
|
428
|
+
end
|
429
|
+
|
430
|
+
sdcard_path = "/mnt/asec/#{package_name}#{i}/pkg.apk"
|
431
|
+
o = `adb shell ls -l #{sdcard_path}`.chomp
|
432
|
+
if o =~ /^-r-xr-xr-x system\s+root\s+(\d+) \d{4}-\d{2}-\d{2} \d{2}:\d{2} #{File.basename(sdcard_path)}$/
|
433
|
+
apk_file = PLATFORM_CURRENT_RELEASE_APK
|
434
|
+
if !File.exists?(apk_file) || $1.to_i == File.size(apk_file)
|
435
|
+
return true
|
436
|
+
else
|
437
|
+
return false
|
438
|
+
end
|
439
|
+
end
|
440
|
+
end
|
441
|
+
return nil
|
442
|
+
end
|
443
|
+
|
368
444
|
end
|
data/assets/rakelib/ruboto.rake
CHANGED
@@ -3,8 +3,11 @@ require 'rubygems'
|
|
3
3
|
require 'time'
|
4
4
|
require 'rake/clean'
|
5
5
|
require 'rexml/document'
|
6
|
+
require 'timeout'
|
6
7
|
|
7
|
-
|
8
|
+
ON_WINDOWS = (RbConfig::CONFIG['host_os'] =~ /mswin|mingw/i)
|
9
|
+
|
10
|
+
ANT_CMD = ON_WINDOWS ? 'ant.bat' : 'ant'
|
8
11
|
|
9
12
|
if `#{ANT_CMD} -version` !~ /version (\d+)\.(\d+)\.(\d+)/ || $1.to_i < 1 || ($1.to_i == 1 && $2.to_i < 8)
|
10
13
|
puts "ANT version 1.8.0 or later required. Version found: #{$1}.#{$2}.#{$3}"
|
@@ -12,48 +15,64 @@ if `#{ANT_CMD} -version` !~ /version (\d+)\.(\d+)\.(\d+)/ || $1.to_i < 1 || ($1.
|
|
12
15
|
end
|
13
16
|
|
14
17
|
adb_version_str = `adb version`
|
15
|
-
(puts
|
16
|
-
(puts "Unrecognized adb version: #$1";exit 1) unless adb_version_str =~ /Android Debug Bridge version (\d+\.\d+\.\d+)/
|
17
|
-
(puts "adb version 1.0.31 or later required. Version found: #$1";exit 1) unless Gem::Version.new($1) >= Gem::Version.new('1.0.31')
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
18
|
+
(puts 'Android SDK platform tools not in PATH (adb command not found).'; exit 1) unless $? == 0
|
19
|
+
(puts "Unrecognized adb version: #$1"; exit 1) unless adb_version_str =~ /Android Debug Bridge version (\d+\.\d+\.\d+)/
|
20
|
+
(puts "adb version 1.0.31 or later required. Version found: #$1"; exit 1) unless Gem::Version.new($1) >= Gem::Version.new('1.0.31')
|
21
|
+
unless ENV['ANDROID_HOME']
|
22
|
+
unless ON_WINDOWS
|
23
|
+
begin
|
24
|
+
adb_path = `which adb`
|
25
|
+
ENV['ANDROID_HOME'] = File.dirname(File.dirname(adb_path)) if $? == 0
|
26
|
+
rescue Errno::ENOENT
|
27
|
+
puts "Unable to detect adb location: #$!"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
(puts 'You need to set the ANDROID_HOME environment variable.'; exit 1) unless ENV['ANDROID_HOME']
|
32
|
+
|
33
|
+
# FIXME(uwe): On windows the file is called dx.bat
|
34
|
+
dx_filename = File.join(ENV['ANDROID_HOME'], 'platform-tools', ON_WINDOWS ? 'dx.bat' : 'dx')
|
35
|
+
unless File.exists? dx_filename
|
36
|
+
puts 'You need to install the Android SDK Platform-tools!'
|
37
|
+
exit 1
|
38
|
+
end
|
39
|
+
new_dx_content = File.read(dx_filename).dup
|
40
|
+
# set defaultXmx=-Xmx1024M
|
41
|
+
xmx_pattern = /^defaultMx="-Xmx(\d+)(M|m|G|g|T|t)"/
|
42
|
+
if new_dx_content =~ xmx_pattern &&
|
43
|
+
($1.to_i * 1024 ** {'M' => 2, 'G' => 3, 'T' => 4}[$2.upcase]) < 2560*1024**2
|
44
|
+
puts "Increasing max heap space from #$1#$2 to 2560M in #{dx_filename}"
|
45
|
+
new_dx_content.sub!(xmx_pattern, 'defaultMx="-Xmx2560M"')
|
46
|
+
File.open(dx_filename, 'w') { |f| f << new_dx_content } rescue puts "\n!!! Unable to increase dx heap size !!!\n\n"
|
47
|
+
end
|
48
|
+
|
49
|
+
def manifest; @manifest ||= REXML::Document.new(File.read(MANIFEST_FILE)) end
|
50
|
+
def package; manifest.root.attribute('package') end
|
51
|
+
def build_project_name; @build_project_name ||= REXML::Document.new(File.read('build.xml')).elements['project'].attribute(:name).value end
|
52
|
+
def scripts_path; @sdcard_path ||= "/mnt/sdcard/Android/data/#{package}/files/scripts" end
|
53
|
+
def app_files_path; @app_files_path ||= "/data/data/#{package}/files" end
|
54
|
+
|
55
|
+
PROJECT_DIR = File.expand_path('..', File.dirname(__FILE__))
|
37
56
|
UPDATE_MARKER_FILE = File.join(PROJECT_DIR, 'bin', 'LAST_UPDATE')
|
38
|
-
BUNDLE_JAR
|
39
|
-
BUNDLE_PATH
|
40
|
-
MANIFEST_FILE
|
57
|
+
BUNDLE_JAR = File.expand_path 'libs/bundle.jar'
|
58
|
+
BUNDLE_PATH = File.expand_path 'bin/bundle'
|
59
|
+
MANIFEST_FILE = File.expand_path 'AndroidManifest.xml'
|
41
60
|
PROJECT_PROPS_FILE = File.expand_path 'project.properties'
|
42
61
|
RUBOTO_CONFIG_FILE = File.expand_path 'ruboto.yml'
|
43
|
-
GEM_FILE
|
44
|
-
GEM_LOCK_FILE
|
45
|
-
RELEASE_APK_FILE
|
46
|
-
APK_FILE
|
47
|
-
TEST_APK_FILE
|
48
|
-
JRUBY_JARS
|
49
|
-
RESOURCE_FILES
|
50
|
-
JAVA_SOURCE_FILES
|
51
|
-
RUBY_SOURCE_FILES
|
52
|
-
APK_DEPENDENCIES
|
53
|
-
KEYSTORE_FILE
|
54
|
-
KEYSTORE_ALIAS
|
55
|
-
|
56
|
-
CLEAN.include('bin', 'gen')
|
62
|
+
GEM_FILE = File.expand_path 'Gemfile.apk'
|
63
|
+
GEM_LOCK_FILE = File.expand_path 'Gemfile.apk.lock'
|
64
|
+
RELEASE_APK_FILE = File.expand_path "bin/#{build_project_name}-release.apk"
|
65
|
+
APK_FILE = File.expand_path "bin/#{build_project_name}-debug.apk"
|
66
|
+
TEST_APK_FILE = File.expand_path "test/bin/#{build_project_name}Test-debug.apk"
|
67
|
+
JRUBY_JARS = Dir[File.expand_path 'libs/jruby-*.jar']
|
68
|
+
RESOURCE_FILES = Dir[File.expand_path 'res/**/*']
|
69
|
+
JAVA_SOURCE_FILES = Dir[File.expand_path 'src/**/*.java']
|
70
|
+
RUBY_SOURCE_FILES = Dir[File.expand_path 'src/**/*.rb']
|
71
|
+
APK_DEPENDENCIES = [MANIFEST_FILE, RUBOTO_CONFIG_FILE, BUNDLE_JAR] + JRUBY_JARS + JAVA_SOURCE_FILES + RESOURCE_FILES + RUBY_SOURCE_FILES
|
72
|
+
KEYSTORE_FILE = (key_store = File.readlines('ant.properties').grep(/^key.store=/).first) ? File.expand_path(key_store.chomp.sub(/^key.store=/, '').sub('${user.home}', '~')) : "#{build_project_name}.keystore"
|
73
|
+
KEYSTORE_ALIAS = (key_alias = File.readlines('ant.properties').grep(/^key.alias=/).first) ? key_alias.chomp.sub(/^key.alias=/, '') : build_project_name
|
74
|
+
|
75
|
+
CLEAN.include('bin', 'gen', 'test/bin', 'test/gen')
|
57
76
|
|
58
77
|
task :default => :debug
|
59
78
|
|
@@ -84,7 +103,7 @@ namespace :debug do
|
|
84
103
|
end
|
85
104
|
end
|
86
105
|
|
87
|
-
desc
|
106
|
+
desc 'build package and install it on the emulator or device'
|
88
107
|
task :install => APK_FILE do
|
89
108
|
install_apk
|
90
109
|
end
|
@@ -117,10 +136,10 @@ task :keystore => KEYSTORE_FILE
|
|
117
136
|
|
118
137
|
file KEYSTORE_FILE do
|
119
138
|
unless File.read('ant.properties') =~ /^key.store=/
|
120
|
-
File.open('ant.properties', 'a'){|f| f << "\nkey.store=#{KEYSTORE_FILE}\n"}
|
139
|
+
File.open('ant.properties', 'a') { |f| f << "\nkey.store=#{KEYSTORE_FILE}\n" }
|
121
140
|
end
|
122
141
|
unless File.read('ant.properties') =~ /^key.alias=/
|
123
|
-
File.open('ant.properties', 'a'){|f| f << "\nkey.alias=#{KEYSTORE_ALIAS}\n"}
|
142
|
+
File.open('ant.properties', 'a') { |f| f << "\nkey.alias=#{KEYSTORE_ALIAS}\n" }
|
124
143
|
end
|
125
144
|
sh "keytool -genkey -v -keystore #{KEYSTORE_FILE} -alias #{KEYSTORE_ALIAS} -keyalg RSA -keysize 2048 -validity 10000"
|
126
145
|
end
|
@@ -129,14 +148,14 @@ desc 'Tag this working copy with the current version'
|
|
129
148
|
task :tag do
|
130
149
|
next unless File.exists?('.git') && `git --version` =~ /git version /
|
131
150
|
unless `git branch` =~ /^\* master$/
|
132
|
-
puts
|
151
|
+
puts 'You must be on the master branch to release!'
|
133
152
|
exit!
|
134
153
|
end
|
135
154
|
# sh "git commit --allow-empty -a -m 'Release #{version}'"
|
136
155
|
output = `git status --porcelain`
|
137
156
|
raise "\nWorkspace not clean!\n#{output}" unless output.empty?
|
138
157
|
sh "git tag #{version}"
|
139
|
-
sh
|
158
|
+
sh 'git push origin master --tags'
|
140
159
|
end
|
141
160
|
|
142
161
|
desc 'Start the emulator with larger disk'
|
@@ -151,7 +170,7 @@ end
|
|
151
170
|
|
152
171
|
desc 'Stop the application on the device/emulator (requires emulator or rooted device).'
|
153
172
|
task :stop do
|
154
|
-
raise
|
173
|
+
raise 'Unable to stop app. Only available on emulator.' unless stop_app
|
155
174
|
end
|
156
175
|
|
157
176
|
desc 'Restart the application'
|
@@ -166,9 +185,9 @@ file MANIFEST_FILE => PROJECT_PROPS_FILE do
|
|
166
185
|
sdk_level = File.read(PROJECT_PROPS_FILE).scan(/(?:target=android-)(\d+)/)[0][0].to_i
|
167
186
|
old_manifest = File.read(MANIFEST_FILE)
|
168
187
|
manifest = old_manifest.dup
|
169
|
-
manifest.sub!(/(android:minSdkVersion=').*?(')/){
|
170
|
-
manifest.sub!(/(android:targetSdkVersion=').*?(')/){
|
171
|
-
File.open(MANIFEST_FILE, 'w'){|f| f << manifest} if manifest != old_manifest
|
188
|
+
manifest.sub!(/(android:minSdkVersion=').*?(')/) { "#$1#{sdk_level}#$2" }
|
189
|
+
manifest.sub!(/(android:targetSdkVersion=').*?(')/) { "#$1#{sdk_level}#$2" }
|
190
|
+
File.open(MANIFEST_FILE, 'w') { |f| f << manifest } if manifest != old_manifest
|
172
191
|
end
|
173
192
|
|
174
193
|
file RUBOTO_CONFIG_FILE
|
@@ -178,7 +197,7 @@ file APK_FILE => APK_DEPENDENCIES do |t|
|
|
178
197
|
end
|
179
198
|
|
180
199
|
desc 'Copy scripts to emulator or device'
|
181
|
-
task :update_scripts =>
|
200
|
+
task :update_scripts => %w(install:quick) do
|
182
201
|
update_scripts
|
183
202
|
end
|
184
203
|
|
@@ -206,7 +225,23 @@ namespace :test do
|
|
206
225
|
task :quick => :update_scripts do
|
207
226
|
Dir.chdir('test') do
|
208
227
|
puts 'Running quick tests'
|
209
|
-
sh "#{ANT_CMD} instrument
|
228
|
+
sh "#{ANT_CMD} instrument"
|
229
|
+
install_retry_count = 0
|
230
|
+
begin
|
231
|
+
timeout 120 do
|
232
|
+
sh "#{ANT_CMD} installi"
|
233
|
+
end
|
234
|
+
rescue TimeoutError
|
235
|
+
puts 'Installing package timed out.'
|
236
|
+
install_retry_count += 1
|
237
|
+
if install_retry_count > 3
|
238
|
+
puts 'Retrying install...'
|
239
|
+
retry
|
240
|
+
end
|
241
|
+
puts 'Trying one final time to install the package:'
|
242
|
+
sh "#{ANT_CMD} installi"
|
243
|
+
end
|
244
|
+
sh "#{ANT_CMD} run-tests-quick"
|
210
245
|
end
|
211
246
|
end
|
212
247
|
end
|
@@ -221,11 +256,26 @@ file BUNDLE_JAR => [GEM_FILE, GEM_LOCK_FILE] do
|
|
221
256
|
next unless File.exists? GEM_FILE
|
222
257
|
puts "Generating #{BUNDLE_JAR}"
|
223
258
|
|
224
|
-
|
225
|
-
|
259
|
+
# Override RUBY_ENGINE (we can bundle from MRI for JRuby)
|
260
|
+
platforms = Gem.platforms
|
261
|
+
ruby_engine = defined?(RUBY_ENGINE) && RUBY_ENGINE
|
262
|
+
Gem.platforms = [Gem::Platform::RUBY, Gem::Platform.new('universal-java')]
|
263
|
+
Object.const_set('RUBY_ENGINE', 'jruby')
|
264
|
+
|
265
|
+
ENV['BUNDLE_GEMFILE'] = GEM_FILE
|
266
|
+
require 'bundler'
|
267
|
+
Bundler.bundle_path = Pathname.new BUNDLE_PATH
|
268
|
+
|
269
|
+
definition = Bundler.definition
|
270
|
+
definition.validate_ruby!
|
271
|
+
Bundler::Installer.install(Bundler.root, definition)
|
272
|
+
|
273
|
+
# Restore RUBY_ENGINE (limit the scope of this hack)
|
274
|
+
Object.const_set('RUBY_ENGINE', ruby_engine) if ruby_engine
|
275
|
+
Gem.platforms = platforms
|
226
276
|
|
227
|
-
gem_paths = Dir["#{BUNDLE_PATH}/
|
228
|
-
raise
|
277
|
+
gem_paths = Dir["#{BUNDLE_PATH}/gems"]
|
278
|
+
raise 'Gem path not found' if gem_paths.empty?
|
229
279
|
raise "Found multiple gem paths: #{gem_paths}" if gem_paths.size > 1
|
230
280
|
gem_path = gem_paths[0]
|
231
281
|
puts "Found gems in #{gem_path}"
|
@@ -257,11 +307,11 @@ file BUNDLE_JAR => [GEM_FILE, GEM_LOCK_FILE] do
|
|
257
307
|
Dir.chdir gem_path do
|
258
308
|
scanned_files = []
|
259
309
|
source_files = RUBY_SOURCE_FILES.map { |f| f.gsub("#{PROJECT_DIR}/src/", '') }
|
260
|
-
Dir[
|
310
|
+
Dir['*/lib/**/*'].each do |f|
|
261
311
|
next if File.directory? f
|
262
|
-
raise
|
312
|
+
raise 'Malformed file name' unless f =~ %r{^(.*?)/lib/(.*)$}
|
263
313
|
gem_name, lib_file = $1, $2
|
264
|
-
if existing_file = scanned_files.find { |sf| sf =~ %r{(.*?)/lib/#{lib_file}} }
|
314
|
+
if (existing_file = scanned_files.find { |sf| sf =~ %r{(.*?)/lib/#{lib_file}} })
|
265
315
|
puts "Overwriting duplicate file #{lib_file} in gem #{$1} with file in #{gem_name}"
|
266
316
|
FileUtils.rm existing_file
|
267
317
|
scanned_files.delete existing_file
|
@@ -300,6 +350,20 @@ puts 'Starting JRuby OpenSSL Service'
|
|
300
350
|
public
|
301
351
|
Java::JopensslService.new.basicLoad(JRuby.runtime)
|
302
352
|
END_CODE
|
353
|
+
elsif jar =~ %r{json/ext/generator.jar$}
|
354
|
+
jar_load_code = <<-END_CODE
|
355
|
+
require 'jruby'
|
356
|
+
puts 'Starting JSON Generator Service'
|
357
|
+
public
|
358
|
+
Java::json.ext.GeneratorService.new.basicLoad(JRuby.runtime)
|
359
|
+
END_CODE
|
360
|
+
elsif jar =~ %r{json/ext/parser.jar$}
|
361
|
+
jar_load_code = <<-END_CODE
|
362
|
+
require 'jruby'
|
363
|
+
puts 'Starting JSON Parser Service'
|
364
|
+
public
|
365
|
+
Java::json.ext.ParserService.new.basicLoad(JRuby.runtime)
|
366
|
+
END_CODE
|
303
367
|
else
|
304
368
|
jar_load_code = ''
|
305
369
|
end
|
@@ -345,7 +409,7 @@ def strings(name)
|
|
345
409
|
end
|
346
410
|
|
347
411
|
def version
|
348
|
-
|
412
|
+
manifest.root.attribute('versionName')
|
349
413
|
end
|
350
414
|
|
351
415
|
def app_name
|
@@ -358,18 +422,24 @@ end
|
|
358
422
|
|
359
423
|
def device_path_exists?(path)
|
360
424
|
path_output =`adb shell ls #{path}`
|
361
|
-
|
362
|
-
result
|
425
|
+
path_output.chomp !~ /No such file or directory|opendir failed, Permission denied/
|
363
426
|
end
|
364
427
|
|
365
|
-
|
428
|
+
# Determine if the package is installed.
|
429
|
+
# Return true if the package is installed and is identical to the local package.
|
430
|
+
# Return false if the package is installed, but differs from the local package.
|
431
|
+
# Return nil if the package is not installed.
|
432
|
+
def package_installed?(test = false)
|
366
433
|
package_name = "#{package}#{'.tests' if test}"
|
367
|
-
|
434
|
+
%w( -0 -1 -2).each do |i|
|
368
435
|
path = "/data/app/#{package_name}#{i}.apk"
|
369
436
|
o = `adb shell ls -l #{path}`.chomp
|
370
|
-
if o =~ /^-rw-r--r-- system\s+system\s+(\d+)
|
437
|
+
if o =~ /^-rw-r--r-- system\s+system\s+(\d+)\s+(\d{4}-\d{2}-\d{2} \d{2}:\d{2})\s+#{File.basename(path)}$/
|
438
|
+
installed_apk_size = $1.to_i
|
439
|
+
installed_timestamp = Time.parse($2)
|
371
440
|
apk_file = test ? TEST_APK_FILE : APK_FILE
|
372
|
-
if !File.exists?(apk_file) ||
|
441
|
+
if !File.exists?(apk_file) || (installed_apk_size == File.size(apk_file) &&
|
442
|
+
installed_timestamp >= File.mtime(apk_file))
|
373
443
|
return true
|
374
444
|
else
|
375
445
|
return false
|
@@ -378,16 +448,19 @@ def package_installed? test = false
|
|
378
448
|
|
379
449
|
sdcard_path = "/mnt/asec/#{package_name}#{i}/pkg.apk"
|
380
450
|
o = `adb shell ls -l #{sdcard_path}`.chomp
|
381
|
-
if o =~ /^-r-xr-xr-x system\s+root\s+(\d+)
|
451
|
+
if o =~ /^-r-xr-xr-x system\s+root\s+(\d+)\s+(\d{4}-\d{2}-\d{2} \d{2}:\d{2})\s+#{File.basename(sdcard_path)}$/
|
452
|
+
installed_apk_size = $1.to_i
|
453
|
+
installed_timestamp = Time.parse($2)
|
382
454
|
apk_file = test ? TEST_APK_FILE : APK_FILE
|
383
|
-
if !File.exists?(apk_file) ||
|
455
|
+
if !File.exists?(apk_file) || (installed_apk_size == File.size(apk_file) &&
|
456
|
+
installed_timestamp >= File.mtime(apk_file))
|
384
457
|
return true
|
385
458
|
else
|
386
459
|
return false
|
387
460
|
end
|
388
461
|
end
|
389
462
|
end
|
390
|
-
|
463
|
+
nil
|
391
464
|
end
|
392
465
|
|
393
466
|
def replace_faulty_code(faulty_file, faulty_code)
|
@@ -420,7 +493,7 @@ def build_apk(t, release)
|
|
420
493
|
else
|
421
494
|
sh "#{ANT_CMD} debug"
|
422
495
|
end
|
423
|
-
|
496
|
+
true
|
424
497
|
end
|
425
498
|
|
426
499
|
def install_apk
|
@@ -431,23 +504,55 @@ def install_apk
|
|
431
504
|
puts "Package #{package} already installed."
|
432
505
|
return
|
433
506
|
when false
|
434
|
-
puts "Package #{package} already installed, but of different size. Replacing package."
|
435
|
-
output =
|
507
|
+
puts "Package #{package} already installed, but of different size or timestamp. Replacing package."
|
508
|
+
output = nil
|
509
|
+
install_retry_count = 0
|
510
|
+
begin
|
511
|
+
timeout 120 do
|
512
|
+
output = `adb install -r #{APK_FILE} 2>&1`
|
513
|
+
end
|
514
|
+
rescue Timeout::Error
|
515
|
+
puts "Installing package #{package} timed out."
|
516
|
+
install_retry_count += 1
|
517
|
+
if install_retry_count > 3
|
518
|
+
puts 'Retrying install...'
|
519
|
+
retry
|
520
|
+
end
|
521
|
+
puts 'Trying one final time to install the package:'
|
522
|
+
output = `adb install -r #{APK_FILE} 2>&1`
|
523
|
+
end
|
436
524
|
if $? == 0 && output !~ failure_pattern && output =~ success_pattern
|
437
525
|
clear_update
|
438
526
|
return
|
439
527
|
end
|
440
528
|
case $1
|
441
529
|
when 'INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES'
|
442
|
-
puts
|
530
|
+
puts 'Found package signed with different certificate. Uninstalling it and retrying install.'
|
443
531
|
else
|
444
532
|
puts "'adb install' returned an unknown error: (#$?) #{$1 ? "[#$1}]" : output}."
|
445
533
|
puts "Uninstalling #{package} and retrying install."
|
446
534
|
end
|
447
535
|
uninstall_apk
|
536
|
+
else
|
537
|
+
# Package not installed.
|
448
538
|
end
|
449
539
|
puts "Installing package #{package}"
|
450
|
-
output =
|
540
|
+
output = nil
|
541
|
+
install_retry_count = 0
|
542
|
+
begin
|
543
|
+
timeout 120 do
|
544
|
+
output = `adb install #{APK_FILE} 2>&1`
|
545
|
+
end
|
546
|
+
rescue Timeout::Error
|
547
|
+
puts "Installing package #{package} timed out."
|
548
|
+
install_retry_count += 1
|
549
|
+
if install_retry_count > 3
|
550
|
+
puts 'Retrying install...'
|
551
|
+
retry
|
552
|
+
end
|
553
|
+
puts 'Trying one final time to install the package:'
|
554
|
+
output = `adb install #{APK_FILE} 2>&1`
|
555
|
+
end
|
451
556
|
puts output
|
452
557
|
raise "Install failed (#{$?}) #{$1 ? "[#$1}]" : output}" if $? != 0 || output =~ failure_pattern || output !~ success_pattern
|
453
558
|
clear_update
|
@@ -465,10 +570,10 @@ end
|
|
465
570
|
|
466
571
|
def update_scripts
|
467
572
|
`adb shell mkdir -p #{scripts_path}` if !device_path_exists?(scripts_path)
|
468
|
-
puts
|
573
|
+
puts 'Pushing files to apk public file area.'
|
469
574
|
last_update = File.exists?(UPDATE_MARKER_FILE) ? Time.parse(File.read(UPDATE_MARKER_FILE)) : Time.parse('1970-01-01T00:00:00')
|
470
575
|
Dir.chdir('src') do
|
471
|
-
Dir[
|
576
|
+
Dir['**/*.rb'].each do |script_file|
|
472
577
|
next if File.directory? script_file
|
473
578
|
next if File.mtime(script_file) < last_update
|
474
579
|
next if script_file =~ /~$/
|
@@ -485,5 +590,5 @@ end
|
|
485
590
|
|
486
591
|
def stop_app
|
487
592
|
output = `adb shell ps | grep #{package} | awk '{print $2}' | xargs adb shell kill`
|
488
|
-
|
593
|
+
output !~ /Operation not permitted/
|
489
594
|
end
|