[Fedora-packaging] New packaging guidelines for Ruby

Bohuslav Kabrda bkabrda at redhat.com
Tue Mar 6 05:50:02 UTC 2012


----- Original Message -----
> On Mon, Mar 05, 2012 at 01:50:04AM -0500, Bohuslav Kabrda wrote:
> > ----- Original Message -----
> > > On Fri, Mar 02, 2012 at 12:42:26AM -0500, Bohuslav Kabrda wrote:
> > > > ----- Original Message -----
> > > > > On Tue, Feb 28, 2012 at 4:47 AM, Bohuslav Kabrda
> > > > > <bkabrda at redhat.com>
> > > > > wrote:
> > > > > > ----- Original Message -----
> > > > > >> = ruby(name) vs rubygems(name) =
> > > > > >
> > > > > > Here is one important reason why Gems should not provide
> > > > > > ruby(name):
> > > > > > The ruby(name) provides are supposed to be provided by the
> > > > > > libraries, that are meant to be directly loadable with
> > > > > > "require
> > > > > > 'name'" even without Rubygems library. The Rubygems are
> > > > > > loaded
> > > > > > by
> > > > > > default in Ruby 1.9.3, but the users may choose not to load
> > > > > > them
> > > > > > by passing "--disable-gems" option to the interpreter
> > > > > > (either
> > > > > > directly or via environment variable RUBYOPT).
> > > > > > For a user, who turns of his Rubygems, a packaged Gem
> > > > > > providing
> > > > > > ruby(name) wouldn't load, while some other non-gem package
> > > > > > providing ruby(name) would load, which is obviously a
> > > > > > puzzling
> > > > > > behaviour.
> > > > > >
> > > > > If the guidelines are to assume that people are going to be
> > > > > passing
> > > > > --disable-gems then they must require that non-gem
> > > > > subpackages
> > > > > exist
> > > > > for all gems.  When a packager packages something that
> > > > > requires
> > > > > other
> > > > > ruby libraries they *must* inspect the code to see whether
> > > > > the
> > > > > code
> > > > > requires the gem or non-gem form.  Otherwise, libraries,
> > > > > applications,
> > > > > and scripts will break when the user runs with the
> > > > > --disable-gems
> > > > > option.
> > > > > 
> > > > > However, the argument that non-gem is legacy behaviour and
> > > > > should
> > > > > no
> > > > > longer be represented in packaging has been made.  After
> > > > > looking
> > > > > at
> > > > > how rubygems have become such an integral part of the ruby
> > > > > ecosystem,
> > > > > this seems reasonable to me but it does not just mean that
> > > > > the
> > > > > non-gem
> > > > > subpackages have been simplified away.  It also means that
> > > > > the
> > > > > Provides and Requires situation has been simplified as well.
> > > > >  If
> > > > > you
> > > > > want to keep the ruby()/rubygem() Provides split because
> > > > > people
> > > > > may
> > > > > run ruby with "--disable-gems" then we need to make non-gem
> > > > > subpackages mandatory as well.
> > > > > 
> > > > > -Toshio
> > > > 
> > > > A simple question: why would we mandate creating non-gem
> > > > subpackages? If the developer uses --disable-gems, then he
> > > > knows
> > > > he won't be able to require any gems. He may even base his code
> > > > on
> > > > it:
> > > > 
> > > > begin
> > > >   require 'mocha'
> > > > rescue LoadError
> > > >   Mocha = nil
> > > > end
> > > > 
> > > > if Mocha then
> > > >   # ...
> > > > else
> > > >   # ...
> > > > end
> > > > 
> > > > I believe that this simple piece of code says it all. The
> > > > developer
> > > > may be doing something _based on the fact that rubygems are/are
> > > > not loaded_. Therefore creating non-gem subpackages should be
> > > > forbidden. Please note, that --disable-gems can be used, for
> > > > example, for use-cases where hundreds of ruby interpreters run
> > > > in
> > > > parallel (not requiring rubygems can make things significantly
> > > > faster in this case), so I'm not just making all this up.
> > > > 
> > 
> > Hi Toshio,
> > I believe you didn't get my point, I'll try to explain it
> > differently:
> > You have a Ruby developer that is developing on some platform
> > (which might not be Fedora) and as Ruby developers do, he uses
> > Rubygems (installed by gem install command) and non-Gem libraries.
> > Let's say that the Gem is rubygem-mocha and the non-gem package is
> > ruby-bsearch. He installs mocha with "gem install mocha" and
> > installs ruby-bsearch as administrator somewhere under
> > %{ruby_sitelibdir}. If he runs the mentioned code with
> > --disable-gems, he is counting on mocha not to be requireable =>
> > therefore raise the LoadError, which he catches. In this case, he
> > still knows that he can require ruby-bsearch, as it is requireable
> > without Rubygems. So the application runs and does some very fast
> > stuff, because it's programmed that way. If the application is run
> > with Rubygems, mocha is requireable and application does something
> > different, which takes more time to do.
> > Now imagine a situation, that this developer deploys his
> > application to Fedora, where local adminstrator has installed
> > non-Gem subpackage of mocha. All of a sudden, the application
> > doesn't run properly, because mocha is requireable even with
> > --disable-gems. This is why non-Gem subpackages are bad and we
> > shouldn't create them: There is nothing like this in the Ruby
> > world, Ruby developers simply don't need it, will never use it and
> > it may even seriously break their applications.
> > Please note, that ruby-bsearch has Provides: ruby(bsearch), as it
> > is requireable with --disable-gems and mocha has Provides:
> > rubygem(mocha) as it is requireable only with Rubygems, which
> > makes perfect sense.
> > 
> What you're dealing with is broken upstream code.
> 

Nope. It may look broken to you, but it is not broken in the Ruby world. The only thing we can achieve by adding non-gem subpackages is breaking something, that is coded right. Is that really what we want?

> If the code is broken if the Mocha library is loadable, then the
> upstream
> should be fixed to not load mocha.
> 

The idea of the code is trying to load a library that may or may not load and do something based on it. There is nothing wrong with that.

> If the upstream wants to be runnable using mocha in some cases but
> not in
> other, then it should be fixed to take an option to control that.
> 
> Your hypothetical upstream is trying to use the ruby interpreter
> --disable-gems command line switch to do "something extra".  But
> there can
> be no assurance that that will do that extra thing.  What if the next
> version of bsearch is only packagd as a gem?  What if the next
> version of
> mocha only comes as a non-gem?  What if the system administrator has
> the
> gemdir for Mocha in their RUBYPATH?  Code that relies on a library
> being
> outside of the path in order to run correctly is buggy code.
> 

If next version of bsearch is only packaged as a gem, then we will have both ruby-bsearch and rubygem-bsearch (and please note, that the first one will provide ruby(bsearch) and the second one rubygem(bsearch) - do you see the difference now?), I see no problem with that. BUT, the developer still relies on the non-gem ruby-bsearch version and wants to use this one, not the gemified one, which might have changed. If he will want to depend on rubygem-bsearch, than he will change it for the new version and cope with it somehow. In the most unlikely scenario, where the next version of mocha comes out as non-gem library, the developer will obviously have to switch to something else. But you need to understand that switching from gem to non-gem in Ruby world is as likely as getting killed by falling piano.

> 
> For the rest of your comments, it's my turn to say, "I believe you
> didn't
> get my point".  Please go back and reread my scenarios and understand
> them.
> 

I reread them, didn't get your point again. Could you please be more obvious and tell me what I didn't get?

> -Toshio
> 
> > > If the developer codes something like that then a theoretical
> > > packaging of
> > > the code does not need to have a Requires: ruby(mocha) either.
> > >  So
> > > this
> > > example doesn't show that Requires: ruby(mocha) or Requires:
> > > rubygem(mocha)
> > > would have any effect.
> > > 
> > > Here's some examples of why I think that the Requires/Provides
> > > and
> > > the
> > > subpackages go hand in hand:
> > > 
> > > (1)
> > > * My script has a "require 'mocha'" which, in Fedora is the
> > > packaged
> > > non-gem
> > > * mocha has a "require 'latte'" which, in Fedora is only packaged
> > > as
> > > a gem.
> > >   ruby-mocha therefore has Require: rubygem(latte)
> > > 
> > > If I run my script with --disable-gem my script will fail even
> > > though
> > > mocha
> > > was packaged as a non-gem and knew to Require the rubygem version
> > > of
> > > latte..
> > > 
> > 
> > And this is precisely my point. It shows how creating and having
> > non-Gem subpackages installed may break code - a code which relies
> > on mocha not being requireable.
> > 
> > > (2)
> > > * My script has a "require 'mocha'".
> > > * mocha has a "require 'latte'" which in Fedora is only packaged
> > > as a
> > > gem.
> > > * The ruby-mocha package has Require: ruby(latte) since someone
> > > could
> > >   attempt to run mocha with --disable-gems.  Since there's no
> > >   ruby(latte)
> > >   Provides, ruby-mocha will either not pass review or fail to yum
> > >   install on
> > >   user's systems.
> > > 
> > 
> > This shows even further, how non-Gem subpackages are not only
> > dangerous, but also unnecessary load for the packagers.
> > 
> > > (3)
> > > * The web application better-cms is packaged in Fedora.  It
> > > Requires:
> > >   rubygem(latte) because it uses "require 'latte'"
> > > * I install that application on my server.
> > > * Because I want to make things faster, I try to run it with
> > > --disable-gems.
> > > * It fails because latte cannot be found if rubygems are not
> > > loaded.
> > > 
> > 
> > The developer of the better-cms knows, that if his application is
> > run with --disable-gems, it will not work. So he may tell his
> > users "never do this, it's not supported" or he just finds non-Gem
> > libraries, that he can use and use them. There isn't a single
> > person in the Ruby world that I know, who would be using something
> > like non-Gem subpackages. They are non-standard and dangerous and
> > as I have shown, they can break your code. So why do you want to
> > create them?
> > 
> > > In all of these cases a strict Require on whether the package
> > > needs
> > > the gem
> > > or non-gem version does not have an effect on whether the code in
> > > question
> > > will run -- it fails in all instances.  In all cases, having a
> > > non-gem
> > > version of the gem libraries is one way to solve the problem.  In
> > > all
> > > instances, deciding that rubygems must be loaded would also solve
> > > the
> > > problem.
> > > 
> > 
> > Nope. The code in question will not run properly only in the case
> > that the non-Gem subpackage is installed. Otherwise, it will work
> > just fine and the way it was supposed to run. Moreover, the
> > Provides: ruby(bsearch) and rubygem(mocha) make sense, since the
> > first provide says, that the bsearch library is required with
> > --disable-gems, while mocha is not.
> > 
> > > -Toshio
> > 
> > --
> > Regards,
> > Bohuslav "Slavek" Kabrda.
> > --
> > packaging mailing list
> > packaging at lists.fedoraproject.org
> > https://admin.fedoraproject.org/mailman/listinfo/packaging
> 
> --
> packaging mailing list
> packaging at lists.fedoraproject.org
> https://admin.fedoraproject.org/mailman/listinfo/packaging

-- 
Regards,
Bohuslav "Slavek" Kabrda.


More information about the packaging mailing list