A Simplified Example Of A Dependency Problem We've Actually Seen In Fedora

Let's start by considering an example package: julep-1.0.

This version of the julep package Provides the usual things a package provides: itself, the files contained therein, etc. It also Requires a few things - in this case it requires the mint package and exactly version 1.0 of the bourbon package.

Under normal, real-world circumstances, there would be many, many more Provides and Requires - hence the ellipses. (For example, the evolution-data-server package Provides around 35 items and Requires about 100.) But as I said - this is a simplified example.[1]

So let's imagine what the whole repo might look like:

We have three packages - julep, bourbon, and mint. As mentioned, julep-1.0 requires mint and bourbon = 1.0. The mint-1.0 package provides mint, so that requirement is satisfied, and bourbon-1.0 satisfies the other dependency.

So: how does this picture change when an update is made available? Well, yum will choose the newest available version of the package - ignoring the old ones. So when mint-2.0 gets released:

Since mint-2.0 provides mint, all our dependencies are still satisfied, and mint-2.0 is accepted. Easy.

So what does depcheck do when a bad update gets proposed? Here's a simple example: what would happen if bourbon-2.0 was a new update?

Since julep-1.0 now has an unsatisfied dependency (there's no bourbon-1.0, since bourbon-2.0 replaced it) depcheck will reject the new bourbon update.[2] But! We can't simply discard the bourbon-2.0 update. Maybe it was part of a larger update, and we're about to also release julep-2.0:

Now that we have julep-2.0 - which requires bourbon-2.0 - everything is consistent and we can move forward. But if we had thrown out bourbon-2.0 when it failed originally, we'd now be rejecting julep-2.0 due to the missing bourbon-2.0! So even though both updates are OK when taken together, we would have rejected them both. No good!

But Of Course It's More Complicated Than That

But, of course, it's more complicated than that. One of the complications mentioned previously is multilib. So what does a multilib repo look like?

Basically it's the same stuff, except the repo contains two versions of some[3] packages - one i386 and one x86_64. The decision about which i686 packages should go into the repo is made by mash. Mostly this Just Works, but occasionally something weird happens - like an update which isn't considered multilib, even though the original package was. (this is what happened with the nss-softokn problems we've seen a couple of times.) For example, what if we got an update for mint that was x86_64 only?

You'll note that all the dependencies are satisfied, so depcheck will accept the update. It's a questionable change, but it doesn't technically cause any dependency problems on its own. But what would happen when (maybe a couple of days later) the new julep-3.0 package shows up, which requires mint-3.0?

And so depcheck will now reject julep-3.0 - even though it's basically valid - because it requires a package that doesn't exist on i386 anymore.

The conclusion you should be drawing here is that (while it does catch a lot of problems) there are problems that depcheck can't handle, and therefore we'll need to be aware of its shortcomings and design future tests to handle those problems.

1 Also, I'm not very good at Inkscape and I got tired of drawing boxes.
2 This also works if the new update has an unsatisfied dependency of its own - for example, if mint-3.0 required the non-existent package muddler.
3 In the Fedora 14 x86_64 repos there are currently about 22,900 packages, 4,500 of which are for i686.