Thursday, October 14, 2010

Enhanced Cabal SDist

Summary: I wrote a little script on top of cabal sdist that checks for common mistakes.

Cabal is the standard way to distribute Haskell packages, and has significantly simplified the process of installing libraries. However, I often make mistakes when creating cabal distributions using sdist. One common problem is that if you don't include a file in your .cabal file it will not be put in the distribution package and the package will fail to build for other people, but if the file is available locally it will still work for you. To work around this problem, I often perform a cabal install immediately after I upload a cabal package. Last week I discovered a package that I'd requested to be uploaded had suffered the same fate (hws – from the fantastic Haskell Workshop paper on writing a scalable web server in Haskell), showing this mistake isn't specific to me.

Eric Kow often says that programmers spend too little time writing tools to help their workflow. In response to this observation I have created the "neil" tool, available in darcs from http://community.haskell.org/~ndm/darcs/neil - darcs get and then cabal install. One feature of this neil tool is neil sdist. The actions neil sdist performs are:


  • cabal check

  • cabal configure to a temporary directory

  • cabal sdist to a temporary directory

  • change to that temporary directory

  • cabal configure –Werror –fwarn-unused-imports

  • cabal build

  • cabal haddock –executables



The intention is that this sequence of actions will fail if anything bad would happen on a users machine. If the file fails to build then cabal build will fail. If the haddock fails to generate than cabal haddock will fail. If there would be warnings during build then –Werror will cause it to fail. If all these checks pass then the package is likely to install without problems (once the cabal test feature is present then that can be included, which will give even more assurance).

I have deliberately not uploaded the neil tool to Hackage, and have no intention of doing so. The name "neil" is not suitable for Hackage, and I intend to add specific actions to help my workflow. If anyone wants to take any of the actions included in this tool and break them out in to separate tools, roll them back into cabal itself etc, they are very welcome.

Taking Eric's advice, I have found that by automating aspects of my workflow I can take steps which were error prone, or verbose, and make them concise and accurate. With neil sdist I have eliminated an entire class of potential errors, with very little ongoing work.

4 comments:

Anonymous said...

Is there any particular reason for "-Werror"?

In some of my packages there are warnings that I will not or cannot fix: for example, a couple of orphaned instances and importing an entity from another module solely so that haddock can find it and link to it.

Neil Mitchell said...

Ivan: Yes, I don't want the user to see any warnings flash by when they install my package. I turn off any warnings my packages give, I'm even happy to turn off warnings totally, but by the time I distribute I don't want users to see warnings (it looks unprofessional).

Duncan said...

There is a Cabal ticket requesting this feature.

http://hackage.haskell.org/trac/hackage/ticket/274

Perhaps you can convert your tool into a patch for cabal-install.

Neil Mitchell said...

Duncan: My code is hacky and works for me - but turning it into something production quality would be massive amounts of work. If anyone wants to start from what I've done they've very welcome to it, but I don't have the time to polish it up. Sorry...