Created
March 26, 2012 22:40
-
-
Save donv/2210325 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
if `ant -version` !~ /version (\d+)\.(\d+)\.(\d+)/ || $1.to_i < 1 || ($1.to_i == 1 && $2.to_i < 8) | |
puts "ANT version 1.8.0 or later required. Version found: #{$1}.#{$2}.#{$3}" | |
exit 1 | |
end | |
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 | |
def scripts_path() @sdcard_path ||= "/mnt/sdcard/Android/data/#{package}/files/scripts" end | |
def app_files_path() @app_files_path ||= "/data/data/#{package}/files" end | |
require 'rake/clean' | |
require 'rexml/document' | |
PROJECT_DIR = Dir.getwd | |
UPDATE_MARKER_FILE = File.expand_path(File.join('bin', 'LAST_UPDATE'), File.dirname(__FILE__)) | |
BUNDLE_JAR = File.expand_path 'libs/bundle.jar' | |
BUNDLE_PATH = File.expand_path 'bin/bundle' | |
MANIFEST_FILE = File.expand_path 'AndroidManifest.xml' | |
RUBOTO_CONFIG_FILE = File.expand_path 'ruboto.yml' | |
GEM_FILE = File.expand_path('Gemfile.apk') | |
GEM_LOCK_FILE = File.expand_path('Gemfile.apk.lock') | |
RELEASE_APK_FILE = File.expand_path "bin/#{build_project_name}-release.apk" | |
APK_FILE = File.expand_path "bin/#{build_project_name}-debug.apk" | |
TEST_APK_FILE = File.expand_path "test/bin/#{build_project_name}Test-debug.apk" | |
JRUBY_JARS = Dir[File.expand_path 'libs/jruby-*.jar'] | |
RESOURCE_FILES = Dir[File.expand_path 'res/**/*'] | |
JAVA_SOURCE_FILES = Dir[File.expand_path 'src/**/*.java'] | |
RUBY_SOURCE_FILES = Dir[File.expand_path 'src/**/*.rb'] | |
APK_DEPENDENCIES = [MANIFEST_FILE, RUBOTO_CONFIG_FILE, BUNDLE_JAR] + JRUBY_JARS + JAVA_SOURCE_FILES + RESOURCE_FILES + RUBY_SOURCE_FILES | |
KEYSTORE_FILE = (key_store = File.readlines('ant.properties').grep(/^key.store=/).first) ? key_store.chomp.sub(/^key.store=/, '') : "#{build_project_name}.keystore" | |
KEYSTORE_ALIAS = (key_alias = File.readlines('ant.properties').grep(/^key.alias=/).first) ? key_alias.chomp.sub(/^key.alias=/, '') : build_project_name | |
CLEAN.include('bin') | |
task :default => :debug | |
file JRUBY_JARS => RUBOTO_CONFIG_FILE do | |
next unless File.exists? RUBOTO_CONFIG_FILE | |
jruby_jars_mtime = JRUBY_JARS.map { |f| File.mtime(f) }.min | |
ruboto_yml_mtime = File.mtime(RUBOTO_CONFIG_FILE) | |
next if jruby_jars_mtime > ruboto_yml_mtime | |
puts '*' * 80 | |
if JRUBY_JARS.empty? | |
puts ' The JRuby jars are missing.' | |
else | |
puts " The JRuby jars need reconfiguring after changes to #{RUBOTO_CONFIG_FILE}" | |
puts " #{RUBOTO_CONFIG_FILE}: #{ruboto_yml_mtime}" | |
puts " #{JRUBY_JARS.join(', ')}: #{jruby_jars_mtime}" | |
end | |
puts ' Run "ruboto update jruby" to regenerate the JRuby jars' | |
puts '*' * 80 | |
end | |
desc 'build debug package' | |
task :debug => APK_FILE | |
namespace :debug do | |
desc 'build debug package if compiled files have changed' | |
task :quick => [MANIFEST_FILE, RUBOTO_CONFIG_FILE, BUNDLE_JAR] + JRUBY_JARS + JAVA_SOURCE_FILES + RESOURCE_FILES do |t| | |
build_apk(t, false) | |
end | |
end | |
desc "build package and install it on the emulator or device" | |
task :install => APK_FILE do | |
install_apk | |
end | |
namespace :install do | |
desc 'uninstall, build, and install the application' | |
task :clean => [:uninstall, APK_FILE, :install] | |
desc 'Install the application, but only if compiled files are changed.' | |
task :quick => 'debug:quick' do | |
install_apk | |
end | |
end | |
desc 'Build APK for release' | |
task :release => RELEASE_APK_FILE | |
file RELEASE_APK_FILE => [KEYSTORE_FILE] + APK_DEPENDENCIES do |t| | |
build_apk(t, true) | |
end | |
desc 'Create a keystore for signing the release APK' | |
file KEYSTORE_FILE do | |
unless File.read('ant.properties') =~ /^key.store=/ | |
File.open('ant.properties', 'a'){|f| f << "\nkey.store=#{KEYSTORE_FILE}\n"} | |
end | |
unless File.read('ant.properties') =~ /^key.alias=/ | |
File.open('ant.properties', 'a'){|f| f << "\nkey.alias=#{KEYSTORE_ALIAS}\n"} | |
end | |
sh "keytool -genkey -v -keystore #{KEYSTORE_FILE} -alias #{KEYSTORE_ALIAS} -keyalg RSA -keysize 2048 -validity 10000" | |
end | |
desc 'Tag this working copy with the current version' | |
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}'" | |
output = `git status --porcelain` | |
raise "Workspace not clean!\n#{output}" unless output.empty? | |
sh "git tag #{version}" | |
sh "git push origin master --tags" | |
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 | |
sh 'emulator -partition-size 1024 -avd Android_3.0' | |
end | |
task :start do | |
start_app | |
end | |
task :stop do | |
raise "Unable to stop app. Only available on emulator." unless stop_app | |
end | |
desc 'Restart the application' | |
task :restart => [:stop, :start] | |
task :uninstall do | |
uninstall_apk | |
end | |
file MANIFEST_FILE | |
file RUBOTO_CONFIG_FILE | |
file APK_FILE => APK_DEPENDENCIES do |t| | |
build_apk(t, false) | |
end | |
desc 'Copy scripts to emulator or device' | |
task :update_scripts => ['install:quick'] do | |
update_scripts | |
end | |
namespace :update_scripts do | |
desc 'Copy scripts to emulator and restart the app' | |
task :restart => APK_DEPENDENCIES do |t| | |
if build_apk(t, false) || !stop_app | |
install_apk | |
else | |
update_scripts | |
end | |
start_app | |
end | |
end | |
task :test => :uninstall do | |
Dir.chdir('test') do | |
puts 'Running tests' | |
sh "adb uninstall #{package}.tests" | |
sh "ant instrument install test" | |
end | |
end | |
namespace :test do | |
task :quick => :update_scripts do | |
Dir.chdir('test') do | |
puts 'Running quick tests' | |
sh 'ant instrument' | |
sh 'ant installi' | |
sh "ant run-tests-quick" | |
end | |
end | |
end | |
file GEM_FILE | |
file GEM_LOCK_FILE | |
desc 'Generate bundle jar from Gemfile' | |
task :bundle => BUNDLE_JAR | |
file BUNDLE_JAR => [GEM_FILE, GEM_LOCK_FILE] do | |
next unless File.exists? GEM_FILE | |
puts "Generating #{BUNDLE_JAR}" | |
FileUtils.mkdir_p BUNDLE_PATH | |
sh "gem install jruby-openssl-0.7.6.2.gem --install-dir #{BUNDLE_PATH}/ruby/1.8" | |
sh "bundle install --gemfile #{GEM_FILE} --path=#{BUNDLE_PATH}" | |
gem_path = Dir["#{BUNDLE_PATH}/*ruby/{1.8,shared}/gems"][0] | |
if package != 'org.ruboto.core' && JRUBY_JARS.none? { |f| File.exists? f } | |
Dir.chdir gem_path do | |
Dir['activerecord-jdbc-adapter-*'].each do |g| | |
puts "Removing #{g} gem since it is included in the RubotoCore platform apk." | |
FileUtils.rm_rf g | |
end | |
end | |
else | |
Dir.chdir gem_path do | |
Dir['jruby-openssl-*/lib'].each do |g| | |
rel_dir = "#{g}/lib/ruby" | |
unless File.exists? rel_dir | |
puts "Relocating #{g} files to match standard load path." | |
#FileUtils.rm_rf "#{g}/1.9" | |
dirs = Dir["#{g}/*"] | |
FileUtils.mkdir_p rel_dir | |
dirs.each do |d| | |
FileUtils.cp_r d, rel_dir | |
end | |
end | |
end | |
end | |
end | |
# Remove duplicate files | |
Dir.chdir gem_path do | |
scanned_files = [] | |
source_files = RUBY_SOURCE_FILES.map { |f| f.gsub("#{PROJECT_DIR}/src/", '') } | |
Dir["*/lib/**/*"].each do |f| | |
next if File.directory? 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 "Overwriting duplicate file #{lib_file} in gem #{$1} with file in #{gem_name}" | |
FileUtils.rm existing_file | |
scanned_files.delete existing_file | |
elsif source_files.include? lib_file | |
puts "Removing duplicate file #{lib_file} in gem #{gem_name}" | |
puts "Already present in project source src/#{lib_file}" | |
FileUtils.rm f | |
next | |
end | |
scanned_files << f | |
end | |
end | |
# Expand JARs | |
Dir.chdir gem_path do | |
Dir['*'].each do |gem_lib| | |
Dir.chdir "#{gem_lib}/lib" do | |
Dir['**/*.jar'].each do |jar| | |
if jar == 'arjdbc/jdbc/adapter_java.jar' | |
jar_load_code = <<-END_CODE | |
require 'jruby' | |
Java::arjdbc.jdbc.AdapterJavaService.new.basicLoad(JRuby.runtime) | |
END_CODE | |
elsif jar =~ /shared\/jopenssl.jar$/ | |
jar_load_code = <<-END_CODE | |
require 'jruby' | |
puts 'Starting JRuby OpenSSL Service' | |
public | |
Java::JopensslService.new.basicLoad(JRuby.runtime) | |
END_CODE | |
else | |
jar_load_code = '' | |
end | |
unless jar =~ /sqlite-jdbc/ | |
puts "Expanding #{gem_lib} #{jar} into #{BUNDLE_JAR}" | |
`jar xf #{jar}` | |
end | |
puts "Writing dummy JAR file #{jar + '.rb'}" | |
File.open(jar + '.rb', 'w') { |f| f << jar_load_code } | |
if jar.end_with?('.jar') | |
puts "Writing dummy JAR file #{jar.sub(/.jar$/, '.rb')}" | |
File.open(jar.sub(/.jar$/, '.rb'), 'w') { |f| f << jar_load_code } | |
end | |
FileUtils.rm_f(jar) | |
end | |
end | |
end | |
end | |
FileUtils.rm_f BUNDLE_JAR | |
Dir["#{gem_path}/*"].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 | |
end | |
# Methods | |
def mark_update(time = Time.now) | |
FileUtils.mkdir_p File.dirname(UPDATE_MARKER_FILE) | |
File.open(UPDATE_MARKER_FILE, 'w') { |f| f << time.iso8601 } | |
end | |
def clear_update | |
mark_update File.ctime APK_FILE | |
if device_path_exists?(scripts_path) | |
sh "adb shell rm -r #{scripts_path}" | |
puts "Deleted scripts directory #{scripts_path}" | |
end | |
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/ | |
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) | |
return true | |
else | |
return false | |
end | |
end | |
end | |
return nil | |
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 | |
def build_apk(t, release) | |
apk_file = release ? RELEASE_APK_FILE : APK_FILE | |
if File.exist?(apk_file) | |
changed_prereqs = t.prerequisites.select do |p| | |
File.file?(p) && !Dir[p].empty? && Dir[p].map { |f| File.mtime(f) }.max > File.mtime(APK_FILE) | |
end | |
return false if changed_prereqs.empty? | |
changed_prereqs.each { |f| puts "#{f} changed." } | |
puts "Forcing rebuild of #{apk_file}." | |
end | |
if release | |
sh 'ant release' | |
else | |
sh 'ant debug' | |
end | |
return true | |
end | |
def install_apk | |
case package_installed? | |
when true | |
puts "Package already installed." | |
return | |
when false | |
puts "Package installed, but of wrong size." | |
end | |
sh 'ant installd' | |
clear_update | |
end | |
def uninstall_apk | |
return if package_installed?.nil? | |
puts "Uninstalling package #{package}" | |
system "adb uninstall #{package}" | |
if $? != 0 && package_installed? | |
puts "Uninstall failed exit code #{$?}" | |
exit $? | |
end | |
end | |
def update_scripts | |
`adb shell mkdir -p #{scripts_path}` if !device_path_exists?(scripts_path) | |
puts "Pushing files to apk public file area." | |
last_update = File.exists?(UPDATE_MARKER_FILE) ? Time.parse(File.read(UPDATE_MARKER_FILE)) : Time.parse('1970-01-01T00:00:00') | |
# TODO(uwe): Use `adb sync src` instead? | |
Dir.chdir('src') do | |
Dir["**/*.rb"].each do |script_file| | |
next if File.directory? script_file | |
next if File.mtime(script_file) < last_update | |
next if script_file =~ /~$/ | |
print "#{script_file}: "; $stdout.flush | |
`adb push #{script_file} #{scripts_path}/#{script_file}` | |
end | |
end | |
mark_update | |
end | |
def start_app | |
`adb shell am start -a android.intent.action.MAIN -n #{package}/.#{main_activity}` | |
end | |
def stop_app | |
output = `adb shell ps | grep #{package} | awk '{print $2}' | xargs adb shell kill` | |
return output !~ /Operation not permitted/ | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
####################################################### | |
# | |
# ruboto/base.rb | |
# | |
# Code shared by other ruboto components. | |
# | |
####################################################### | |
# Only used needed for ruboto-core apps | |
require 'ruboto/version' | |
$RUBOTO_VERSION = 10 | |
def confirm_ruboto_version(required_version, exact=true) | |
raise "requires $RUBOTO_VERSION=#{required_version} or greater, current version #{$RUBOTO_VERSION}" if $RUBOTO_VERSION < required_version and not exact | |
raise "requires $RUBOTO_VERSION=#{required_version}, current version #{$RUBOTO_VERSION}" if $RUBOTO_VERSION != required_version and exact | |
end | |
require 'java' | |
$package_name = ($activity || $service || $broadcast_receiver).package_name | |
$package = eval("Java::#{$package_name}") | |
# Create convenience method for top-level android package so we do not need to prefix with 'Java::'. | |
module Kernel | |
def android | |
JavaUtilities.get_package_module_dot_format('android') | |
end | |
end | |
java_import "android.R" | |
module Ruboto | |
java_import "#{$package_name}.R" | |
begin | |
Id = JavaUtilities.get_proxy_class("#{$package_name}.R$id") | |
rescue NameError | |
Java::android.util.Log.d "RUBOTO", "no R$id" | |
end | |
end | |
AndroidIds = JavaUtilities.get_proxy_class("android.R$id") | |
# | |
# Callbacks | |
# | |
module Ruboto | |
module CallbackClass | |
def new_with_callbacks &block | |
new.initialize_ruboto_callbacks &block | |
end | |
end | |
module Callbacks | |
def initialize_ruboto_callbacks &block | |
instance_eval &block | |
setup_ruboto_callbacks | |
self | |
end | |
def ruboto_callback_methods | |
(singleton_methods - ["on_create", "on_receive"]).select{|i| i =~ /^on_/} | |
end | |
def setup_ruboto_callbacks | |
ruboto_callback_methods.each do |i| | |
begin | |
setCallbackProc(self.class.const_get(i.sub(/^on_/, "CB_").upcase), method(i)) | |
rescue | |
end | |
end | |
end | |
end | |
end | |
# | |
# Import a class and set it up for handlers | |
# | |
def ruboto_import(*package_classes) | |
java_import(package_classes).each do |package_class| | |
package_class.class_eval do | |
extend Ruboto::CallbackClass | |
include Ruboto::Callbacks | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'ruboto/activity' | |
require 'ruboto/widget' | |
require 'ruboto/util/toast' | |
require 'ruboto/util/stack' | |
ruboto_import_widgets :Button, :LinearLayout, :TextView | |
$activity.start_ruboto_activity "$sample_activity" do | |
setTitle 'This is the Title' | |
def on_create(bundle) | |
self.content_view = | |
linear_layout(:orientation => :vertical) do | |
@text_view = text_view :text => 'What hath Matz wrought?', :id => 42 | |
button :text => 'http', :width => :wrap_content, :id => 43, | |
:on_click_listener => @handle_click | |
button :text => 'https', :width => :wrap_content, :id => 44, | |
:on_click_listener => @handle_click | |
end | |
end | |
@handle_click = proc do |view| | |
Thread.start do | |
begin | |
run_on_ui_thread { toast 'Loading HTTPS library' } | |
with_large_stack { require 'net/https' } | |
run_on_ui_thread { toast 'Getting HTTPS response' } | |
response = nil | |
#host = 'evening-ocean-4975.herokuapp.com' | |
#host = 'www.google.com' | |
host = 'www.google.no' | |
uri = URI("#{view.text}://#{host}/") | |
use_ssl = view.text.to_s == 'https' | |
run_on_ui_thread { toast("host: #{uri.host}, port: #{uri.port}, ssl: #{use_ssl}") } | |
http = Net::HTTP.new(uri.host, uri.port) | |
http.use_ssl = use_ssl | |
http.verify_mode = OpenSSL::SSL::VERIFY_NONE | |
http.start do |http| | |
req = Net::HTTP::Get.new("/") | |
response = http.request(req) | |
resp = response.body | |
puts resp.inspect | |
response =resp | |
end | |
run_on_ui_thread { @text_view.text = response } | |
run_on_ui_thread { toast response } | |
run_on_ui_thread { @text_view.text = response } | |
rescue | |
puts "Got exception: #$!" | |
puts $!.backtrace.join("\n") | |
puts | |
e = $! | |
run_on_ui_thread do | |
toast "Exception: #{$!}" | |
@text_view.text = $!.to_s | |
end | |
end | |
end | |
end | |
end |
jruby-openssl 0.7.6.2 is 0.7.6.1 with some logging added. 0.7.6.1 is fully usable.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
a jruby-openssl 0.7.6.2 is referenced in the rakefile. does it matter whether it's 0.7.6.2 or 0.7.6.1? if so, is it possible to get 0.7.6.2?