[Rubygems-developers] PATCH: respect requirements of gems

Dick Davies rasputnik at hellooperator.net
Thu Apr 22 07:43:52 EDT 2004

* Mauricio Fern?ndez <batsman.geo at yahoo.com> [0439 08:39]:
> On Wed, Apr 21, 2004 at 09:14:32PM -0400, Chad Fowler wrote:
> > I don't, however, like the idea of gems being responsible for telling 
> > us which gems depend on them.  

I agree it's not  ideal, but I don't know who else would know,and
the key thing I was trying to achieve was calculating the dependants
(hmm, need a new word there) on demand...

One possibility I thought of was having the installed gem have a list
of what is using it, but I couldn't see a clean way of doing that,
and I don't understand exactly how a gemspec gets converted into an
installed gem. 
It's obviously a bit unrealistic to expect the log4r gemspec writer
to know in advance all packages that might ever use log4r :)

Plus that's more work and clutter across the code to do all this
book keeping.
(This is actually how NetBSD pkgsrc does it, but then that's written
using make, so it's hardly a poster child...)

Some kind of dynamic check before uninstall seemed like the simplest
way to get the safety without bloating other peoples code.

> I don't think this is too hard a 
> > problem, though.  We can always do something like (I haven't tried to 
> > run this yet):
> > 
> > def check_dependent_gems(gem_name, gem_version)
> >   dependent = []
> >   Gem::Cache.from_installed_gems.each do { |name, spec|
> >     spec.dependencies.each do |d|
> >       if(d.name == name and d.version == version) then
>            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> The problem is a bit harder than this, due to Rubygems being able
> to install several versions of a lib. at a time, and the fact that
> add_dependency can be used w/o an explicit API version specification.

Yeah, I got that far - that's why I ran away from version support. 
Things are further complicated by multiple versions, as you say, and
that a dependencies field can also specify a minimum version.

For example, if copland needs log4r > 1.0 and we have log4r 1.2
and 1.3, it is safe to remove either, and log4r 0.9 can go too,
since it doesn't help in any case.

How about this approach? Instead of second guessing who will miss
us when we run away from home, we go hide in the shed and see
who cries :)

We/you/I add a satisfied?() method to Gem::Dependency which takes
something like a Gem::Cache. It just checks that what is installed
contains what that gem needs.

Then when a gem is about to be uninstalled, a copy of the cache 
with the gem in question removed is passed to the satisfied()
method of each Dependency on the installed Gems.

If satisfied() returns false, that Gem will miss us when
we're gone, so uninstall stops.

All the version complexity is taken out of the uninstaller, and you
can use the satisfied() as part of installation too.
(For all I know that's what you already do, I haven't looked at 
the installer yet.)

IMO a gem should be able to tell us what it needs, so this 
would be the right place to do the checks.

Does that sound acceptable?

> IMHO, just like when installing, Rubygems should ensure that the system
> is not left in a broken state when removing packages.

That's essential IMO. If it can be done cleanly, that's great.
I think a temporary solution at least is needed before a next release.

A radioactive cat has eighteen half-lives.
Rasputin :: Jack of All Trades - Master of Nuns

More information about the Rubygems-developers mailing list