Dealing with broken Haskell packages

As we approach the release of GHC 7.10, there is a new wave of Haskell packages that require trivial fixes to build with the new versions of the compiler and standard libraries, but whose authors/maintainers are not around to apply the fixes. This is especially annoying when there is a pull request on GitHub, and all the maintainer would have to do is to press the green Merge button, and upload the new version on hackage.

If you are a responsible maintainer and don’t want this to happen to your packages in the future, you should appoint backup maintainers for your packages.

But what if you are a user of a package that remains broken on hackage, even though a fix is available? Here I review several ways to deal with this problem, including the new and promising Stackage snapshots.

Building the package locally

If all you care about is to get something installed locally (be it the broken package itself, or something that directly or indirectly depends on it), you can install the fixed version locally.

Non-sandboxed way

Check out the repository or branch with the fix, and cabal-install it:

% git clone -b ghc710 https://github.com/markus1189/feed.git % cabal install ./feed

(I prepend ./ to make sure cabal understands that I mean the directory, and not the package name on hackage.)

Sandboxed way

If you’re installing in the sandbox, then you can use add-source (although the non-sandboxed version will work in this case, too):

% git clone -b ghc710 https://github.com/markus1189/feed.git % cabal sandbox add-source feed % cabal install whatever-you-needed

If the package whatever-you-needed has feed among its transitive dependencies, cabal will automatically install it from the add-source’d directory.

Limitations

This approach doesn’t work well if:

You are a maintainer of a package that depends on the broken library. It’s hard to ask your users to check out and build the fixed version by hand. You work on an in-house application that your coworkers should be able to build, for the same reason.

Forking the package

You cannot upload the fixed version of a package on hackage bypassing the maintainer. However, you can upload it under a new name. This works well if you are a maintainer of a package that directly depends on the broken package, because you can easily make your package depend on your fork.

Examples of this are tasty depending on regex-tdfa-rc (a fork of regex-tdfa) and tasty-golden depending on temporary-rc (a fork of temporary).

Limitations

This doesn’t work well if there’s a chain of dependencies leading from your package to the broken one. You have to either persuade the other maintainer(s) to depend on your fork or fork the entire chain. If the broken package becomes actively developed again, you need to either move back to using it or backport the bugfixes from it to your fork. (I only fork packages when I find this scenario unlikely.) Other packages that depend on the broken package won’t automatically get fixed. Some people get upset when you fork packages.

Stackage snapshots

Instead of uploading the fixed version to hackage (which you can’t), you can upload it to Stackage instead, by creating a custom snapshot.

The procedure is described in Experimental package releases via Stackage Server. You create four files:

The fixed tarball (produced by cabal sdist ). You probably want to bump the package’s version, so that it doesn’t conflict with the version already on hackage.

). You probably want to bump the package’s version, so that it doesn’t conflict with the version already on hackage. Two text files: desc and slug . The first one contains a human-readable description of the snapshot; the second contains an id that will become part of the snapshot’s URL.

and . The first one contains a human-readable description of the snapshot; the second contains an id that will become part of the snapshot’s URL. A text file with the packages to be copied directly from hackage. For the purpose of this article, you probably want to leave this file empty. (I don’t know if it’s ok not to include it at all.)

Then you pack these four files into a tarball (that’s right, it’ll be a tarball with a tarball inside) and upload to stackage (after registering, if you haven’t registered before).

The outcome will be a custom hackage-like repository which will contain the single version of a single package — the one you’ve uploaded. (Of course, you can include multiple packages or versions if you like.)

The Stackage website will give you the remote-repo line that you can put into your cabal.config along with the hackage or stackage repos that are already there.

In contrast to building packages locally, you can easily tell your users or coworkers to add that repo as well.

Limitations

If the new hackage release of the broken package will get the same version number as your stackage version, there will be a conflict. (I actually don’t know what happens in that case; my guess is that cabal will silently pick one of the two available versions.) If the package you maintain (which depends on the broken package) is a small one, or is deep down the dependency chain, it may be hard to tell your users to add the repository. If, on the other hand, you maintain a major web framework or other such thing, it would probably work.

Taking over a package

There’s a procedure for taking over a package described on the wiki. You’ll need to contact the current maintainer; wait an indefinite amount of time (there’s no consensus about it; estimates vary from 2 weeks to 6-12 months); ask again on the mailing list and wait again; finally ask Hackage admins to grant you the rights.

Limitations