This flake provides an unopinionated approach to packaging PureScript projects with the Nix package manager. Leveraging PureScript’s registry and the new 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.
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, a spago.yaml
and a spago.lock
file are required for mkSpagoDerivation
to determine your project’s name and dependencies.
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 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.
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 }:
...
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.
The buildPhase
and installPhase
always run pre
and post
hooks, even if the commands provided by the user don’t specify them.
- purifix A different tool to package PureScript programs with Nix.
- spago2nix Another tool for packaging PureScript programs with Nix.
- easy-purescript-nix A repository and Nix flake that provides lots of PureScript tools.
- purs-nix A tool for Nix based PureScript development.
- mkElmDerivation A similar tool (that I created) to package Elm applications with Nix.
All of this repository is under the MIT license.