Want to know what I did for #hackweek8? I pulled ruby packaging apart and put it back together.
I... - split ruby-common from the ruby package, so it can also be used from ruby 1.8 distros - added patched rpms to devel:languages:ruby:backports for older distros to support overwriting macros and ruby dependencies (11.4 and sle11) - enhanced the %gem_install macro - wrote a gemspec to rpm converter to have requires and provides in rpm automatic without gem2rpm run - changed the gem2rpm template heavily
The key idea behind my work was that creating gem.rpm with gem2rpm is easy, updating is problematic (and over half the gems in dlre being outdated kind of proves my point :)
So the new template has no requires and no provides, because rpm can find out both from the installed .gemspec. E.g. I found a couple of cases that left broken provides with an update (e.g. 0.8.X providing _0_7). But this strange suffixing is no longer necessary anyway.
E.g. rails-3_2 has these automatic requires now:
ruby(abi) = 1.9.1 rubygem(1.9.1:actionmailer) = 3.2.7 rubygem(1.9.1:actionpack) = 3.2.7 rubygem(1.9.1:activerecord) = 3.2.7 rubygem(1.9.1:activeresource) = 3.2.7 rubygem(1.9.1:activesupport) = 3.2.7 rubygem(1.9.1:bundler) >= 1.0 rubygem(1.9.1:bundler) < 2 rubygem(1.9.1:railties) = 3.2.7
No more bundler-1_0, but a simple bundler < 2.
The automatic provides cover the old names, but I kind of hope we can drop them in the future:
rubygem(1.9.1:rails) = 3.2.7 rubygem(rails) = 3.2.7 rubygem-rails = 3.2.7 rubygem-rails-3 = 3.2.7 rubygem-rails-3_2 = 3.2.7 rubygem-rails-3_2_7 = 3.2.7
I do not generate buildrequires in the template either, even though this is a rather tough call.
We need buildrequires mainly to check that the dependencies are in the repo, but they create several problems: - gems build in "rings" and require a finished -> succeeded step for every ring, a rails update are 4 such rings. YOU GET CRAZY if the obs is busy! - you can't rely on automatism as the gem specificies "rails > 1.0", but there are 4 such rails versions and the build service wants to know which one you mean. And in case the rails version requires a rack > 1.1, it wants to know which one of those. YOU GET CRAZY!
As gem packaging has to be 99% automatic to compete with out of rpm gem, I went for calling gem install with -f and ignore buildignores.
To have a way to check dependencies in OBS, I created a small package called "all-good", that itself buildrequires all gems in the repository. That means for a rails update you will only need one ring: update all gems and then let the scheduler calculate if all-good can be expanded or if something misses dependencies. (all-good has a script to update the buildrequires if you had new gems)
As some gems require specific but old versions of other gems, I created (DISCLAIMER: careful, do not read further if you're easy to upset) a package containing all those gems. This package will build rpms for all gems in the source directory. While fixing the current dependencies, I found 33 gems that I didn't feel worthy enough for their own spec file, so they ended up in d:l:r:e/all-the-others.
It should be noted, that all the gems in there are of course tabu for factory submission. If you need a dependency in factory, create a spec file and dig out the license, gems are pretty bad in specifying the license in .gemspec, so most gem2rpm generated spec files have the CHECK(Ruby) license (even though most I found in practice have MIT).
As digging out the license is pretty boring work you don't want to do another time when updating the package, I changed gem2rpm to take the license from the output file in case there is no license in the gemspec.
This makes it possible to update to a newer version for gems pretty easy: gem2rpm *.gem -o *.spec.
Whenever a spec file needs manual adaption, I add a MANUAL comment in there, so you spot in a diff very easy that you need to check e.g. an extra buildrequire or some file list manipulation.
If the week had more days, I think I would put the whole %package and %files sections in a macro, so that we can (later) have ruby20 and ruby19 in parallel. If the requires are automatic and the buildrequires nonexistant, it's basically about the %files sections.