Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 268857 - Patch to have ruby.eselect switch all executables provided by gems
Summary: Patch to have ruby.eselect switch all executables provided by gems
Status: RESOLVED WONTFIX
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: New packages (show other bugs)
Hardware: All Linux
: High normal (vote)
Assignee: Gentoo Ruby Team
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-05-06 21:21 UTC by Sven Schwyn (svoop)
Modified: 2010-07-29 10:07 UTC (History)
0 users

See Also:
Package list:
Runtime testing required: ---


Attachments
Patch to switch executables installed with the "gem" command. (ruby-eselect.patch,581 bytes, patch)
2009-05-06 21:22 UTC, Sven Schwyn (svoop)
Details | Diff
Patch to switch executables installed with the "gem" command. (ruby-eselect.patch,1.15 KB, patch)
2009-05-07 10:25 UTC, Sven Schwyn (svoop)
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Sven Schwyn (svoop) 2009-05-06 21:21:36 UTC
When both Ruby 1.8.x and 1.9.x is installed and gems with executables are installed using the "gem" comman rather than Portage (e.g. because the gems are installed by a rake task or because a gem is not available as an ebuild which is true for most bleeding edge gems from Github), the following can happen:

eselect ruby set ruby18
gem install rake          # => /usr/bin/rake is created with shebang ruby18
eselect ruby set ruby19
gem install rake          # => /usr/bin/rake is overwritten with shebang ruby19
eselect ruby set ruby18   # => /usr/bin/rake still uses ruby19

Furthermore if different versions of gems are used on the two profiles, the executables will still be overwritten and cause inconsistencies.

Reproducible: Always

Steps to Reproduce:




Here's a solution:


(1)

Extend the ruby.ebuild (for Ruby 1.9) and rubygems.ebuild to install the file /etc/gemrc with the following content:

<snippet begins>
--- 
gem: --format-executable
<snippet ends>

This will cause all executables installed by the "gem" command to get the version postfix 18 or 19, e.g. /usr/bin/rake18.

(2)

Apply the attached patch to eselect-ruby.ebuild. It extends the "create_symlinks" part to remove all unversioned executables and creates symlinks to the versioned executables.

(3)

Add informational text to eselect-ruby.ebuild, something like:

<snippet begins>
If you install gems with executables using the gem command, make sure to run the following command to make the executables available without version postfix:

eselect ruby set `eselect ruby show | grep ruby`

Furthermore, if you see this message for the first time, you should re-install all gems with executables in order to built them correctly.
<snippet ends>

(4)

Maybe a good extra would be a "rebuild" action for "eselect ruby" which sets the current profile  as the command in (3) does.


I've tried this approach with Ruby 1.8.x and 1.9.x and it works fine so far. Big thanks for considering this patch!
Comment 1 Sven Schwyn (svoop) 2009-05-06 21:22:46 UTC
Created attachment 190541 [details, diff]
Patch to switch executables installed with the "gem" command.
Comment 2 Hans de Graaff gentoo-dev Security 2009-05-07 06:02:46 UTC
Does this patch also work correctly when using eselect on gem modules? E.g. rails.eselect for Rails, or the more generic but still experimental gem.eselect module from the ruby overlay which manages gem binary symlinks for multiple slots.
Comment 3 Sven Schwyn (svoop) 2009-05-07 10:24:40 UTC
I guess it can be made compatible with rails.eselect (and gem.eselect which I haven't yet checked out).

But I'm not sure whether it's a good idea to introduce/use slotting for gems in the first place, because RubyGems already has slotting of sorts in place. Here's what the gem help says:

> For example `rake _0.7.3_ --version` will run rake version 0.7.3 if a newer
> version is also installed.

Is there a reason for having additional slotting on Portage level? Maybe redesigning gem.eselect to use the RubyGems slotting would be good common ground?

(I've extended the patch to include a "rebuild" task as described in (4) above.)
Comment 4 Sven Schwyn (svoop) 2009-05-07 10:25:50 UTC
Created attachment 190604 [details, diff]
Patch to switch executables installed with the "gem" command.
Comment 5 Hans de Graaff gentoo-dev Security 2009-05-08 05:17:26 UTC
(In reply to comment #3)

> the first place, because RubyGems already has slotting of sorts in place.
> Here's what the gem help says:
> 
> > For example `rake _0.7.3_ --version` will run rake version 0.7.3 if a newer
> > version is also installed.
> 
> Is there a reason for having additional slotting on Portage level? Maybe
> redesigning gem.eselect to use the RubyGems slotting would be good common
> ground?

rubygems slotting works fine for the files in /usr/lib/ruby/gems, but it simply overwrites the binaries in /usr/bin, so you'll end up with whatever the last version of the gem installed there. This usually works fine anyway since most of these /usr/bin files are just thin wrappers around invoking the code in /usr/lib, and many of them use the trick described above with rake to allow executing a particular version.

There are two problems with this:

1) portage does not allow this overwriting and will complain when one slot tries to overwrite files installed by another.
2) there are cases where the binaries between versions are not the same (gettext comes to mind here). 

2. may be an exception that we could solve in a different way, but in any case we need to solve 1.
Comment 6 Sven Schwyn (svoop) 2009-05-08 06:23:11 UTC
> 1) portage does not allow this overwriting and will complain when one slot
> tries to overwrite files installed by another.

The clean solution would be a patch to Portage: Allow a file to belong to more than one slot and only delete it once the last owning slot is uninstalled.

I don't know the guts of Portage well enough to tell whether this is doable, sounds like it to an outsider. What do you think?

> 2) there are cases where the binaries between versions are not the same
> (gettext comes to mind here). 

This is IMHO an upstream issue and if gettext breaks this behaviour, then it should be fixed there by slimming down the executable to a mere wrapper - as do the others.
Comment 7 Hans de Graaff gentoo-dev Security 2009-05-10 18:56:17 UTC
(In reply to comment #6)

> The clean solution would be a patch to Portage: Allow a file to belong to more
> than one slot and only delete it once the last owning slot is uninstalled.
> 
> I don't know the guts of Portage well enough to tell whether this is doable,
> sounds like it to an outsider. What do you think?

It sounds like an interesting idea, but I have no clue how feasible this is for portage or the other package managers. This would probably need to be an EAPI-related functionality. Perhaps you could raise this issue on the gentoo-dev list and see what happens?
Comment 8 Diego Elio Pettenò (RETIRED) gentoo-dev 2010-07-29 10:07:16 UTC
I guess this can be closed; while not perfect, the current fakegem solution fixes the problem of gems for multiple Ruby versions; just use ruby18 -S $foo or ruby19 -S $foo to get it with the non-default implementation.