lib/rconf/configurators/ruby_configurator.rb in rconf-0.10.1 vs lib/rconf/configurators/ruby_configurator.rb in rconf-1.0.0

- old
+ new

@@ -16,22 +16,14 @@ include Configurator register :ruby description "Installs ruby interpreter and rubygems.\n" + - 'Installs and uses rvm on supported (i.e. non-Windows) platforms' + 'Installs and uses rbenv on supported (i.e. non-Windows) platforms' - setting 'version', 'Ruby version using rvm notation (see "rvm list known")', :required => true - setting 'rubygems', 'Rubygems version, e.g. "1.3.7"' - setting 'gemset', 'Gemset to be used for platforms supporting rvm' + setting 'version', 'Ruby version using rbenv notation (see "rbenv versions")', :required => true - # RVM version used to install rubies - RVM_VERSION = '1.10.2' - - # RVM releases URL - RVM_RELEASES_URL = 'https://rvm.io/releases' - # Let configurator run, it is idempotent # # === Return # false:: Always return false def check_linux @@ -39,82 +31,27 @@ end alias :check_darwin :check_linux alias :check_windows :check_linux # Switch to ruby version defined in settings - # Use rvm and install it if needed + # Use rbenv and install it if needed # # === Return # true:: Always return true def run_linux - check_rvm(RVM_VERSION) - return true if aborting - Command.set_ruby(version, gemset) - report_check("Checking whether #{version} is the active ruby") - out = Command.execute('rvm', 'current').output - if out =~ /^#{version.gsub('.', '\\.')}/ - report_success - check_rvmrc - else - report_failure - report_check("Switching to #{version}") - out = Command.execute('rvm', 'use', version).output - case out - when /is not installed\./ - report_failure - report_fatal "Failed to install #{ruby}" if @tried - Platform.dispatch(version) { :install_ruby } - @tried = true - Command.execute_in_ruby('gem', 'install', 'rconf') unless gemset - run - return true - when /^Using / - report_success - check_rvmrc - else - report_fatal("Failed to use #{version}:\n#{out}") - end + if Command.execute('rvm').success? + report_fatal "rconf detected an installation of RVM, rconf now uses rbenv to configure ruby versions.\n" + + "Unfortunately rbenv and RVM cannot be installed together on the same machine (see https://github.com/sstephenson/rbenv/).\n" + + "Please uninstall RVM and try again ('rvm implode' will delete RVM and all installed rubies and gems).\n" + + "Once RVM is uninstalled please start a new shell (you may also need to remove references to RVM from your ~/.bash_profile)" + return true end - if gemset - report_check("Checking whether gemset #{gemset} exists") - res = Command.execute('rvm', version, 'exec', 'rvm', 'gemset', 'list') - if res.output =~ /^(\s+|=> )#{gemset}$/ - report_success - else - report_failure - report_check("Creating gemset #{gemset} for #{version}") - Command.execute('rvm', version, 'exec', 'rvm', 'gemset', 'create', gemset, - :abort_on_failure => "Failed to create gemset '#{gemset}'") - end - report_check("Switching to gemset #{gemset}") - Command.execute('rvm', version, 'exec', 'rvm', 'gemset', 'use', gemset, - :abort_on_failure => "Failed to switch to gemset '#{gemset}'") - report_success - report_check("Checking whether rconf is installed") - res = Command.execute_in_ruby('rconf', '--version') - if res.output =~ /#{RightConf::VERSION}/ - report_success - else - report_failure - report_check("Installing rconf") - Command.execute_in_ruby('gem', 'install', 'rconf', :abort_on_failure => "Failed to install rconf") - report_success - end - end - if rubygems - report_check("Checking whether rubygems #{rubygems} is installed") - res = Command.execute_in_ruby('gem', '--version') - if res.success? && res.output =~ /^#{rubygems}$/ - report_success - else - report_failure - report_check("Installing rubygems #{rubygems}") - Command.execute_rvm('rubygems', rubygems, :abort_on_failure => 'Failed to install rubygems') - report_success - end - end - true + check_rbenv + return true if aborting + check_ruby + Command.set_ruby(ruby_version) + true end alias :run_darwin :run_linux # Switch to ruby version defined in settings # TBD @@ -122,97 +59,107 @@ # === Return # true:: Always return true def run_windows end - # Set command prefix when already configured - # Re-create .rvmrc if needed + protected + + # Make version compatible with RVM + def ruby_version + @ruby_version ||= version.start_with?('ruby-') ? version[5..-1] : version + end + + # Check whether rbenv and ruby-build are installed and installs it/them if not # # === Return # true:: Always return true - def post_process - Command.set_ruby(version, gemset) - check_rvmrc - true + def check_rbenv + res = Command.execute('rbenv') + rbenv_in_path = res.success? + if rbenv_in_path + res.output =~ /^rbenv ([0-9]+)\.([0-9]+)\.([0-9]+)$/ + maj, min, build = [$1.to_i, $2.to_i, $3.to_i] + if maj == 0 && min < 4 + report_fatal("rconf requires rbenv version 0.4.0 or greater, you have #{maj}.#{min}.#{build} installed, please upgrade (e.g. via brew upgrade rbenv) and try again") + end + return true + end + rbenv_present = File.exist?(File.join(ENV['HOME'], '.rbenv', 'bin', 'rbenv')) + update_msg = "You should add 'eval \"$(rbenv init -)\"' to your .bash_profile / .bashrc etc. " + + "so rbenv is properly initialized in new shells, the following assumes ~/.bash_profile is used (Mac OS X):\n\n" + + "echo 'eval \"$(rbenv init -)\"' >> ~/.bash_profile\n\n".blue + + "You should also update your PATH environment variable with:\n\n" + + "echo 'export PATH=\"$HOME/.rbenv/shims:$PATH\" >> ~/.bash_profile'\n".blue + if rbenv_present + post_note "rconf detected rbenv is installed in #{rbenv_path} but it is not in the PATH.\n" + update_msg + aborting(true) + return true + else + opts = { :report => true, :post_install => update_msg }.merge(abort_option('Failed to install rbenv')) + PackageInstaller.install('rbenv', opts) + opts = { :report => true }.merge(abort_option('Failed to install ruby-build')) + PackageInstaller.install('ruby-build', opts) { !Command.execute('ruby-build') } + true + end end - protected - - # Check whether the right version of RVM is installed and install it if not + # Check .ruby-version and its content # - # === Parameters - # version(String):: Version of RVM to be checked, e.g. '1.2.6' - # # === Return # true:: Always return true - def check_rvm(version) - report_check("Checking that rvm #{version} is installed") - out = Command.execute('rvm', '--version').output - if out =~ /rvm #{RVM_VERSION.gsub('.', '\\.')}/ - report_success - else - report_failure - if out =~ /rvm ([^\s]+)/ - report_error "WARNING!: You have rvm #{Regexp.last_match[1]} installed which may not be compatible with rconf.\n" + - "rconf will proceed and try to install rvm #{version}." + def check_ruby + exists = File.exist?('.ruby-version') + if exists + contents = IO.read('.ruby-version') + right_ruby = !!(contents =~ /#{ruby_version}/) + end + + unless exists && right_ruby + unless Command.execute('rbenv', 'local', ruby_version).success? + report_check("Installing ruby #{ruby} (this will take a while, please be patient)") + Platform.dispatch(ruby_version) { :install_ruby } + Command.execute('rbenv', 'local', ruby_version) end - report_check("Installing rvm #{version}") - rvm_src = File.join(ENV['HOME'] || '/root', '.rvm/src') - FileUtils.mkdir_p(rvm_src) - Dir.chdir(rvm_src) do - Command.execute('curl', '-O', '-f', - "#{RVM_RELEASES_URL}/rvm-#{version}.tar.gz", - :abort_on_failure => "Failed to download rvm #{version}") - Command.execute('tar', 'zxf', "rvm-#{version}.tar.gz", - :abort_on_failure => "Failed to extract rvm tgz from #{File.join(Dir.getwd, 'rvm-' + version + '.tar.gz')}") - end - Dir.chdir(File.join(rvm_src, "rvm-#{version}")) do - Command.execute('./install', :abort_on_failure => "Failed to install rvm #{version}") - end - post_note "Configuration required installing RVM, please start a new shell to activate it and re-run rconf to finish configuration".green - aborting(true) - report_success end - setup_bashrc true end - # Install given ruby version using rvm + # Install given ruby version using rbenv + # Install any prerequesites first # # === Parameters - # ruby(String):: Ruby version compatible with rvm + # ruby(String):: Ruby version compatible with rbenv # # === Return # true:: Always return true def install_ruby(ruby) Platform.dispatch(ruby) { :install_ruby_prerequisites } - report_check("Installing #{ruby} (this will take a while, please be patient)") - Command.execute('rvm', 'install', ruby, :abort_on_failure => 'Failed to install ruby') + # Can't abort on failure rbenv install seems to exist with a non zero error code even when successful :( + Command.execute('rbenv', 'install', ruby) report_success true end - # Install given ruby version using rvm - # On Lion, need to setup CC env var before running rvm install + # Install given ruby version using rbenv + # On Lion, need to setup CC env var before running rbenv install # # === Parameters - # ruby(String):: Ruby version compatible with rvm + # ruby(String):: Ruby version compatible with rbenv # # === Return # true:: Always return true def install_ruby_darwin(ruby) - report_check("Installing #{ruby} (this will take a while, please be patient)") - version = `system_profiler SPDeveloperToolsDataType -xml | xpath "//*[text()='_items']/following-sibling::array/dict/child::key[text()='spdevtools_version']/following-sibling::string/text()" 2> /dev/null` + c_version = `system_profiler SPDeveloperToolsDataType -xml | xpath "//*[text()='_items']/following-sibling::array/dict/child::key[text()='spdevtools_version']/following-sibling::string/text()" 2> /dev/null` env = {} - if version =~ /^4\.2\.[0-9]+/ + if c_version =~ /^4\.2\.[0-9]+/ if !File.executable?('/usr/bin/gcc-4.2') - report_fatal("The C compiler included with Xcode #{version} produces buggy ruby interpreters, please install the C compilers from https://github.com/downloads/kennethreitz/osx-gcc-installer/GCC-10.7-v2.pkg and re-run rconf") + report_fatal("The C compiler included with Xcode #{c_version} produces buggy ruby interpreters, please install the C compilers from https://github.com/downloads/kennethreitz/osx-gcc-installer/GCC-10.7-v2.pkg or update your version of Xcode and re-run rconf") else env['CC'] = '/usr/bin/gcc-4.2' end end - Command.execute('rvm', 'install', ruby, :abort_on_failure => 'Failed to install ruby', :env => env) + Command.execute('rbenv', 'install', ruby, :abort_on_failure => 'Failed to install ruby', :env => env) report_success end # Make sure to install all required linux packages first # @@ -252,83 +199,20 @@ # true:: Always return true def install_ruby_prerequisites_darwin(ruby) true end - # Check .rvmrc and its content - # - # === Return - # true:: Always return true - def check_rvmrc - if !File.exist?('.rvmrc') || IO.read('.rvmrc') !~ /#{version}@#{gemset}/ - report_check('Setting up .rvmrc') - begin - File.open('.rvmrc', 'w') do |f| - f.puts "environment_id=\"#{version}@#{gemset}\"" - f.puts RVM_HOOK - f.puts "type -P rconf &>/dev/null && { rconf; }" - f.puts "type -P rconf &>/dev/null || { echo 'rconf not installed, skipping (see .rvmrc)'; }" - end - report_success - post_note "Configuration required switching the active ruby\nPlease run " + 'cd ..;cd -'.blue + ' to activate it and finish configuration'.green - aborting(true) - rescue Exception => e - report_failure - report_error(e.message) - end - end - true - end - # rvm mojo for creating and enabling 'environments' - RVM_HOOK = <<-EOF -if [[ -d "${rvm_path:-$HOME/.rvm}/environments" \ - && -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]] -then - \. "${rvm_path:-$HOME/.rvm}/environments/$environment_id" - - if [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]] - then - . "${rvm_path:-$HOME/.rvm}/hooks/after_use" - fi -else - # If the environment file has not yet been created, use the RVM CLI to select. - if ! rvm --create "$environment_id" - then - echo "Failed to create RVM environment '${environment_id}'." - return 1 - fi -fi -if [[ $- == *i* ]] # check for interactive shells -then - echo "Using: $(tput setaf 2)$GEM_HOME$(tput sgr0)" # show the user the ruby and gemset they are using in green -else - echo "Using: $GEM_HOME" # don't use colors in interactive shells -fi - EOF - - # Setup .bashrc for rvm support + # Produce abort on failure option # - # === Return - # true:: Always return true - def setup_bashrc - if EnvironmentUpdater.update(rvm_bash_activation, ['PATH']) - post_note '.rvmrc was updated, please reload your shell to activate it and re-run rconf' - aborting(true) - end - end - - # rvm bash activation code + # === Parameters + # message(String):: Abort message to be used in case abort option should be set # # === Return - # code(String):: Code that needs to be added to bashrc to activate rvm - def rvm_bash_activation - code = <<EOS -export rvm_trust_rvmrcs_flag=1 -if [[ -n "$PS1" ]]; then - if [[ -s $HOME/.rvm/scripts/rvm ]] ; then source $HOME/.rvm/scripts/rvm ; fi -fi -EOS + # {}:: Empty hash if 'abort_on_failure' is notset + # opts(Hash):: Abort option with give message otherwise + def abort_option(message) + opts = abort_on_failure && { :abort_on_failure => message } || {} end end end