Going back in (dist) time

So you updated Quicklisp with (ql:update-dist "quicklisp"), and now a library you depended on is broken. It returns 42 from a function that previously returned 21, or maybe the API changed in an important incompatible way. Now your project is stalled and you have to figure out how to make things work again.

Quicklisp is designed with this situation in mind. Old project sources are kept around in indefinitely, and at a permanent URL, so you can go back to old sets of projects.

The user interface needs to be cleaned up, but here's how it works today:

* (use-package :ql-dist)
* (available-versions (dist "quicklisp"))
(("2011-07-30" . "http://beta.quicklisp.org/dist/quicklisp/2011-07-30/distinfo.txt") 
 ("2011-06-19" . "http://beta.quicklisp.org/dist/quicklisp/2011-06-19/distinfo.txt") 
 ("2011-05-22" . "http://beta.quicklisp.org/dist/quicklisp/2011-05-22/distinfo.txt") 
 ("2011-04-18" . "http://beta.quicklisp.org/dist/quicklisp/2011-04-18/distinfo.txt") 
 ("2011-03-20" . "http://beta.quicklisp.org/dist/quicklisp/2011-03-20/distinfo.txt") 
 ("2011-02-19" . "http://beta.quicklisp.org/dist/quicklisp/2011-02-19/distinfo.txt") 
 ("2011-01-10" . "http://beta.quicklisp.org/dist/quicklisp/2011-01-10/distinfo.txt") 
 ("2010-12-07" . "http://beta.quicklisp.org/dist/quicklisp/2010-12-07/distinfo.txt") 
 ("2010-11-07" . "http://beta.quicklisp.org/dist/quicklisp/2010-11-07/distinfo.txt") 
 ("2010-10-07" . "http://beta.quicklisp.org/dist/quicklisp/2010-10-07/distinfo.txt"))
* (install-dist "http://beta.quicklisp.org/dist/quicklisp/2011-06-19/distinfo.txt" :replace t)
lots of output

That set of commands will revert to the June, 2011 Quicklisp dist. So if your project critically depends on the versions you got in June, you can always go back to it.


  1. Argh! This deleted my whole dists directory.

    How about a dists/retired so that stuff doesn't disappear? Then when you go forward in (dist) time again, the stuff doesn't need to be downloaded and installed again.

  2. I'm not sure I want to keep archives around on the chance that they might be used in some future upgrade or downgrade, though it does make a lot of sense to keep archives around that are immediately applicable to the up/downgrade in progress. I'll see what I can do to make that work.

  3. This is starting to feel like perlbrew... and it's quite helpful for those that have to work with Perl.

  4. This just answered my main concern about replacing my current collection of manually-downloaded libraries. The last thing I need is the equivalent of "just grab the latest from svn," so the knowledge that I can pin everything to a specific release and then later upgrade the lot to a newer specific one is a huge relief.

  5. Does ':replace t' somehow hint at being able to install multiple versions of a library at the same time and just choose one in your project?

    I mean being able to choose the library version from the project source code, so that multiple projects can choose their own set of libraries as in: (ql:quickload "system" version).

  6. ':replace t' means that overwriting an existing dist of the same name is not an error.

    There's a mechanism in place to have multiple dists with overlapping projects and specifying which dist or project is the preferred source for a given system. But there isn't any way to specify that at quickload time, it's a global configuration property of the overall Quicklisp environment.

  7. OK, I must be doing something wrong, but don't know what. If I follow exactly what you say I get the following:

    The function COMMON-LISP-USER::AVAILABLE-VERSIONS is undefined.
    [Condition of type UNDEFINED-FUNCTION]

    Any pointers on how to get this working?

  8. The (use-package :ql-dist) part is very important.

  9. I also would like to be able to keep have several versions of the distr on the computer.

    I would suggest to keep the files distinfo.txt, systems.txt, releases.txt, etc. in a separate directory for every dist version.

    The software directory might be common, because the archives are uniquely named.

    So I could switch between distr version. This action will just use distrinfo.txt and friends from the folder named after the version. It will just tell quicklisp what version of every library to pick up from the software directory.

    As for cleaning the archives, it might be a separate action (by default it might be invoked in during dist update and similar actions, but with easy possibility to avoid this).