Rubygems and Config::CONFIG


#1

Hello,

I have two versions of ruby installed, rooted at different source
trees. In order to make them not collide in my $PATH, I simply
configured one with a program-suffix:

EPREFIX1/bin/ruby
EPREFIX2/bin/ruby18

Life was peachy until I installed rubygems. The gems executables all
go in the ruby bindirs (alongside ruby and ruby18), but they ignore
any --program-prefix or --program-suffix. Would it not be a good idea
to have the executables named with the same prefix and suffix as the
ruby executable? I think the shebang lines should also be rewritten
to use the full path to the ruby executable used to run setup.rb.

Of course, this would make it impossible to move the ruby executable
without breaking gems, but I’d kinda expect a few things may break if
you were to pull a stunt like that.

Now, there’s no Config::CONFIG[‘program_suffix’] (or prefix), so it’d
probably be an idea to add these too. But they can also be sucked out
of Config::CONFIG[‘configure_args’] with Shellwords easily.

What do you think?


#2

On Thu, 16 Feb 2006, George O. wrote:

go in the ruby bindirs (alongside ruby and ruby18), but they ignore
probably be an idea to add these too. But they can also be sucked out
of Config::CONFIG[‘configure_args’] with Shellwords easily.

What do you think?

i have exactly the same issue here at work and i’m working with chad and
jim to
get something like this into rubygems now:

(gem script)

 #!/usr/bin/env ruby

 require 'rubygems'
 Gem.manage_gems

 required_version = Gem::Version::Requirement.new(">= 1.8.0")
 unless 

required_version.satisfied_by?(Gem::Version.new(RUBY_VERSION))
puts “Expected Ruby Version #{required_version}, was
#{RUBY_VERSION}”
exit(1)
end

 # We need to preserve the original ARGV to use for passing gem 

options
# to source gems. If there is a – in the line, strip all options
after
# it…its for the source building process.
args = !ARGV.include?("–") ? ARGV.clone :
ARGV[0…ARGV.index("–")]

 # allow env vars of GEM_xxx or command lines args of k=v to 

supercede any
# Config::CONFIG values kvs = []
#
# this allows commands like
#
# GEM_bindir=/usr/local/bin gem install arrayfields
#
# or
#
# gem install arrayfields bindir=/usr/local/bin
#
# note that any and all Config::CONFIG values may be tweaked for
fine
# grained control of install process.
#
re = %r/^ \s* ([^=\s]+) \s* = \s* ([^\s]+) \s* $/x
args.delete_if{|arg| (m = re.match(arg)) and (kvs <<
m.to_a.last(2))}
ENV::each{|k,v| (k =~ %r/^GEM_/) and (kvs << [k.delete(‘GEM_’),
v])}
unless kvs.empty?
require ‘rbconfig’
kvs.each{|k,v| Config::CONFIG[k] = v}
end

 Gem::GemRunner.new.run(args)

please try this out and let me know how it works for you.

kind regards.

-a


#3

removed_email_address@domain.invalid writes:

i have exactly the same issue here at work and i’m working with chad
and jim to get something like this into rubygems now:

(gem script)
[…]

please try this out and let me know how it works for you.

Hi Ara,

I think that might be addressing a different issue. That lets you
give `gem’ a bindir, etc. through envvars, so it can, e.g., install
each gem in a different location, right?

What I was proposing was that the `gem’ script itself should respect
the program prefix and suffix. For example, if I have two ruby
builds:

–prefix=/usr/local/ruby | --prefix=/usr/local/ruby18
| --program-suffix=18
-----------------------------±-----------------------------
/usr/local/ruby/bin/rdoc | /usr/local/ruby18/bin/rdoc18
/usr/local/ruby/bin/ri | /usr/local/ruby18/bin/ri18
/usr/local/ruby/bin/ruby | /usr/local/ruby18/bin/ruby18
/usr/local/ruby/bin/… | /usr/local/ruby18/bin/…

then:

cd rubygems-0.8.11 | cd rubygems-0.8.11
ruby setup.rb | ruby18 setup.rb

installs: | installs:
/usr/local/ruby/bin/gem | /usr/local/ruby18/bin/gem18
with shebang path: | with shebang path:
/usr/local/ruby/bin/ruby | /usr/local/ruby18/bin/ruby18

Should be easy to do; all the info needed is in Config::CONFIG.
gem18 install blah' would install gems in theruby18’ tree, and gem install blah' would install gems for in theruby’ tree. Complete
separation.

I don’t yet know whether exectuables installed by gems have suffixes
etc., but I think they should too: rake' should useruby’, rake18' should useruby18’. The rule of thumb would be that anything in the
ruby bin directory must have the program-prefix and program-suffix of
the ruby binary used to install it, and if it’s a ruby script, it must
use the complete path to that same ruby binary in its shebang. Note
that everything in the ruby bin dir from standard ruby already follows
this pattern. If rubygems was to become part of standard ruby, surely
it would follow suit.

I’m not sure what your scenario is, Ara, but might this be an
alternative to using environment variables?

The scenario that led me to this was having two rubies installed in
different directories. Since the name and content of the gem file is
fixed, installing rubygems with each ruby gave me:

/usr/local/ruby/bin/gem – with shebang line #!/usr/bin/env ruby
/usr/local/ruby18/bin/gem – with shebang line #!/usr/bin/env ruby

Not only does which gem depend on the PATH, but they both use
/usr/local/ruby/bin/ruby anyway. D’oh!

I imagine another fairly common scenario is to have more than one
build on a shared drive on a heterogenous network. e.g., a network of
Solaris and Linux hosts might have ruby mounted on a shared drive with
binaries ruby.i386 and ruby.sun5 in the same directory. In this case,
I think you’d similarly need a gem.i386' that usesruby.i386’, and a
gem.sun5' that usesruby.sun5’ (in the shebang). This would also
allow each gem to configure itself for the current platform if
necessary using Config::CONFIG.