forked from ruboto/ruboto
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Rakefile
executable file
·295 lines (247 loc) · 9.26 KB
/
Rakefile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
require 'time'
def manifest() @manifest ||= REXML::Document.new(File.read(MANIFEST_FILE)) end
def package() manifest.root.attribute('package') end
def build_project_name() @build_project_name ||= REXML::Document.new(File.read('build.xml')).elements['project'].attribute(:name).value end
UPDATE_MARKER_FILE = File.expand_path(File.join('tmp', 'LAST_UPDATE'), File.dirname(__FILE__))
BUNDLE_JAR = 'libs/bundle.jar'
BUNDLE_PATH = 'tmp/bundle'
require 'rake/clean'
require 'rexml/document'
jars = Dir['libs/*.jar']
stdlib = jars.grep(/stdlib/).first #libs/jruby-stdlib-VERSION.jar
jruby_jar = jars.grep(/core/).first #libs/jruby-core-VERSION.jar
MANIFEST_FILE = 'AndroidManifest.xml'
APK_FILE = "bin/#{build_project_name}-debug.apk"
TEST_APK_FILE = "test/bin/#{build_project_name}Test-debug.apk"
CLEAN.include('tmp', 'bin')
task :default => :debug
desc 'build debug package'
task :debug => [BUNDLE_JAR, :mark_update] do
sh 'ant debug'
end
desc "build package and install it on the emulator or device"
task :install => [APK_FILE, BUNDLE_JAR, :mark_update] do
sh 'ant ruboto-install-debug' unless package_installed?
end
task :tag => :release do
unless `git branch` =~ /^\* master$/
puts "You must be on the master branch to release!"
exit!
end
sh "git commit --allow-empty -a -m 'Release #{version}'"
sh "git tag #{version}"
sh "git push origin master --tags"
#sh "gem push pkg/#{name}-#{version}.gem"
end
task :sign => :release do
sh "jarsigner -keystore #{ENV['RUBOTO_KEYSTORE']} -signedjar bin/#{build_project_name}.apk bin/#{build_project_name}-unsigned.apk #{ENV['RUBOTO_KEY_ALIAS']}"
end
task :align => :sign do
sh "zipalign 4 bin/#{build_project_name}.apk #{build_project_name}.apk"
end
task :publish => :align do
puts "#{build_project_name}.apk is ready for the market!"
end
desc 'Start the emulator with larger disk'
task :emulator do
system 'emulator -partition-size 1024 -avd Android_3.0'
end
task :start_app do
`adb shell am start -a android.intent.action.MAIN -n #{package}/.#{main_activity}`
end
task :stop_app do
`adb shell ps | grep #{package} | awk '{print $2}' | xargs adb shell kill`
end
desc 'Restart the application'
task :restart => [:stop_app, :start_app]
task :uninstall do
puts "Uninstalling package #{package}"
system "adb uninstall #{package}"
end
namespace :install do
desc 'Uninstall, build, and install the application'
task :clean => [:uninstall, :install]
desc 'Build, install, and restart the application'
task :restart => [:install, :start_app]
namespace :restart do
desc 'Uninstall, build, install, and restart the application'
task :clean => [:uninstall, :install, :start_app]
end
end
file MANIFEST_FILE
file APK_FILE => MANIFEST_FILE do
puts "#{MANIFEST_FILE} changed. Forcing rebuild of #{APK_FILE}."
Rake::Task['debug'].invoke
end
desc 'Copy scripts to emulator or device'
task :update_scripts => [BUNDLE_JAR, APK_FILE] do
sdcard_path = "/mnt/sdcard/Android/data/#{package}/files"
app_files_path = "/data/data/#{package}/files"
if package_installed?
if device_path_exists?(sdcard_path)
puts 'Pushing files to apk public file area.'
data_dir = sdcard_path
elsif device_path_exists?(app_files_path)
puts 'Pushing files to apk private file area.'
data_dir = app_files_path
else
puts 'Cannot find the scripts directory on the device.'
puts 'If you have a non-rooted device, you need to add'
puts %q{ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />}
puts 'to the AndroidManifest.xml file to enable the update_scripts rake task.'
puts "Reverting to uninstalling and re-installing the apk."
Rake::Task['install:clean'].invoke
next
end
else
puts 'Cannot find the app on the device. Installing it.'
Rake::Task['install:clean'].invoke
next
end
last_update = File.exists?(UPDATE_MARKER_FILE) ? Time.parse(File.read(UPDATE_MARKER_FILE)) : Time.parse('1970-01-01T00:00:00')
Dir.chdir('assets') do
['scripts'].each do |asset_dir|
Dir["#{asset_dir}/*"].each do |asset_file|
next if File.directory? asset_file
next if File.ctime(asset_file) < last_update
print "#{asset_file}: " ; $stdout.flush
`adb push #{asset_file} #{data_dir}/#{asset_file}`
end
end
end
mark_update
end
namespace :update_scripts do
desc 'Copy scripts to emulator and restart the app'
task :restart => [:stop_app, :update_scripts, :start_app]
end
task :update_test_scripts do
test_scripts_path = "/data/data/#{package}.tests/files/scripts"
# TODO(uwe): Investigate if we can just push the scripts instead of building and installing the instrumentation APK
if package_installed?(true) && device_path_exists?(test_scripts_path)
Dir['test/assets/scripts/*.rb'].each do |script|
print "#{script}: " ; $stdout.flush
`adb push #{script} #{test_scripts_path}`
end
`adb shell ps | grep #{package}.tests | awk '{print $2}' | xargs adb shell kill`
else
Dir.chdir 'test' do
sh 'ant install'
end
end
end
task :test => :uninstall do
Dir.chdir('test') do
puts 'Running tests'
system "adb uninstall #{package}.tests"
system "ant run-tests"
end
end
namespace :test do
task :quick => [:update_scripts, :update_test_scripts] do
Dir.chdir('test') do
puts 'Running quick tests'
sh "ant run-tests-quick"
end
end
end
file 'Gemfile'
desc 'Generate bundle jar from Gemfile'
file BUNDLE_JAR => 'Gemfile' do
next unless File.exists? 'Gemfile'
puts "Generating #{BUNDLE_JAR}"
FileUtils.mkdir_p BUNDLE_PATH
sh "bundle install --path=#{BUNDLE_PATH}"
# FIXME(uwe): Should not be necessary. ARJDBC should not offer the same files as AR.
Dir.chdir "#{BUNDLE_PATH}/ruby/1.8/gems" do
scanned_files = []
Dir["*/lib/**/*"].each do |f|
raise "Malformed file name" unless f =~ %r{^(.*?)/lib/(.*)$}
gem_name, lib_file = $1, $2
if existing_file = scanned_files.find{|sf| sf =~ %r{(.*?)/lib/#{lib_file}}}
puts "Removing duplicate of file #{lib_file} in gem #{gem_name}"
puts "Already present in gem #{$1}"
end
end
end
# FIXME(uwe): Remove when directory listing in apk subdirectories work.
# FIXME(uwe): http://jira.codehaus.org/browse/JRUBY-5775
Dir["#{BUNDLE_PATH}/ruby/1.8/gems/activesupport-*/lib/active_support/core_ext.rb"].each do |faulty_file|
faulty_code = <<-'EOF'
Dir["#{File.dirname(__FILE__)}/core_ext/*.rb"].sort.each do |path|
require "active_support/core_ext/#{File.basename(path, '.rb')}"
end
EOF
replace_faulty_code(faulty_file, faulty_code)
end
Dir["#{BUNDLE_PATH}/ruby/1.8/gems/activemodel-*/lib/active_model/validations.rb"].each do |faulty_file|
faulty_code = <<-EOF
Dir[File.dirname(__FILE__) + "/validations/*.rb"].sort.each do |path|
filename = File.basename(path)
require "active_model/validations/\#{filename}"
end
EOF
replace_faulty_code(faulty_file, faulty_code)
end
FileUtils.rm_f BUNDLE_JAR
Dir["#{BUNDLE_PATH}/ruby/1.8/gems/*"].each_with_index do |gem_dir, i|
`jar #{i == 0 ? 'c' : 'u'}f #{BUNDLE_JAR} -C #{gem_dir}/lib .`
end
FileUtils.rm_rf BUNDLE_PATH
Rake::Task['install'].invoke
end
task :mark_update do
mark_update
end
# Methods
def mark_update
FileUtils.mkdir_p File.dirname(UPDATE_MARKER_FILE)
File.open(UPDATE_MARKER_FILE, 'w'){|f| f << Time.now.iso8601}
end
def strings(name)
@strings ||= REXML::Document.new(File.read('res/values/strings.xml'))
value = @strings.elements["//string[@name='#{name.to_s}']"] or raise "string '#{name}' not found in strings.xml"
value.text
end
def version() strings :version_name end
def app_name() strings :app_name end
def main_activity() manifest.root.elements['application'].elements["activity[@android:label='@string/app_name']"].attribute('android:name') end
def device_path_exists?(path)
path_output =`adb shell ls #{path}`
result = path_output.chomp !~ /No such file or directory|opendir failed, Permission denied/
puts "Checking path on device: #{path}: #{result || path_output}"
result
end
def package_installed? test = false
package_name = "#{package}#{'.tests' if test}"
['', '-0', '-1', '-2'].each do |i|
p = "/data/app/#{package_name}#{i}.apk"
o = `adb shell ls -l #{p}`.chomp
if o =~ /^-rw-r--r-- system\s+system\s+(\d+) \d{4}-\d{2}-\d{2} \d{2}:\d{2} #{File.basename(p)}$/
apk_file = test ? TEST_APK_FILE : APK_FILE
if !File.exists?(apk_file) || $1.to_i == File.size(apk_file)
puts "Found package #{p}"
return true
else
puts "Package #{p} installed, but of wrong size."
return false
end
end
end
puts "Package not found: #{package_name}"
return false
end
private
def replace_faulty_code(faulty_file, faulty_code)
explicit_requires = Dir["#{faulty_file.chomp('.rb')}/*.rb"].sort.map{|f| File.basename(f)}.map do |filename|
"require 'active_model/validations/#{filename}'"
end.join("\n")
old_code = File.read(faulty_file)
new_code = old_code.gsub faulty_code, explicit_requires
if new_code != old_code
puts "Replaced directory listing code in file #{faulty_file} with explicit requires."
File.open(faulty_file, 'w'){|f| f << new_code}
else
puts "Could not find expected faulty code\n\n#{faulty_code}\n\nin file #{faulty_file}\n\n#{old_code}\n\n"
end
end