lib/ruboto/util/setup.rb in ruboto-0.15.0 vs lib/ruboto/util/setup.rb in ruboto-0.16.0
- old
+ new
@@ -6,10 +6,13 @@
module Setup
include Ruboto::Util::Verify
REPOSITORY_BASE = 'http://dl-ssl.google.com/android/repository'
REPOSITORY_URL = "#{REPOSITORY_BASE}/repository-8.xml"
+ RUBOTO_GEM_ROOT = File.expand_path '../../../..', __FILE__
+ WINDOWS_ELEVATE_CMD = "#{RUBOTO_GEM_ROOT}/bin/elevate_32.exe -c -w"
+
#########################################
#
# Core Set up Method
#
@@ -27,11 +30,14 @@
def which(cmd)
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
exts.each do |ext|
exe = File.join(path, "#{cmd}#{ext}")
- return exe if File.executable? exe
+ if File.executable? exe
+ exe.gsub!('\\', '/') if windows?
+ return exe
+ end
end
end
nil
end
@@ -40,41 +46,50 @@
#########################################
#
# Utility Methods
#
+ MAC_OS_X = 'macosx'
+ WINDOWS = 'windows'
+ LINUX = 'linux'
+
def android_package_os_id
case RbConfig::CONFIG['host_os']
- when /^darwin(.*)/ then
- 'macosx'
- when /linux/ then
- 'linux'
- when /^mswin32|windows(.*)/ then
- 'windows'
+ when /^darwin(.*)/
+ MAC_OS_X
+ when /linux/
+ LINUX
+ when /^mswin32|windows|mingw32/
+ WINDOWS
else
## Error
nil
end
end
+ def mac_os_x?
+ android_package_os_id == MAC_OS_X
+ end
+
+ def windows?
+ android_package_os_id == WINDOWS
+ end
+
def android_package_directory
- if RbConfig::CONFIG['host_os'] =~ /^mswin32|windows(.*)/
- 'AppData/Local/Android/android-sdk'
- else
- ENV['ANDROID_HOME'] ? ENV['ANDROID_HOME'] : File.join(File.expand_path('~'), "android-sdk-#{android_package_os_id}")
- end
+ return ENV['ANDROID_HOME'] if ENV['ANDROID_HOME']
+ File.join File.expand_path('~'), windows? ? 'AppData/Local/Android/android-sdk' : "android-sdk-#{android_package_os_id}"
end
def path_setup_file
- case RbConfig::CONFIG['host_os']
- when /^darwin(.*)/ then
+ case android_package_os_id
+ when MAC_OS_X
'.profile'
- when /linux/ then
+ when LINUX
'.bashrc'
- when /^mswin32|windows(.*)/ then
- 'windows'
+ when WINDOWS
## Error
+ 'windows'
else
## Error
nil
end
end
@@ -82,74 +97,112 @@
def get_tools_version(type='tool')
require 'rexml/document'
require 'open-uri'
doc = REXML::Document.new(open(REPOSITORY_URL))
- doc.root.elements.to_a("sdk:#{type}/sdk:revision").map do |t|
+ version = doc.root.elements.to_a("sdk:#{type}/sdk:revision").map do |t|
major = t.elements['sdk:major']
minor = t.elements['sdk:minor']
micro = t.elements['sdk:micro']
version = major.text
version += ".#{minor.text}" if minor
version += ".#{micro.text}" if micro
version
- end.sort_by{|v| Gem::Version.new(v)}.last
+ end.sort_by { |v| Gem::Version.new(v) }.last
+
+ # FIXME(uwe): Temporary fix for bug in build-tools 19.0.0
+ return '18.1.1' if type == 'build-tool' && version == '19.0.0'
+ # EMXIF
+
+ version
end
#########################################
#
# Check Methods
#
def check_all(api_levels)
- @existing_paths = []
- @missing_paths = []
+ @existing_paths ||= []
+ @missing_paths ||= []
- @java_loc = check_for('java', 'Java runtime')
- @javac_loc = check_for('javac', 'Java Compiler')
+ @java_loc = check_for('java', 'Java runtime', ENV['JAVA_HOME'] && "#{ENV['JAVA_HOME']}/bin/java")
+ @javac_loc = check_for('javac', 'Java Compiler', ENV['JAVA_HOME'] && "#{ENV['JAVA_HOME']}/bin/javac")
@ant_loc = check_for('ant', 'Apache ANT')
check_for_android_sdk
check_for_emulator
+ check_for_haxm
check_for_platform_tools
check_for_build_tools
api_levels.each { |api_level| check_for_android_platform(api_level) }
+ @existing_paths.uniq!
+ @missing_paths.uniq!
+
puts
- ok = @java_loc && @javac_loc && @ant_loc && @android_loc && @emulator_loc && @adb_loc && @dx_loc && @platform_sdk_loc.all? { |_, path| !path.nil? }
+ ok = @java_loc && @javac_loc && @ant_loc && @android_loc && @emulator_loc && @haxm_kext_loc && @adb_loc && @dx_loc && @platform_sdk_loc.all? { |_, path| !path.nil? }
puts " #{ok ? '*** Ruboto setup is OK! ***' : '!!! Ruboto setup is NOT OK !!!'}\n\n"
ok
end
def check_for_emulator
@emulator_loc = check_for('emulator', 'Android Emulator',
File.join(android_package_directory, 'tools', 'emulator'))
end
+ def check_for_haxm
+ case android_package_os_id
+ when MAC_OS_X
+ @haxm_kext_loc = '/System/Library/Extensions/intelhaxm.kext'
+ found = File.exists?(@haxm_kext_loc)
+ @haxm_kext_loc = nil unless found
+ puts "#{'%-25s' % 'Intel HAXM'}: #{(found ? 'Found' : 'Not found')}"
+ @haxm_installer_loc = File.join(android_package_directory, 'extras', 'intel', 'Hardware_Accelerated_Execution_Manager', 'IntelHAXM.dmg')
+ @haxm_installer_loc = nil unless File.exists?(@haxm_installer_loc)
+ when LINUX
+ @haxm_installer_loc = 'Not supported, yet.'
+ @haxm_kext_loc = 'Not supported, yet.'
+ return
+ when WINDOWS
+ @haxm_kext_loc = `sc query intelhaxm`
+ found = ($? == 0)
+ @haxm_kext_loc = nil unless found
+ puts "#{'%-25s' % 'Intel HAXM'}: #{(found ? 'Found' : 'Not found')}"
+ @haxm_installer_loc = File.join(android_package_directory, 'extras', 'intel', 'Hardware_Accelerated_Execution_Manager', 'IntelHaxm.exe')
+ @haxm_installer_loc = nil unless File.exists?(@haxm_installer_loc)
+ return
+ end
+ end
+
def check_for_platform_tools
@adb_loc = check_for('adb', 'Android SDK Command adb',
- File.join(android_package_directory, 'platform-tools', 'adb'))
+ File.join(android_package_directory, 'platform-tools', windows? ? 'adb.exe' : 'adb'))
end
def check_for_build_tools
@dx_loc = check_for('dx', 'Android SDK Command dx',
- Dir[File.join(android_package_directory, 'build-tools', '*', 'dx')][-1])
+ Dir[File.join android_package_directory, 'build-tools', '*', windows? ? 'dx.bat' : 'dx'][-1])
end
def check_for_android_sdk
@android_loc = check_for('android', 'Android Package Installer',
- File.join(android_package_directory, 'tools', 'android'))
+ File.join(android_package_directory, 'tools', windows? ? 'android.bat' : 'android'))
end
def check_for(cmd, pretty_name=nil, alt_dir=nil)
rv = which(cmd)
- rv = nil if rv.nil? or rv.empty?
+ rv = nil if rv && rv.empty?
if rv
@existing_paths << File.dirname(rv)
- elsif alt_dir and File.exists?(alt_dir)
+ elsif alt_dir && File.exists?(alt_dir)
rv = alt_dir
- ENV['PATH'] = "#{File.dirname(rv)}:#{ENV['PATH']}"
+ if windows?
+ ENV['PATH'] = "#{File.dirname(rv).gsub('/', '\\')};#{ENV['PATH']}"
+ else
+ ENV['PATH'] = "#{File.dirname(rv)}:#{ENV['PATH']}"
+ end
@missing_paths << "#{File.dirname(rv)}"
end
puts "#{'%-25s' % (pretty_name || cmd)}: #{(rv ? 'Found' : 'Not found')}"
rv
@@ -173,24 +226,28 @@
def install_all(accept_all, api_levels)
install_java(accept_all) unless @java_loc && @javac_loc
install_ant(accept_all) unless @ant_loc
install_android_sdk(accept_all) unless @android_loc
- check_all(api_levels)
- install_android_tools(accept_all) unless @dx_loc && @adb_loc && @emulator_loc # build-tools, platform-tools and tools
+
+ # build-tools, platform-tools, tools, and haxm
+ install_android_tools(accept_all) unless @dx_loc && @adb_loc && @emulator_loc && @haxm_installer_loc
+ install_haxm(accept_all) unless @haxm_kext_loc
+
if @android_loc
api_levels.each do |api_level|
install_platform(accept_all, api_level) unless @platform_sdk_loc[api_level]
end
end
+ check_all(api_levels)
end
def install_java(accept_all)
- case RbConfig::CONFIG['host_os']
- when /^darwin(.*)/
- when /linux/
- when /^mswin32|windows(.*)/
+ case android_package_os_id
+ when MAC_OS_X
+ when LINUX
+ when WINDOWS
# FIXME(uwe): Detect and warn if we are not "elevated" with adminstrator rights.
#set IS_ELEVATED=0
#whoami /groups | findstr /b /c:"Mandatory Label\High Mandatory Level" | findstr /c:"Enabled group" > nul: && set IS_ELEVATED=1
#if %IS_ELEVATED%==0 (
# echo You must run the command prompt as administrator to install.
@@ -215,11 +272,11 @@
end
resp = process_response(resp)
open(java_installer_file_name, 'wb') { |file| file.write(resp.body) }
puts "Installing #{java_installer_file_name}..."
system java_installer_file_name
- raise "Unexpected exit code while installing Java: #{$?}" unless $? == 0
+ raise "Unexpected exit code while installing Java: #{$?.exitstatus}" unless $? == 0
FileUtils.rm_f java_installer_file_name
else
puts
puts 'You can download and install the Java JDK manually from'
puts 'http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html'
@@ -233,19 +290,19 @@
system %Q{setx JAVA_HOME "#{ENV['JAVA_HOME']}"}
@missing_paths << "#{File.dirname(@javac_loc)}"
end
end
else
- raise "Unknown host os: #{RbConfig::CONFIG['host_os']}"
+ raise "Unknown host os: #{android_package_os_id}"
end
end
def install_ant(accept_all)
- case RbConfig::CONFIG['host_os']
- when /^darwin(.*)/
- when /linux/
- when /^mswin32|windows(.*)/
+ case android_package_os_id
+ when MAC_OS_X
+ when LINUX
+ when WINDOWS
# FIXME(uwe): Detect and warn if we are not "elevated" with adminstrator rights.
#set IS_ELEVATED=0
#whoami /groups | findstr /b /c:"Mandatory Label\High Mandatory Level" | findstr /c:"Enabled group" > nul: && set IS_ELEVATED=1
#if %IS_ELEVATED%==0 (
# echo You must run the command prompt as administrator to install.
@@ -353,40 +410,35 @@
print 'Would you like to download and install it? (Y/n): '
a = STDIN.gets.chomp.upcase
end
if accept_all || a == 'Y' || a.empty?
Dir.chdir File.expand_path('~/') do
- case RbConfig::CONFIG['host_os']
- when /^darwin(.*)/
+ case android_package_os_id
+ when MAC_OS_X
asdk_file_name = "android-sdk_r#{get_tools_version}-#{android_package_os_id}.zip"
- system "wget http://dl.google.com/android/#{asdk_file_name}"
- system "unzip #{'-o ' if accept_all}#{asdk_file_name}"
- system "rm #{asdk_file_name}"
- when /linux/
+ download(asdk_file_name)
+ unzip(accept_all, asdk_file_name)
+ FileUtils.rm_f asdk_file_name
+ when LINUX
asdk_file_name = "android-sdk_r#{get_tools_version}-#{android_package_os_id}.tgz"
- system "wget http://dl.google.com/android/#{asdk_file_name}"
+ download asdk_file_name
system "tar -xzf #{asdk_file_name}"
- system "rm #{asdk_file_name}"
- when /^mswin32|windows(.*)/
+ FileUtils.rm_f asdk_file_name
+ when WINDOWS
# FIXME(uwe): Detect and warn if we are not "elevated" with adminstrator rights.
#set IS_ELEVATED=0
#whoami /groups | findstr /b /c:"Mandatory Label\High Mandatory Level" | findstr /c:"Enabled group" > nul: && set IS_ELEVATED=1
#if %IS_ELEVATED%==0 (
# echo You must run the command prompt as administrator to install.
# exit /b 1
#)
asdk_file_name = "installer_r#{get_tools_version}-#{android_package_os_id}.exe"
- require 'net/http'
- Net::HTTP.start('dl.google.com') do |http|
- puts 'Downloading...'
- resp = http.get("/android/#{asdk_file_name}")
- open(asdk_file_name, 'wb') { |file| file.write(resp.body) }
- end
+ download(asdk_file_name)
puts "Installing #{asdk_file_name}..."
- system asdk_file_name
- raise "Unexpected exit code while installing the Android SDK: #{$?}" unless $? == 0
+ system "#{WINDOWS_ELEVATE_CMD} #{asdk_file_name}"
+ raise "Unexpected exit code while installing the Android SDK: #{$?.exitstatus}" unless $? == 0
FileUtils.rm_f asdk_file_name
return
else
raise "Unknown host os: #{RbConfig::CONFIG['host_os']}"
end
@@ -394,43 +446,99 @@
end
check_for_android_sdk
unless @android_loc.nil?
ENV['ANDROID_HOME'] = (File.expand_path File.dirname(@android_loc)+'/..').gsub(File::SEPARATOR, File::ALT_SEPARATOR || File::SEPARATOR)
puts "Setting the ANDROID_HOME environment variable to #{ENV['ANDROID_HOME']}"
- if RbConfig::CONFIG['host_os'] =~ /^mswin32|windows(.*)/
+ if windows?
system %Q{setx ANDROID_HOME "#{ENV['ANDROID_HOME']}"}
end
@missing_paths << "#{File.dirname(@android_loc)}"
end
end
end
+ def download(asdk_file_name)
+ print "Downloading #{asdk_file_name}: \r"
+ uri = URI("http://dl.google.com/android/#{asdk_file_name}")
+ body = ''
+ Net::HTTP.new(uri.host, uri.port).request_get(uri.path) do |response|
+ length = response['Content-Length'].to_i
+ response.read_body do |fragment|
+ body << fragment
+ print "Downloading #{asdk_file_name}: #{body.length / 1024**2}MB/#{length / 1024**2}MB #{(body.length * 100) / length}%\r"
+ end
+ puts
+ end
+ File.open(asdk_file_name, 'wb') { |f| f << body }
+ end
+
+ def unzip(accept_all, asdk_file_name)
+ require 'zip'
+ Zip::File.open(asdk_file_name) do |zipfile|
+ zipfile.each do |f|
+ f.restore_permissions = true
+ f.extract { accept_all }
+ end
+ end
+ end
+
def install_android_tools(accept_all)
- if @android_loc and (@dx_loc.nil? || @adb_loc.nil? || @emulator_loc.nil?)
+ if @android_loc and (@dx_loc.nil? || @adb_loc.nil? || @emulator_loc.nil? || @haxm_installer_loc.nil?)
puts 'Android tools not found.'
unless accept_all
- print 'Would you like to download and install it? (Y/n): '
+ print 'Would you like to download and install them? (Y/n): '
a = STDIN.gets.chomp.upcase
end
if accept_all || a == 'Y' || a.empty?
- update_cmd = "android --silent update sdk --no-ui --filter build-tools-#{get_tools_version('build-tool')},platform-tool,tool -a --force"
+ android_cmd = windows? ? 'android.bat' : 'android'
+ update_cmd = "#{android_cmd} --silent update sdk --no-ui --filter build-tools-#{get_tools_version('build-tool')},extra-intel-Hardware_Accelerated_Execution_Manager,platform-tool,tool -a"
update_sdk(update_cmd, accept_all)
check_for_build_tools
check_for_platform_tools
check_for_emulator
+ check_for_haxm
end
end
end
+ def install_haxm(accept_all)
+ if @haxm_installer_loc && @haxm_kext_loc.nil?
+ puts 'HAXM not installed.'
+ unless accept_all
+ print 'Would you like to install HAXM? (Y/n): '
+ a = STDIN.gets.chomp.upcase
+ end
+ if accept_all || a == 'Y' || a.empty?
+ case android_package_os_id
+ when MAC_OS_X
+ system "hdiutil attach #{@haxm_installer_loc}"
+ # FIXME(uwe): Detect volume
+ # FIXME(uwe): Detect mpkg file with correct version.
+ system 'sudo -S installer -pkg /Volumes/IntelHAXM_1.0.6/IntelHAXM_1.0.6.mpkg -target /'
+ when LINUX
+ puts ' HAXM installation on Linux is not supported, yet.'
+ return
+ when WINDOWS
+ cmd = @haxm_installer_loc.gsub('/', "\\")
+ puts "Running the HAXM installer"
+ system %Q{#{WINDOWS_ELEVATE_CMD} "#{cmd}"}
+ raise "Unexpected return code: #{$?.exitstatus}" unless $? == 0
+ return
+ end
+ end
+ end
+ end
+
def install_platform(accept_all, api_level)
puts "Android platform SDK for #{api_level} not found."
unless accept_all
print 'Would you like to download and install it? (Y/n): '
a = STDIN.gets.chomp.upcase
end
if accept_all || a == 'Y' || a.empty?
- update_cmd = "android update sdk --no-ui --filter #{api_level},sysimg-#{api_level.slice(/\d+$/)} --all"
+ android_cmd = windows? ? 'android.bat' : 'android'
+ update_cmd = "#{android_cmd} update sdk --no-ui --filter #{api_level},sysimg-#{api_level.slice(/\d+$/)} --all"
update_sdk(update_cmd, accept_all)
check_for_android_platform(api_level)
end
end
@@ -463,17 +571,24 @@
# Path Config Method
#
def config_path(accept_all)
unless @missing_paths.empty?
- if RbConfig::CONFIG['host_os'] =~ /^mswin32|windows(.*)/
- puts "\nYou are missing some paths. Execute these lines to add them:\n\n"
+ puts "\nYou are missing some paths. Execute these lines to add them:\n\n"
+ if windows?
@missing_paths.each do |path|
puts %Q{ set PATH="#{path.gsub '/', '\\'};%PATH%"}
end
- system %Q{setx PATH "%PATH%;#{@missing_paths.map { |path| path.gsub '/', '\\' }.join(';')}"}
+ old_path = ENV['PATH'].split(';')
+ new_path = (@missing_paths.map { |path| path.gsub '/', '\\' } + old_path).uniq.join(';')
+ if new_path.size <= 1024
+ system %Q{setx PATH "#{new_path}"}
+ else
+ puts "\nYour path is HUGE: #{new_path.size} characters. It cannot be saved permanently:\n\n"
+ puts new_path.gsub(';', "\n")
+ puts
+ end
else
- puts "\nYou are missing some paths. Execute these lines to add them:\n\n"
@missing_paths.each do |path|
puts %Q{ export PATH="#{path}:$PATH"}
end
puts
unless accept_all