- Nix 98.5%
- Shell 1.5%
| .github/workflows | ||
| examples | ||
| nix | ||
| .gitignore | ||
| build.sh | ||
| default.nix | ||
| flake.lock | ||
| flake.nix | ||
| LICENSE | ||
| README.md | ||
purifix
Build PureScript projects from a spago.yaml file with a Nix
function instead of spago.
Like with spago, with purifix your spago.yaml file acts as a
single source of truth. When you change spago.yaml you don’t
need to change the Nix expression, purifix automatically picks up
the changes.
For example, this is how you would build the PureScript package
./examples/purescript-package/
with purifix:
purifix {
src = ./examples/purescript-package;
}
Features
-
spago.yamlas single source of truth. -
Compiles all package sets on the PureScript registry.
-
Support for multiple PureScript backends.
-
Support for bundling with
esbuild. -
Incremental compilation (that is, you only compile
preludeonce)This is done by manually merging the
cache-db.jsonfile generated bypurs. -
Support for running tests with Node.js.
-
Support for running the main module.
-
Support for generating documentation and outputting markdown or html for your package and all of its dependencies.
-
Support for monorepos and local packages installed from the file system.
-
Support for entering a development shell where you can quickly compile your package sources.
Installing / Getting purifix
The purifix function lives in this repo, and the recommended installation procedure is to include this flake and add the exported overlay to overlays when importing nixpkgs.
A simple package could be installed in a flake.nix file like below:
{
inputs = {
nixpkgs = {
url = "github:NixOS/nixpkgs";
};
purifix = {
url = "github:purifix/purifix";
};
flake-utils = {
url = "github:numtide/flake-utils";
};
};
outputs = inputs:
inputs.flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import inputs.nixpkgs {
inherit system;
overlays = [ inputs.purifix.overlay ];
};
my-package = pkgs.purifix {
src = ./.;
};
in
{
packages = {
default = my-package;
};
defaultPackage = my-package;
});
}
You can also use purifix without flakes by importing the purifix function like so:
let
purifix = import (builtins.fetchGit "https://github.com/purifix/purifix.git") {};
in purifix {
src = ./.;
}
It's recommended to pin the fetched purifix commit using the rev attribute so
that your builds remain reproducible.
Building the derivation produced by purifix
Building the derivation produced by purifix is as simple as calling
nix-build on it. Here is how you would build the example PureScript package
in this repo:
$ nix-build ./nix/examples.nix -A purifix-example
...
/nix/store/iyk9zzl7bwyvij4s67529xcmqlr3nqil-example-purescript-package-0.0.1
This produces an output with a single directory output/. output/ contains
all the transpiled PureScript code:
$ tree /nix/store/hjcxs72xkjm4qad78railg6kflbljpcz-example-purescript-package-0.0.1
/nix/store/hjcxs72xkjm4qad78railg6kflbljpcz-example-purescript-package-0.0.1
└── output
├── cache-db.json
├── Control.Alt
│ ├── docs.json
│ ├── externs.cbor
│ └── index.js
├── Control.Alternative
│ ├── docs.json
│ ├── externs.cbor
...
Creating a package
This repository contain some example packages to show how to get
started using purifix to build your PureScript sources. Below is a minimal
spago.yaml defining how to build all the PureScript in the src directory.
Required fields are name, version, dependencies and package_set.
package:
name: example-purescript-package
version: 0.0.1
dependencies: [ "console", "effect", "foldable-traversable", "prelude"]
workspace:
package_set:
registry: 11.3.0
Developing using purifix
To create a development shell where you can easily compile your package sources
without having to wait for a full nix build you can run nix develop or
nix-shell on the develop attribute of your purifix package.
(purifix {
src = ./examples/purescript-package;
}).develop
This will place you in a shell where you have the purifix executable. This executable
will copy the precompiled dependencies to the output directory and then only compile your
package-specific files.
$ purifix src/Main.purs
will compile the Main.purs file and place the result in the output directory together with
the precompiled dependencies.
Using purescript-language-server
You can use purescript-language-server with purifix. Make sure that you
include spago.yaml when finding the root of your PureScript package.
Below is an example of configuring coc.nvim to use the purescript-language-server.
"purescript": {
"command": "purescript-language-server",
"args": ["--stdio"],
"filetypes": ["purescript"],
"trace.server": "off",
"rootPatterns": ["spago.yaml", "psc-package.json", "spago.dhall"],
"settings": {
"purescript": {
"addSpagoSources": true,
"addNpmPath": true
}
}
}
Before you load your project with the purescript-language-server it can be
useful to run purifix in the development shell so that you don't have to
compile all your dependencies again.
Creating an application bundle
(purifix {
src = ./examples/purescript-package;
}).bundle {
format = "iife";
minify = true;
app = true;
}
Monorepos
You can use purifix with monorepos containing multiple PureScript packages.
If your src directory contains more than one package purifix will return an
attribute set from package name to package. Set the src attribute of the call
purifix to the root of your repository and let purifix search for your nested packages.
If your individual packages do not contain a workspace field to specify which package
set to use purifix will try to parse workspace from a spago.yaml file in the root
of your src folder.
(purifix {
src = ./examples/local-monorepo;
}).example-purescript-package
Running tests
(purifix {
src = ./examples/local-monorepo;
}).example-purescript-package.test
Running the main module with node
(purifix {
src = ./examples/local-monorepo;
}).example-purescript-package.run
$ nix build .#example-registry-package-run --out-link result
$ ./result/bin/example-purescript-package
🍝
1337
This can also be packaged as an app in a flake. The executable is given the same name as the package.
Generating documentation
You can generate documentation for your package with
(purifix {
src = ./examples/purescript-package;
}).docs {
format = "html";
}