vigoo's software development blog

Haskell plugin for Gradle

Posted on April 22, 2015

My team at Prezi uses Haskell for several projects, which usually depend on each other, often with build steps using other languages such as Scala, C++ or Haxe. As Gradle is used heavily in the company, we decided to try to integrate our Haskell projects within Gradle.

The result is Gradle Haskell Plugin, which we were using succesfully in the last 2 months in our daily work, and we have open-sourced recently.

What makes this solution interesting is that it not just simply wraps cabal within Gradle tasks, but implements a way to define dependencies between Haskell projects and to upload the binary Haskell artifacts to a repository such as artifactory.

This makes it easy to modularize our projects, publish them, and also works perfectly with pride, an other open-source Prezi project. This means that we can work on a subset of our Haskell projects while the other dependencies are built on Jenkins, and it also integrates well with our non-Haskell projects.

How does it work?

The main idea is that we let cabal manage the Haskell packages, and handle whole Haskell sandboxes on Gradle level. So if you have a single Haskell project, it will be built using cabal and the result sandbox (the built project together with all the dependent cabal packages which are not installed in the global package database) will be packed/published as a Gradle artifact.

This is not very interesting so far, but when you introduce dependencies on Gradle level, the plugin does something which (as far as I know) is not really done by anyone else, which I call sandbox chaining. This basically means that to compile the haskell project, the plugin will pass all the dependent sandboxes' package database to cabal and GHC, so for the actual sandbox only the packages which are not in any of the dependent sandboxes will be installed.

Example

Let's see an example scenario with 4 gradle-haskell projects.

gradle-haskell-plugin

The project called Haskell project depends on two other projects, which taking into accound the transitive dependencies means it depends on three other haskell projects. Each project has its own haskell source and cabal file. Building this suite consists of the following steps:

For more information, check out the documentation.