Module: Nuggets::Ruby
Overview
Heavily based on Phusion Passenger’s PlatformInfo module; see their code.
– Phusion Passenger - www.modrails.com/ Copyright © 2010 Phusion
“Phusion Passenger” is a trademark of Hongli Lai & Ninh Bui.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. ++
Constant Summary collapse
- CONFIG =
::RbConfig::CONFIG
- GEM_HOME =
gem_home- RUBY_ENGINE =
defined?(::RUBY_ENGINE) ? ::RUBY_ENGINE : 'ruby'
- OSX_RUBY_RE =
%r{\A/System/Library/Frameworks/Ruby.framework/Versions/.*?/usr/bin/ruby\Z}- UPDATE_RVM =
:nodoc:
%q{Please update RVM by running 'rvm update --head && rvm reload && rvm repair all'.}
Instance Attribute Summary collapse
-
#ruby_command ⇒ Object
Returns correct command for invoking the current Ruby interpreter.
-
#ruby_executable ⇒ Object
Returns the full path to the current Ruby interpreter’s executable file.
-
#rvm_path ⇒ Object
If the current Ruby interpreter is managed by RVM, returns the directory in which RVM places its working files.
-
#rvm_ruby_string ⇒ Object
If the current Ruby interpreter is managed by RVM, returns the RVM name which identifies the current Ruby interpreter plus the currently active gemset, e.g.
Instance Method Summary collapse
-
#command_for_ruby_tool(name) ⇒ Object
Returns the correct command string for invoking the
nameexecutable that belongs to the current Ruby interpreter. -
#locate_ruby_tool(name) ⇒ Object
Locates a Ruby tool command
name, e.g. - #ruby_options_to_argv(args, ruby_command = ruby_command) ⇒ Object
-
#ruby_sudo_command ⇒ Object
Returns either ‘sudo’ or ‘rvmsudo’ depending on whether the current Ruby interpreter is managed by RVM.
-
#ruby_supports_fork? ⇒ Boolean
Returns whether the Ruby interpreter supports process forking.
-
#rvm? ⇒ Boolean
Returns whether the current Ruby interpreter is managed by RVM.
Instance Attribute Details
#ruby_command ⇒ Object
Returns correct command for invoking the current Ruby interpreter. In case of RVM this function will return the path to the RVM wrapper script that executes the current Ruby interpreter in the currently active gem set.
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/nuggets/ruby.rb', line 76 def ruby_command return @ruby_command if defined?(@ruby_command) return @ruby_command = ruby_executable unless rvm? if name = rvm_ruby_string and dir = rvm_path if ::File.exist?(filename = ::File.join(dir, 'wrappers', name, 'ruby')) # Old wrapper scripts reference $HOME which causes # things to blow up when run by a different user. return @ruby_command = filename unless ::File.read(filename).include?('$HOME') end abort 'Your RVM wrapper scripts are too old. ' << UPDATE_RVM end # Something's wrong with the user's RVM installation. # Raise an error so that the user knows this instead of # having things fail randomly later on. # 'name' is guaranteed to be non-nil because rvm_ruby_string # already raises an exception on error. abort 'Your RVM installation appears to be broken: the RVM path cannot be found. ' << 'Please fix your RVM installation or contact the RVM developers for support.' end |
#ruby_executable ⇒ Object
Returns the full path to the current Ruby interpreter’s executable file. This might not be the actual correct command to use for invoking the Ruby interpreter; use ruby_command instead.
105 106 107 108 109 110 |
# File 'lib/nuggets/ruby.rb', line 105 def ruby_executable @ruby_executable ||= begin dir, name, ext = CONFIG.values_at(*%w[bindir RUBY_INSTALL_NAME EXEEXT]) ::File.join(dir, name + ext).sub(/.*\s.*/m, '"\&"') end end |
#rvm_path ⇒ Object
If the current Ruby interpreter is managed by RVM, returns the directory in which RVM places its working files. Otherwise returns nil.
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/nuggets/ruby.rb', line 132 def rvm_path return @rvm_path if defined?(@rvm_path) return @rvm_path = nil unless rvm? [::ENV['rvm_path'], '~/.rvm', '/usr/local/rvm'].compact.each { |path| path = ::File.(path) return @rvm_path = path if ::File.directory?(path) } # Failure to locate the RVM path is probably caused by the # user customizing $rvm_path. Older RVM versions don't # export $rvm_path, making us unable to detect its value. abort 'Unable to locate the RVM path. Your RVM ' << 'installation is probably too old. ' << UPDATE_RVM end |
#rvm_ruby_string ⇒ Object
If the current Ruby interpreter is managed by RVM, returns the RVM name which identifies the current Ruby interpreter plus the currently active gemset, e.g. something like this: “ruby-1.9.2-p0@mygemset”
Returns nil otherwise.
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 |
# File 'lib/nuggets/ruby.rb', line 157 def rvm_ruby_string return @rvm_ruby_string if defined?(@rvm_ruby_string) return @rvm_ruby_string = nil unless rvm? # RVM used to export the necessary information through # environment variables, but doesn't always do that anymore # in the latest versions in order to fight env var pollution. # Scanning $LOAD_PATH seems to be the only way to obtain # the information. # Getting the RVM name of the Ruby interpreter ("ruby-1.9.2") # isn't so hard, we can extract it from the #ruby_executable # string. Getting the gemset name is a bit harder, so let's # try various strategies... # $GEM_HOME usually contains the gem set name. return @rvm_ruby_string = ::File.basename(GEM_HOME) if GEM_HOME && GEM_HOME.include?('rvm/gems/') # User somehow managed to nuke $GEM_HOME. Extract info from $LOAD_PATH. $LOAD_PATH.each { |path| return @rvm_ruby_string = $1 if path =~ %r{^.*rvm/gems/([^/]+)} } # On Ruby 1.9, $LOAD_PATH does not contain any gem paths until # at least one gem has been required so the above can fail. # We're out of options now, we can't detect the gem set. # Raise an exception so that the user knows what's going on # instead of having things fail in obscure ways later. abort 'Unable to autodetect the currently active RVM gem set ' << "name. Please contact this program's author for support." end |
Instance Method Details
#command_for_ruby_tool(name) ⇒ Object
Returns the correct command string for invoking the name executable that belongs to the current Ruby interpreter. Returns nil if the command is not found.
If the command executable is a Ruby program, then we need to run it in the correct Ruby interpreter just in case the command doesn’t have the correct shebang line; we don’t want a totally different Ruby than the current one to be invoked.
If it’s not a Ruby program then it’s probably a wrapper script as is the case with e.g. RVM (~/.rvm/wrappers).
234 235 236 237 |
# File 'lib/nuggets/ruby.rb', line 234 def command_for_ruby_tool(name) filename = respond_to?(name) ? send(name) : locate_ruby_tool(name) shebang_command(filename) =~ /ruby/ ? "#{ruby_command} #{filename}" : filename end |
#locate_ruby_tool(name) ⇒ Object
Locates a Ruby tool command name, e.g. ‘gem’, ‘rake’, ‘bundle’, etc. Instead of naively looking in $PATH, this function uses a variety of search heuristics to find the command that’s really associated with the current Ruby interpreter. It should never locate a command that’s actually associated with a different Ruby interpreter.
NOTE: The return value may not be the actual correct invocation for the tool. Use command_for_ruby_tool for that.
Returns nil when nothing’s found.
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
# File 'lib/nuggets/ruby.rb', line 206 def locate_ruby_tool(name) extensions = ['', CONFIG['EXEEXT']].compact.uniq # Deduce Ruby's --program-prefix and --program-suffix from its install name # and transform the given input name accordingly. # # "rake" => "jrake", "rake1.8", etc [name, CONFIG['RUBY_INSTALL_NAME'].sub('ruby', name)].uniq.each { |basename| extensions.each { |ext| result = locate_ruby_tool_by_basename("#{basename}#{ext}") return result if result } } nil end |
#ruby_options_to_argv(args, ruby_command = ruby_command) ⇒ Object
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 |
# File 'lib/nuggets/ruby.rb', line 255 def (args, ruby_command = ruby_command) argv = [ruby_command] args.pop.each { |key, val| opt = "-#{key.to_s[0, 1]}" if val.is_a?(::Array) val.each { |wal| argv << opt << wal.to_s } elsif opt == '-e' argv << opt << val.to_s elsif val != false argv << "#{opt}#{val unless val == true}" end } if args.last.is_a?(::Hash) argv.concat(args.map! { |arg| arg.to_s.strip }) end |
#ruby_sudo_command ⇒ Object
Returns either ‘sudo’ or ‘rvmsudo’ depending on whether the current Ruby interpreter is managed by RVM.
192 193 194 |
# File 'lib/nuggets/ruby.rb', line 192 def ruby_sudo_command "#{'rvm' if rvm?}sudo" end |
#ruby_supports_fork? ⇒ Boolean
Returns whether the Ruby interpreter supports process forking.
115 116 117 118 119 120 121 122 |
# File 'lib/nuggets/ruby.rb', line 115 def ruby_supports_fork? # MRI >= 1.9.2's respond_to? returns false # for methods that are not implemented. ::Process.respond_to?(:fork) && RUBY_ENGINE != 'jruby' && RUBY_ENGINE != 'macruby' && CONFIG['target_os'] !~ /mswin|windows|mingw/ end |
#rvm? ⇒ Boolean
Returns whether the current Ruby interpreter is managed by RVM.
125 126 127 |
# File 'lib/nuggets/ruby.rb', line 125 def rvm? CONFIG['bindir'] =~ %r{/\.?rvm/} end |