Recently I wrote a couple of little scripts for helping build haskell projects on nixos. Here’s how to use them to help build a yesod project.

In this example I’ve checked out my scripts with git into my home directory, like so:

[bburdette@nixosthe1 ~]$ git clone https://github.com/bburdette/hsnixinit.git

Here I’m assuming that there’s no ghc (or yesod) installed with nix-env. I like to leave them uninstalled, and set up dependencies in my projects to pull them in as needed. However, to get started we’ll need the ‘yesod’ utility to create a yesod skeleton project. At this point I should say I’m planning to use a nixpkgs repo that I cloned, in case I want to add some packages (purescript). Its important to use the yesod-bin that goes with this repo, because of all the version dependencies it puts into the .cabal file when you make a scaffolding project. If you don’t plan on using your own repo, just omit “~/nixpkgs” in the steps below.

So let’s install yesod-bin from my nixpkgs repo:

[bburdette@nixosthe1 blah3]$ nix-env -i yesod-bin -f ~/nixpkgs installing `yesod-bin-1.2.12.3' building path(s) `/nix/store/xci405330nsjqwmk4qw7azglgdfzbw0s-user-environment' created 6095 symlinks in user environment [bburdette@nixosthe1 blah3]$ cd .. [bburdette@nixosthe1 ~]$ yesod init Welcome to the Yesod scaffolder. I'm going to be creating a skeleton Yesod project for you. What do you want to call your project? We'll use this for the cabal name. Project name: blah4 Yesod uses Persistent for its (you guessed it) persistence layer. This tool will build in either SQLite or PostgreSQL or MongoDB support for you. We recommend starting with SQLite: it has no dependencies. s = sqlite p = postgresql pf = postgresql + Fay (experimental) mongo = mongodb mysql = MySQL simple = no database, no auth url = Let me specify URL containing a site (advanced) So, what'll it be? s That's it! I'm creating your files now... --------------------------------------- ___ {-) |\ [m,].-"-. / [][__][__] \(/\__/\)/ [__][__][__][__]~~~~ | | [][__][__][__][__][] / | [__][__][__][__][__]| /| | [][__][__][__][__][]| || | ~~~~ ejm [__][__][__][__][__]__,__, \__/ --------------------------------------- The foundation for your web application has been built. There are a lot of resources to help you use Yesod. Start with the book: http://www.yesodweb.com/book Take part in the community: http://yesodweb.com/page/community Start your project: cd blah4 && cabal sandbox init && cabal install --enable-tests . [bburdette@nixosthe1 ~]$ nix-env -e yesod-bin uninstalling `yesod-bin-1.2.12.3'

Ok, now I have a blah4.cabal file. I uninstalled yesod-bin again at the end so I won’t use the wrong version for creating another project. Now to create a shell.nix and default.nix to pull in the dependencies – ghc, etc.

[bburdette@nixosthe1 blah4]$ ~/hsnixinit/setup.sh blah4 ~/nixpkgs [bburdette@nixosthe1 blah4]$ ls app devel.hs Model.hs shell.nix Application.hs Foundation.hs blah4.cabal static config Handler ns templates default.nix Import.hs Settings tests deploy messages Settings.hs

So the new files are default.nix, shell.nix and the script ns. Next, let’s pull in the dependencies with the ‘ns’ script – which is just a shortcut for “nix-shell -I nixpkgs=~/nixpkgs”. At this stage you may get a lot of compiling happening, or downloading of binary packages. On my system I already have the packages so it only changes the prompt to nix-shell.

Once ‘ns’ completes, then we “cabal sandbox init”, and then “cabal install” to build the project.

[bburdette@nixosthe1 blah4]$ ./ns [nix-shell:~/blah4]$ cabal sandbox init Writing a default package environment file to /home/bburdette/blah4/cabal.sandbox.config Creating a new sandbox at /home/bburdette/blah4/.cabal-sandbox [nix-shell:~/blah4]$ cabal install Resolving dependencies... Notice: installing into a sandbox located at /home/bburdette/blah4/.cabal-sandbox Configuring blah4-0.0.0... Building blah4-0.0.0... Installed blah4-0.0.0 [nix-shell:~/blah4]$

So that’s that. The project can be run. But, now the “yesod” command is missing, and we’d like that in order to run the server in development mode, where it automatically recompiles the project whenever source code files change.

To make that available, we’ll add it in to the ‘default.nix’ file, at the top and in a new section, buildTools.

{ cabal, aeson, conduit, dataDefault, fastLogger, hjsmin, hspec , httpConduit, monadControl, monadLogger, persistent , persistentSqlite, persistentTemplate, resourcet, shakespeare , text, transformers, waiExtra, waiLogger, warp, yaml, yesod , yesodAuth, yesodCore, yesodForm, yesodStatic, yesodTest, yesodBin }: cabal.mkDerivation (self: { pname = "blah4"; version = "0.0.0"; src=./.; isLibrary = true; isExecutable = true; buildDepends = [ aeson conduit dataDefault fastLogger hjsmin httpConduit monadControl monadLogger persistent persistentSqlite persistentTemplate shakespeare text waiExtra waiLogger warp yaml yesod yesodAuth yesodCore yesodForm yesodStatic ]; buildTools = [ yesodBin ]; testDepends = [ hspec monadLogger persistent persistentSqlite resourcet transformers yesod yesodCore yesodTest ]; meta = { license = self.stdenv.lib.licenses.unfree; platforms = self.ghc.meta.platforms; }; })

After editing the file, exit from nix-shell and reenter it again to pull in the yesod tool.

[nix-shell:~/blah4]$ exit exit [bburdette@nixosthe1 blah4]$ ./ns [nix-shell:~/blah4]$ yesod devel Yesod devel server. Press ENTER to quit