Mailinglist Archive: opensuse-ruby (11 mails)

< Previous Next >
Re: [opensuse-ruby] Revised gem packaging
On Mon, 30 Jul 2012 15:22:34 +0200
Stephan Kulow <coolo@xxxxxxx> wrote:


Want to know what I did for #hackweek8? I pulled ruby packaging apart
and put it back together.

- 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
- 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

I play with it now when I try to get working webyast and SLMS with new
gems and I found it really cool. Good work. One disadvantage is that
all dependencies need to be generated by new gem2rpm. I convert a lot
of gems in dlre, but more maybe will be needed.

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:

Please do not drop it in near future, as we use recent gems in ATK and
part of gems is also in SDK, so we want to be backward compatible if
customer create ruby/rails rpm with old dependencies.

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.

Yes, it is reasonable and helps with speed up of build.

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

We use for testing target rails appliance, that have rpm with

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.

I think we need to create policy for such packages. Example is
factory_girl, where I create old version because new one doesn't work
with ruby 1.9. I think that plain name should be always latest version
and create suffix only if you need old version. I use copypac with
specific revision and looks working for me.


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

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.

Greetings, Stephan

To unsubscribe, e-mail: opensuse-ruby+unsubscribe@xxxxxxxxxxxx
To contact the owner, e-mail: opensuse-ruby+owner@xxxxxxxxxxxx

< Previous Next >
List Navigation
Follow Ups