[arch-general] Ruby gem packages in Arch
anatol.pomozov at gmail.com
Fri Jan 10 21:57:45 EST 2014
I manage a lot of Ruby packages (~230) in AUR, updated ~150 of them
recently. I would like to share my experience with herding these
packages. Some of the issues might be similar to other language
package systems (cpan, pip, nodejs).
First it worth mention that Ruby has its own packages manager
(rubygems). It is the standard and nearly all ruby software
distributed via rubygems. Rubygems has its package specification that
includes information like project homepage, developer contacts,
license, information about native dependencies. It makes sense to
parse those specifications and use it for PKGBUILD maintenance. The
idea is to have a script that will create ruby packages, will bump
versions, update dependencies if needed. And this scriptability is
important - copy/pasting ruby gems information is boring and
error-prone. There are several scripts that perform gem->arch
conversion and I work on one of them called 'gem2arch' .
>From other side rubygems differ from pacman that sometimes make it
harder to match packages. The main difference is that rubygems has
very flexible dependency mechanism. Several versions of a package can
be installed at the same time. Another package can specify custom
dependency restriction. It can depend on a specific version e.g.
'=4.0.2' or it can ask for a range of versions, or any crazy set of
restrictions like 'provide me package FOO with version between 2.3 and
3.1.4 but excluding 2.8 and 3.0.2'. The most popular type of
dependency restriction is 'approximately greater' aka '~>'. '~>3.0.3'
means 'give me package with version 3.0.XXX where XXX equal or larger
than 3'. '~>' is quite popular mechanism to stick to a specific
version range with stable API. Because rubygem can have several
versions of the package installed such restrictions do not block other
packages from using more recent versions. Thus package FOO might use
version 2.x while BAR uses 3.x and everyone is happy.
This dependency mechanism is different from the Arch where the
preferred form of dependency is 'use HEAD version'. Several versions
can be installed in Arch by adding version suffix to the package name
e.g. ruby1.8 or apachae2.2. But versioned packages is an exception
rather than rule in Arch. In rubygems using non-HEAD version is normal
and widely-used practice. ~20% of my ruby packages are versioned one,
e.g. ruby-rail-2 ruby-tilt-1. ruby-rails-2 means the latest version of
rails 2.xx and ruby-tilt-1 is the latest version of tilt 1.yy.
Dependency version calculation might be tricky in case of complex
dependency restrictions, e.g. foo-2.2.1 might be either 'foo',
'foo-2', 'foo-2.2' or 'foo-2.2.1' depending on what other released
version 'foo' has. Doing these calculations manually might be tricky
but thanks to 'gem2arch' it makes things easier.
In general adding/updating packages is a simple task (thanks to
gem2arch). Only small number of packages require custom modifications
like source patching or adding native dependencies.
Emphasizing importance of scripting I would like to mention a rule
that makes scripting harder. Ruby language page  says "For
libraries, use ruby-$gemname. For applications, use the program name".
How to calculate this rule in a script? Is a file in /usr/bin enough
to tell that this is an app? Actually a lot of the ruby libraries can
be used both as command-line application and a library (rake, rdoc,
rubygems, erubis, nokogiri, ....) it is safe to tell that all packages
in rubygems are libraries. If so I propose to change this rule to "all
ruby packages should be named ruby-$gemname". Other ruby users like
this idea .
Also some maintainers try to make package names nicer and do not
follow "ruby-$gemname" rule. For example 'rubyirc' gem was packed as
ruby-irc Arch package. It is harder for a script to match the gem to
this package. Also there was a problem when another gem called 'irc'
appeared, this one is actually should be used for 'ruby-irc' package.
So I propose another rule for Ruby (and other languages) - follow
'ruby-$gemname' even if gemname already contains a mention of 'ruby'.
To negative side of ruby packaging in AUR I can add bad situation with
inactive maintainers. The ruby packages are spread over many
maintainers most of which are inactive and do not update packages.
Ruby packages in AUR stay out-of-date for many months. In general I
think that for an active ruby development that does not require Arch
dependencies 'gem installed in $HOME' is better way to go.
More information about the arch-general