This Time Self-Hosted
dark mode light mode Search

Rubygems… UNHACKED!

I have written yesterday about the difficulty of removing the Rubygems hacks we’ve been using — well, today I got a good news: I was able to mostly remove them. I say mostly because there are still a couple of things that need to be fixed, with the help of upstream (all my changes are available on my Rubygems fork in the gentoo branch):

  • there is no way in the original sources to change the location of the system configuration file; for Windows it’s found on the register, for everyone else it’s /etc; I’ve had to change the sources to allow for overriding that with the operating system defaults;
  • there is one test that actually only works if there is no alternate default set installed, as it checks that the binary directory of the gems is the same as the one for Ruby; that is no longer the case for us;
  • JRuby … pretty much fails a whole bunch of tests; some it’s not really its fault, for instance it lacks mkmf/extconf since that there are no C-compiled extensions; others are caused by different problems, such as tests’ ordering or the huge difference in handling of threading between the original implementations and JRuby;
  • I had to patch up a bit the Rakefile so that it can be used without Rubyforge support, which was a requirement for Ruby Enterprise (well at least for my system; the problem is that it still does not build with OpenSSL 1.0, so I have a non-OpenSSL Ruby Enterprise install… and that means that Rubyforge can’t load, and even so the Rubyforge plugin for Hoe);
  • documentation fails to build, not sure on why or how, but it does, when using the rake docs command; I’ll have to check out why and see if I can get it fixed.

But now back to the important good news: you can now safely use the gem command as root! Gems installed with sudo gem install foo will install in /usr/local rather than directly in /usr, no longer colliding or clashing with the Portage-installed packages (which are officially supported). Obviously, both are searched, but the local variant would take precedence, and the user’s home gems get even higher priority for search. This also means that if you don’t care about Gentoo support for the Ruby extensions, you can simply use gem and be done with it.

Now moving a bit back to not-too-good news and next steps. The not-too-good news is that since this dropped all the previously-present hacks, including a few needed to get gem from within Portage, this new version is not compatible with the old gems.eclass. Well, it’s relatively not good news, and partially good news; this is one of the final nails in that eclass’s coffin; we have now a very good reason to get rid of all the remaining packages; soon.

Note: I have said before that we still lack a way to properly build bindings that are part of bigger packages; luckily none of those require gems.eclass, they rather use the old ruby.eclass which does not require rubygems at all. So it’s fine to deprecate and get rid of the uses of that right now even though we might have more work to do before ruby-ng takes over everything.

Next steps for what concerns the rubygems package itself, if it was up to me, would be to drop the four gem18, gem19, gemee18 and jgem: all the ruby-fakegem.eclass binary wrappers right now install a single script, which by default uses the currently-configured Ruby interpreter, and you simply have to use ruby19 -S command to start it with a different interpreter. But gem itself is not treated this way and we rather have four copies of it with different names, and different shebangs, which sounds a waste. To change this, among other things, we need to change the eselect-ruby module (which I sincerely would avoid touching if possible).

Further step: supporting multiple Ruby implementation with the current system is mostly easy… but we have no way to change the current interpreter on a per-user or per-session basis; this is something that, as far as I can tell, we could actually take out of the Python book (or maybe the Java book, both have something like that, but the Python failures actually teach us one very important thing: we cannot use a script, we have to use a binary to do that job, even if it’s a very stupid one, as older Linux and other non-Linux systems will fail if you chain interpreters). Again, an eselect-ruby task… I would probably wait for Alex, unless there is enough interest for me to work on it.

Then let’s see, we’ve got to fully migrate out of the old-style virtual/ruby dependencies into =dev-lang/ruby-1.8* so that we can actually implement a new-style virtual that proxies the ssl USE flag, and then start using that; we’ve got to implement a general way to handle one-out-of-multiple target handling for packages that use Ruby as an embedded interpreter rather than build libraries for it; then there is again the problem of finding a way to build bindings within larger packages (or move some of them to build the Ruby extensions by themselves — I remember obexftp could use something like that), there is the fake-specification-generation to be fixed so that it works with bundler, and there are some (corner?) cases where Ruby 1.9 complain about missing fields in our generated files. So as you can see there is a long way still, but we’re going up there, step by step.

And before I leave, I’d like to thank Zeno Davatz for funding the un-hacking of rubygems — if that wasn’t the case, I’d probably have had to post this next week, or month. And if there are other people wanting Ruby 1.9 available faster (or improved 1.8 support), I’m still available to be hired, you can contact me and provide me with an idea of what you’re looking for. I’m available both to implement particular feature pieces, porting of the web of dependencies of given gems, or even just on a retainer basis so that you can have “priority” support for what concerns the general extension packaging in Gentoo.

Comments 3
  1. Excellent work, thank you!Now I still get the following error with gem18:~> gem18/usr/lib/ruby/site_ruby/1.8/rubygems/defaults/operating_system.rb:25:in `ruby_engine’: uninitialized constant Module::RUBY_DESCRIPTION (NameError) from /usr/lib/ruby/site_ruby/1.8/rubygems/defaults.rb:36:in `user_dir’ from /usr/lib/ruby/site_ruby/1.8/rubygems/defaults/operating_system.rb:15:in `default_path’ from /usr/lib/ruby/site_ruby/1.8/rubygems.rb:635:in `path’ from /usr/lib/ruby/site_ruby/1.8/rubygems/source_index.rb:68:in `installed_spec_directories’ from /usr/lib/ruby/site_ruby/1.8/rubygems/source_index.rb:58:in `from_installed_gems’ from /usr/lib/ruby/site_ruby/1.8/rubygems.rb:883:in `source_index’ from /usr/lib/ruby/site_ruby/1.8/rubygems/gem_path_searcher.rb:81:in `init_gemspecs’ from /usr/lib/ruby/site_ruby/1.8/rubygems/gem_path_searcher.rb:13:in `initialize’ from /usr/lib/ruby/site_ruby/1.8/rubygems.rb:841:in `new’ from /usr/lib/ruby/site_ruby/1.8/rubygems.rb:841:in `searcher’ from /usr/lib/ruby/site_ruby/1.8/rubygems.rb:840:in `synchronize’ from /usr/lib/ruby/site_ruby/1.8/rubygems.rb:840:in `searcher’ from /usr/lib/ruby/site_ruby/1.8/rubygems.rb:479:in `find_files’ from /usr/lib/ruby/site_ruby/1.8/rubygems.rb:983:in `load_plugins’ from /usr/lib/ruby/site_ruby/1.8/rubygems.rb:1139 from /usr/lib/ruby/site_ruby/1.8/auto_gem.rb:5:in `require’ from /usr/lib/ruby/site_ruby/1.8/auto_gem.rb:5

  2. Excellent work Diego. Thank you. RC3 solves the above problem. Also I needed to link /usr/bin/ruby1.9 to /usr/bin/ruby19 because I am on Funtoo.;)Pleasure working with you! Have a nice day!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.