It’s actually quite obvious with such an introduction that I’m going to write again about ruby-ng.eclass that I’ve been working on since last month. While my original idea was to write the eclass, submit it on gentoo-dev the week after, and have it in production in just a month, it wasn’t that easy at all.
The first problem is that Ruby on Rails demotivated me with all the tests failing badly for one reason or the other; the second was that, by using an extended set of ebuilds as a test, I was actually able to find enough flaws in my original logics which really improved the situation.
Tonight I worked a bit more on the eclasses (because in the mean time I split it in two: ruby-ng and ruby-fakegem – I was tempted to call it ruby-jasper to play with the names Ruby and Gems, but the joke was probably lost on most people and it’s very likely it would be misunderstood entirely), and finally went around to add some declarative functions to add dependencies, as well as deciding to change further the design of the ebuilds.
The first step was to get rid of the double-inheritance problem that I’ve created in the previous iteration. The fakegem eclass allowed to define a single variable that provided dependencies that are both run-time and test-time (so build-time under test USE flag conditional). Unfortunately since these dependencies needed to have the proper dependencies set by
ruby_samelib (which creates the correct USE flag conditionals for the current Ruby implementations selected), which was provided by ruby-ng, but they also had to be defined before inheriting fakegem.
My new solution is to simply use a function call to add these dependencies, so for instance if a package were to need
dev-ruby/tzinfo, it would be doing something like this:
The eclass will translate that into adding that to
RDEPEND, and, in addition, adding it with a test conditional to
DEPEND. This has also the side effect of not limiting to fakegems, which is nice, although not strictly needed. It doesn’t stop here of course; because we have dependencies that are instead needed only at buildtime, and sometimes just when building docs or running tests. For that, there is a differently-named function that works just the same:
ruby_add_bdepend test virtual/ruby-test-unit
I’ve designed the function so that it only accepts either one or two parameters: with one parameter, it is interpreted as a space-separated list of atoms to depend on; with two, the first is interpreted as a space-separated list of conditions to have enabled to depend on the list, while the second is again the atoms list. Right now the actual code I have on the eclass is just written badly, before I commit it I have to make it less idiotic (because I admit it is, but it was also written at 3am on a night I was pretty depressed!).
You also might have noticed the
virtual/ruby-test-unit atom in the previous snippet. Indeed I started creating virtuals for Ruby stuff. Initially, I wanted to use a sophisticated, overcomplex and error-prone interface for the
ruby_add_[br]depend function that allowed to add a package to the list only when an implementation is selected, or for all implementations but one. But then the logical side of me took over and I finally decided to go with an easy, linear interface for the functions, and then add virtuals to the mix.
My reasons to choose virtuals are that the number of packages for which this treatment is needed is pretty low:
- rubygems, only needed on Ruby 1.8; both JRuby and Ruby 1.9 bring their own code;
- test-unit, that is provided by both Ruby 1.8 and JRuby, but has to be provided externally on Ruby 1.9, and the gem works on all three anyway;
- minitest, that is provided by Ruby 1.9 but neither by Ruby 1.8 nor JRuby;
- eventually rake (that JRuby provides in its own version!);
- almost surely ruby-openssl to request either the Ruby implementation with SSL support enabled, or the jruby-openssl package.
Considering this very modest amount of packages, adding complexity on the eclasses is exactly what I’d like to avoid; also, if the next implementation of Ruby we’re adding already comes with rubygems, but needs test-unit, or the other way around, we don’t want to have to change the dependencies of all the ebuilds, we just want to change the virtual, and then eventually add the new ruby implementations when needed.
I’m still not sure whether we should create a ruby-virtuals category (like we have java-virtuals) or go with virtual/ruby-* (like Perl is doing); the latter approach looks to me like it’s messy, but the former requires adding a new category. I won’t decide alone anyway, luckily.
So, did I get the eclasses ready for submittal? Well… no. There are quite a few more problems that I need to solve, for this to happen. The first problem is, obviously, to make sure that the tests work as they should; there are quite a few that needs to be fixed as I said, but I cannot really do that alone. Then there is the problem of deciding what the virtuals should look like. I should also check out a new JRuby ebuild for the testing bed overlay because currently it aliases the gems directory from Ruby 1.8 to JRuby which it shouldn’t, especially with the new support.
Again, there is to make sure that all the ebuilds in the overlay are working well, with all the dependency properly set in place and so on. More to this, there is need to ensure that all the stuff that is almost identical between the ebuilds is present in the eclass, but no overcomplexity is added to that either. One thing I need to tackle is documentation (re)generation and installation, because that really is important.
And also there are some very important issues of compatibility with what we have in portage right now: Hans should have added the new slotted version of ruby-gettext; we need to properly support slotted fake gems; in theory this only means that just the fakegem bin wrapper should be made to install the wrappers as
foo-$SLOT and find the correct version of the gem when looking up the path. Unfortunately I’ll have to study the gems API to find if and how that can be done. And we should make sure that all this works fine with eselect gem (or get it to!).
So the road is still long in front of us, but given that I’ve been working on this alone for the past weeks, I hope we’ll have something ready to enter the tree before end of summer.
After that somebody has to find a way to get Rails applications to install with ebuilds and be managed with
webapp-config or similar!