2021-12-10
This post is part of a series called The Road to purescript2nix
.
Update 2023-02-15: Viktor Kronvall (@considerate) took purescript2nix
and fixed it up to be able to use the new PureScript Registry. During this process, purescript2nix
has been renamed to purifix
, and moved to its own GitHub Organization. Links to the purescript2nix
repo in this blog post should all still work, but they will be redirected to the purifix
repo. If you're looking for the exact code this blog post describes, you should find it at commit 1e5e98dcd851e31
.
purescript2nix
is a Nix function that allows you to easily build a PureScript project with Nix. It uses the info in your spago.dhall
and packages.dhall
files as a single source of truth in order to construct a Nix build plan.
This post explains how to use purescript2nix
, shows some of the implementation, and explains why I started working on this project.
Using purescript2nix
Given a PureScript project in the directory ./example-purescript-package
, you can build it with purescript2nix
with a call like the following1:
This produces a derivation that will build your source code.
The purescript2nix
repository contains an example package that you may want to play around with.
Implementation
Under the covers, purescript2nix
will roughly do the following things:
Read the
spago.dhall
andpackages.dhall
files into Nix.This is done with the Nix function
dhallDirectoryToNix
.Compute all transitive dependencies for the package you are trying to build, given an input package set.
This is mainly done with the Nix function
builtins.genericClosure
2.Download the PureScript source code for all dependencies.
This is relatively straight-forward with Nix.
Actually compile the PureScript code.
This is done by directly calling
purs
.
The output of purescript2nix
is a derivation that contains all the compiled PureScript code.
Why write purescript2nix
?
I was a mentor for Summer of Nix 2021. One of the members on my team, David Hauer (@DavHau), started the project dream2nix. dream2nix is meant to be a generic framework to wrap up all the lang2nix tools (like cabal2nix
, crate2nix
, yarn2nix
, poetry2nix
, etc) and provide a unified interface.
I wanted to contribute a backend to dream2nix for PureScript, but it seemed like there weren't any easy approaches to building a PureScript project with Nix. Most current approaches require a manual steps for dumping the contents of the spago.dhall
and packages.dhall
files, as well getting Nix-compatible hashes for all PureScript dependencies.
I wanted to eliminate these manual steps, so I started thinking about what would be required for an easy-to-use purescript2nix
function. The two big things necessary for this are:
- the ability to read Dhall files in as Nix (even when the Dhall files have remote imports)
- Nix-compatible hashes in the PureScript package sets
Implementing these two things took a surprising amount of time. But with these in place, putting together purescript2nix
was relatively easy.
Although, after this work, I ran out of steam and didn't end up creating a PureScript backend for dream2nix
. I have opened an issue about it in case anyone wants to work on this.
Caveats
Currently, the big caveat with purescript2nix
is that it requires using a PureScript package set with Nix-compatible hashes. See this issue for more information.
There is also an issue with using purescript2nix
when building from a Nix Flake.
I would welcome help on either of these issues (or anything else on the purescript2nix
issue tracker).
Conclusion
If you're looking for an easy way to build a PureScript package with Nix, purescript2nix
might be a good choice.
If you're looking to adopt purescript2nix
into your build system professionally, I am open to freelancing or consulting arrangements. I am of course open to any other freelance or consulting projects involving Nix. Feel free to get in touch for more info.
Footnotes
This requires access to the
purescript2nix
function. You can get access to this function by adding thepurescript2nix
repo as a Flake input, or just directly importing the repo. See the README.md for more info. Open an issue if you need more help.↩︎I learned about this from Justin Woo. He has a post about this called Working with PureScript package sets with just Nix. I put together my own example of
builtins.genericClosure
in this issue.↩︎
tags: purescript, nixos