Stories
Slash Boxes
Comments

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Idea! CPAN Version Advisories

Journal written by schwern (1528) and posted by brian_d_foy on 2007.09.16 21:26   Printer-friendly
My friend Jeff woke me up today because I IM'd him late last night saying "I have this great idea and I need to talk with someone about it!" This isn't that idea, but another one Jeff suggested.

We got to talking about the problem of CPAN dependencies. He mentioned that Python modules don't really have many dependencies, but they're not very complex either. CPAN modules can do some really complex things because they can let some other module do the work, but that leads to a long, and fragile, dependency chain.

We talked about some of the attempts to solve that and why they suck. They mostly revolve around depending on a fixed version. Debian packages can depend on a major version of another package (say, 3.x) and won't use a newer major version. Module::Install tries to solve it by shipping a fixed version of itself and any dependencies. only.pm tries to solve it by coding in specific versions. The problem with these approaches is they try to freeze the upgrade process.
The idea that modules get better over succeeding revisions is basically correct in the long run. Software is not wine, old versions don't get better with age. We just adapt to their quirks. The more adapted we are to a particular version's quirks the harder it becomes to upgrade. The dynamic upgrade environment avoids this sort of particularly nasty bit rot.

Jeff explained Debian's system and said it's to avoid API changes. Debian policy doesn't allow incompatible API changes within a major version. But that's not really CPAN's problem, they're usually bugs. With that realization, Jeff pointed out the key thing: the problems are *temporary*.

A single version of a CPAN module has a bug which breaks your dependency chain, but the next version will probably fix it. Or the next one, or the next one. Eventually, the march of versions forward will fix the problem. So hard coding "only use version 1.34" into your module takes a temporary problem and applies a permanent halt to upgrades.

So the solution should also be temporary and only last as long as the problem exists. Wouldn't it be neat if there was some way to flag the upgrade of a dependency to be problematic? Wouldn't it be neat if there was a way for the CPAN shell to query a service and request the advisories about a particular module? It's like traffic advisories.

"...and here's Michael Schwern with the CPAN traffic report. Michael?"

"Bill, I'm flying over the latest RSS feed and DBI is jack knifed across two lanes of dependency traffic. It looks like a bug fix in Test::More 0.71 revealed a flaw and caused DBI's test suite to skid. A couple of XML modules got tangled up in that crash, the patching crews expect to have them fixed by tomorrow evening. Those of you thinking about installing DBI should avoid the Test::More 0.71 and take the 0.70 instead today. We'll have more updates at the top of the hour. Over to Pudge with the sports. Pudge?"

"Today the Red Sox..."

What happens is when there's a dependency problem, say a bug fix in Test::More reveals test failures in DBI (which it does), the author of the dependent module (Andreas) can report a CPAN Version Advisory that DBI 1.59 and Test::More >= 0.71 are incompatible. When a user goes to install DBI the CPAN shell queries the service for any advisories. It uses that information to decide what to do. In this case it might say "DBI 1.59 is incompatible with your installed version of Test::More (0.71). Would you like to downgrade to 0.70?" It could even get clever and note that a given module is only a build requirement and temporarily downgrade just for the build and tests.

You could even go so far as to have the advisories contain a patch.

Later on, when DBI puts out a fixed version and the dependency conflict is resolved, Andreas can remove the advisory and dependency resolution marches forward as normal.

The advantages this has over hard-coding this information into, say, DBI's own Makefile.PL is that it's orthogonal to module releases. The problem occurs between DBI releases. DBI would have to release a new version just to say "I don't work with Test::More 0.71" and that's a lot of bother. It also does not require the author to issue the advisory. The author of the dependency could issue an advisory, or a trusted 3rd party. This removes several bottlenecks from the process.

It would seem to relieve much of the day-to-day problems with failing CPAN dependencies these days while hanging onto the basic, forward looking assumption that latest version good.
Display Options Threshold:
The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
  • An interesting idea. It actually crossed my mind that in many cases CPAN Testers spot these sort of incompatibilities, but with the scale of the reports and CPAN it could get tricky and very time consuming to review them all. Or were you only thinking of doing this with major distributions (e.g. Phalanx 100?), or when an actual user hits a problem?

    Once PITA is up and running, this sort of confirmation of fixes could be done fairly quickly, perhaps with an automated test harness that tests notable combinations of dependencies of a distribution. It might make authors more aware of older dependencies that should be avoided by upping the version in their prerequisites.

  • > What happens is when there's a dependency problem, say a bug fix in
    > Test::More reveals test failures in DBI (which it does), the author of
    > the dependent module (Andreas) can report a CPAN Version Advisory that
    > DBI 1.59 and Test::More >= 0.71 are incompatible. When a user goes to
    > install DBI the CPAN shell queries the service for any advisories. It
    > uses that information to decide what to do. In this case it might say
    > "DBI 1.59 is incompatible with your installed version of Test::More (0.71).
    > Would you like to downgrade to 0.70?" It could even get clever and note that
    > a given module is only a build requirement and temporarily downgrade just
    > for the build and tests.

    "Would you like to downgrade?"

    It's going to be extremely difficult for users in this situation. If we apply the "7 layers of recursion" principle, how are they going to have any idea what to do in this situation?

    Most likely they'll not know, but your question suggests they probably should.

    So they agree to a downgrade (which CPAN.pm doesn't REALLY know how to do properly anyway, except by installing over the top of the newer version) and now they have an older version of a module which breaks a dependency of something ELSE which needed the new version to work.

    I see lots of places where this could go wrong...

    Perhaps an alternative would be to flag the new Test::More version as "pathological", which would (temporarily) remove it from the index.

    This would let you "back out" a buggy (either itself, or downstream) released version, with the index reverting to an older version.

    You'd get a window to fix the downstream modules, and then you could enable that release again...

  • Nice timing! (Score:1)

    by ChrisDolan (2855) on 2007.09.18 0:10 (#57884) Homepage Journal
    This is well timed. A cpan-testers report [perl.org] from David Cantrell today revealed that Perl::Critic 1.072 made an API change that broke Perl::Critic::More. It's been broken for two weeks and 6 minor releases of Perl::Critic, but nobody noticed.

    So, we'll probably push out a Perl::Critic 1.078 soon, but in the meantime, you have to choose between Perl::Critic bug fixes or Perl::Critic::More passing its tests.

    The sad thing is that the failure happened while a test script was trying to decided if it was in "author mode" and consequently whether it should even run (the correct answer was no...)
  • by dito (152) on 2007.09.18 5:39 (#57886) Homepage

    The basic problem is that putting the burden of "what version can I use?" on the user is broken. By user I mean author of a module which uses another module. The library maintainer knows far more about compatibility than the average user and so the library maintainer should be able to publish that information (out of band).

    This post [blogspot.com] goes quite a bit further (probably too far for Perl). I actually implemented the engine for the abstract stuff in that post but the most important aspect is actually the interface. How to allow people to express compatibility without breaking their wrists or their brains.

  • by realzhang (8166) on 2007.09.18 5:46 (#57887)
    When I try to install DBIx::Class on WinXP with PPM, the error ocurs as follows: ERROR: File conflict for 'C:/Perl/html/site/lib/Test/Builder/Tester/Color.html'. The package Test-Simple has already installed a file that package Test-Builder-Tester wants to install. Who could help me? Thanks!!!
  • by Hercynium (8027) on 2007.09.18 8:33 (#57888)
    As I was reading the "Traffic Report" I thought to myself that it sounded just like the helicopter broadcasts on WBZ-1030 (AM Radio) here around Boston...

    So, ending with the Red Sox reference was a teriffic bit of irony :)
  • 'Nudder idea... (Score:1)

    by EvilSuggestions (8163) on 2007.09.18 18:08 (#57895)

    A long time ago, after a talk that Ingy gave about only.pm, I mentioned to him an idea I had that would avoid hard coding module versions into scripts, but would address the common issue that makes people want to use only.pm in the first place - that your script used to work, but installation of a later version of a module breaks it. And moreover, it leverages one of our favorite topics - testing!

    The basic idea is that you write a test suite for your script, run the suite (using some tool that's probably going to resemble prove with some added bells and whistles), and if it passes all tests, capture the list of modules loaded during testing and their associated versions (crawling %INC, etc), and put that somewhere as a "test certificate".

    Then, when running your script outside the test suite, it has some pragma like "use only::certified;" that reads the certificate, and loads only the module versions that passed certification testing earlier. Or to put that another way: in order to be used in your script, a particular version of a module must be "certified" for use in your script.

    Later on, newer versions of those modules could be installed, and other scripts on your system could use them, but your script should remain unharmed. If you then decide that you want to try to pick up newer module versions, you run through your certification process again, and only if all the tests pass does a new certificate get generated.

    Obviously, challenges like where do you store the certificates, testing scripts as opposed to modules, and capturing accurate module version info during testing would need considerable thought before something like this could be implemented, but that's the basic outline.

  • Sorry if this is a little bit terse, I don't have much time...

    1) Module authors list dependencies of their modules in Makefile.PL/Meta.yml (they already do, don't they?)

    2) PAUSE parses this info and puts it into a cross-reference DB.

    3) Authors can enter compatibility info into this DB via web interface, just saying "module M works with version X of module A and version Y of module B" or "module M doesn't work with version Z of module C". (could/should this be part of rt.cpan.org? I think so...)

    3a) can also be augmented by cpan-tester-results?

    4) CPAN publishes this x-ref list

    5) cpan(p?) shell can download this x-ref list and finally present intelligent suggestions/questions to the user:

    "by updating to version Z of module C you will break working module M. really proceed? N/y"

    "you want to install module M that requires module A. do you want to install the latest version of module A (which may or may not work with module M) or better install version X of module A that is known to work?"

    etc. etc. ad nauseam... :-)

    problem solved, now somebody go implement... *ggg*