This flake provides an unopinionated approach to packaging [[https://github.com/purescript/purescript][PureScript]] projects with the [[https://github.com/NixOS/nixpkgs][Nix]] package manager. Leveraging [[https://github.com/purescript/registry][PureScript's registry]] and the new [[https://github.com/purescript/spago][spago@next]], this repository facilitates the creation of reproducible builds for PureScript projects with minimal complexity. This works by treating a PureScript project's =spago.lock= as a single source of truth for dependencies.
Table of contents :toc:
[[#examples][Examples]]
[[#out-of-date-registry][Out of date registry]]
[[#limitations][Limitations]]
[[#notes][Notes]]
[[#related][Related]]
[[#license][License]]
Examples The most important function that this flake provides is the ~mkSpagoDerivation~ function, exposed as both an output and via an overlay. This provides a wrapper around ~stdenv.mkDerivation~ which puts all of your project's dependencies in the right place, making it easy for you to build your projects in a reproducible way.
Importantly, the =spago.lock= file is required for ~mkSpagoDerivation~ to determine your project's dependencies. Optionally, if you provide your project's =spago.yaml= file, then your project's name will be extracted and used. You can provide a =name= or =pname= argument instead.
Here is a simple =flake.nix= that builds a PureScript project.
{ inputs = { nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; flake-utils.url = "github:numtide/flake-utils"; mkSpagoDerivation.url = "github:jeslie0/mkSpagoDerivation"; ps-overlay.url = "github:thomashoneyman/purescript-overlay"; };
outputs = { self, nixpkgs, flake-utils, mkSpagoDerivation }: flake-utils.lib.eachDefaultSystem ( system: let pkgs = import nixpkgs { inherit system; overlays = [ mkSpagoDerivation.overlays.default ps-overlay.overlays.default ]; }; in { packages.default = pkgs.mkSpagoDerivation { spagoYaml = ./spago.yaml; spagoLock = ./spago.lock; src = ./.; nativeBuildInputs = [ pkgs.purs-unstable pkgs.spago-unstable pkgs.esbuild ]; version = "0.1.0"; buildPhase = "spago bundle"; installPhase = "mkdir $out; cp index.js $out"; }; } ); }
The only attribute ~mkSpagoDerivation~ requires is ~src~. The ~spagoYaml~ attribute will default to =${src}/spago.yaml= and likewise, ~spagoLock~ defaults to =${src}/spago.lock=. Everything else is passed into ~mkDerivation~. There are no assumptions about the which version of the compiler is used - you must specify which copy of Spago and PureScript you want to use. Dependencies can be added through ~buildInputs~ or ~nativeBuildInputs~. The following example demonstrates this, by using [[https://github.com/aristanetworks/purescript-backend-optimizer][purescript-backend-optimizer]] and using the unstable PureScript compiler from the PureScript Overlay.
{ inputs = { nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; flake-utils.url = "github:numtide/flake-utils"; ps-overlay.url = "github:thomashoneyman/purescript-overlay"; mkSpagoDerivation.url = "github:jeslie0/mkSpagoDerivation"; };
outputs = { self, nixpkgs, flake-utils, ps-overlay, mkSpagoDerivation }: flake-utils.lib.eachDefaultSystem ( system: let pkgs = import nixpkgs { inherit system; overlays = [ mkSpagoDerivation.overlays.default ps-overlay.overlays.default ]; }; in { packages.default = pkgs.mkSpagoDerivation { spagoYaml = ./spago.yaml; spagoLock = ./spago.lock; src = ./.; version = "0.1.0"; nativeBuildInputs = [ pkgs.esbuild pkgs.purs-backend-es pkgs.purs-unstable pkgs.spago-unstable ]; buildPhase = "spago build && purs-backend-es bundle-app --no-build --minify --to=main.min.js"; installPhase = "mkdir $out; cp -r main.min.js $out"; }; } ); }
Some other useful functions are exposed. One is ~buildDotSpago~, which builds a project's =.spago= directory. It takes an attribute set ~{ spagoLock, src }~, which respectively are the paths to the project's ~spago.lock~ and the root of the project. Another useful function is ~buildSpagoNodeJs~, which builds the =spago-nodejs= directory, typically located in the user's =.cache= directory.
Out of date registry It is possible for this repository to not have the most up-to-date registry set. If you cant wait for the GitHub action to update this repository, you can override the =registry= and =registry-index= inputs to this flake.
{ inputs = { nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; flake-utils.url = "github:numtide/flake-utils"; ps-overlay.url = "github:thomashoneyman/purescript-overlay"; mkSpagoDerivation = { url = "github:jeslie0/mkSpagoDerivation"; inputs = { registry.url = "github:purescript/registry/066f77d3b668fd7916e0af493d8d8ec7a850d774"; registry-index.url = "github:purescript/registry-index/53cfacb3b1677120eb5e6c11a1f2449d1049c2ce"; }; }; };
outputs = { self, nixpkgs, flake-utils, ps-overlay, mkSpagoDerivation }: ...
Limitations At the time of writing, this project only supports PureScript projects that make use of the newer spago@next releases. In particular, the project needs a ~spago.yaml~ file and a ~spago.lock~ file is required too.
Notes ** Hooks The ~buildPhase~ and ~installPhase~ always run =pre= and =post= hooks, even if the commands provided by the user don't specify them.
Related
[[https://github.com/purifix/purifix/][purifix]] A different tool to package PureScript programs with Nix.
[[https://github.com/justinwoo/spago2nix][spago2nix]] Another tool for packaging PureScript programs with Nix.
[[https://github.com/justinwoo/easy-purescript-nix][easy-purescript-nix]] A repository and Nix flake that provides lots of PureScript tools.
[[https://github.com/purs-nix/purs-nix][purs-nix]] A tool for Nix based PureScript development.
[[https://github.com/jeslie0/mkElmDerivation][mkElmDerivation]] A similar tool (that I created) to package [[https://elm-lang.org/][Elm]] applications with Nix.
License All of this repository is under the MIT license.