@@ -1,10 +1,12 @@
11# User Guide
22
3−So you want to use `haskell.nix` with your stack or cabal project. The
4−general approach will be to pick the right tool from `nix-tools` and
5−produce a `pkgs.nix` expressions. Getting a copy of the haskell.nix,
6−hackage.nix (and potentially stackage.nix) source will then equip us
7−to produce derivations that we can `nix build`.
3+So you want to use [Haskell.nix][] with your stack or cabal project. The
4+general approach will be to pick the right tool from `nix-tools` and
5+produce a `pkgs.nix` expression. Getting a copy of the `nix-tools`
6+(and potentially the [Haskell.nix][] source), will then equip us to
7+produce derivations that we can `nix build`.
8+
9+[haskell.nix]: https://github.com/input-output-hk/haskell.nix
810
911## Installing `nix-tools`
1012
@@ -20,101 +22,141 @@ If you would like to then install `nix-tools` into your profile, run:
2022nix-env -i ./nt
2123```
2224
23−## Setup
25+## Getting the [Haskell.nix][] source (optional)
2426
25−The general structure will be the same for haskell.nix, independent of
26−the use of stack or cabal. Let us assume for now that we have
27−generated a `pkgs.nix` expression in `nix`.
27+The [Haskell.nix][] and `nix-tools` source will be useful if you would
28+like to contribute improvements, or read the source code to fully
29+understand something that the documentation doesn't cover.
2830
29−- [Generating a `pkgs.nix` for a stack project](/user-guide-stack)
30−- [Generating a `pkgs.nix` for a cabal project](/user-guide-cabal)
31+```bash
32+git clone https://github.com/input-output-hk/nix-tools
33+git clone https://github.com/input-output-hk/haskell.nix
34+cd haskell.nix
35+nix build -f . nix-tools --out-link nt
36+```
3137
32−## default.nix
38+## Importing [Haskell.nix][] into your project
3339
34−We will start with defining a helper function in our `default.nix`
35−that will allow us to override the source imports with `-I
36−haskell=/path/to/haskell.nix` in case we need it.
40+The easiest way to get a hold of [Haskell.nix][] is with
41+[`fetchTarball`](https://nixos.org/nix/manual/#ssec-builtins).
3742
3843```nix
39−{ pkgs ? import <nixpkgs> {}
40−}:
41−let
42− overrideWith = override: default:
43− let
44− try = builtins.tryEval (builtins.findFile builtins.nixPath override);
45− in if try.success then
46− builtins.trace "using search host <${override}>" try.value
47− else
48− default;
49−in
44+import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz) {}
45+```
46+
47+If you have your own `pkgs` variable, pass it to [Haskell.nix][] to
48+prevent double-evaluation of the Nixpkgs collection.
49+
50+```nix
51+{ pkgs ? import <nixpkgs> {} }:
52+
53+import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz) { inherit pkgs; }
5054```
5155
52−Next we will use this to import `haskell.nix`.
56+### Pinning the [Haskell.nix][] version
57+
58+For simplicity's sake we will use `fetchTarball` for the examples in
59+this documentation. This will always get the latest version, and is
60+similar to an auto-updating Nix channel.
61+
62+However, in your own project, you may wish to pin [Haskell.nix][] (as
63+you would pin Nixpkgs). This will make your builds reproducable, more
64+predictable, and faster (because the fixed version is cached).
5365
54−**NOTE**: update the `rev` and `sha256` values to the recent ones as
55− found on GitHub. Especially `haskell.hackage` and `haskell.stackage`
56− will evolve with package release on hackage and stackage releases
57− respectively.
66+One way of doing this is to use `nix-prefetch-git` to get a JSON file
67+with a revision and SHA-256 hash of [Haskell.nix][].
68+
69+```
70+$ nix-prefetch-git --quiet https://github.com/input-output-hk/haskell.nix | tee haskell-nix-src.json
71+{
72+ "url": "https://github.com/input-output-hk/haskell.nix",
73+ "rev": "f1a94a4c82a2ab999a67c3b84269da78d89f0075",
74+ "date": "2019-06-05T01:06:12+00:00",
75+ "sha256": "0ggxsppjlb6q6a83y12cwgrdnqnw1s128rpibgzs5p1966bdfqla",
76+ "fetchSubmodules": false
77+}
78+```
79+
80+(The `tee` command is just to show you the result.)
81+Use the following expression to import that version:
5882
5983```nix
84+{ pkgs ? import <nixpkgs> {} }:
85+
6086let
61− haskellLib = pkgs.fetchFromGitHub {
62− owner = "input-output-hk";
63− repo = "haskell.nix";
64− rev = "5180ae9d78756509c81b98b8e6d974e350b15752";
65− sha256 = "0fbnnvymdp2qb09wlqy6ga8wsyhglx607cjdfg510s1gs756v9yx";
66− name = "haskell-lib-source";
87+ spec = builtins.fromJSON (builtins.readFile ./haskell-nix-src.json);
88+ haskell-nix-src = pkgs.fetchgit {
89+ name = "haskell-lib";
90+ inherit (spec) url rev sha256 fetchSubmodules;
6791 };
68− haskell = import (overrideWith "haskell" haskellLib) { inherit pkgs; };
6992in
93+ import haskell-nix-src { inherit pkgs; }
7094```
7195
72−Finally we string this together and produce a package set:
96+There are other possible schemes for pinning. See
97+[`haskell.nix/lib/fetch-external.nix`](https://github.com/input-output-hk/haskell.nix/blob/master/lib/fetch-external.nix),
98+the [niv](https://github.com/nmattia/niv) tool, or the Nix Flakes
99+proposal.
100+
101+### Overriding the Hackage version
102+
103+Sometimes you might want to use a chosen version of Haskell.nix with a
104+recent update of Hackage or Stackage. This can be done with JSON pins:
105+
106+```bash
107+nix-prefetch-git https://github.com/input-output-hk/hackage.nix | tee hackage-src.json
108+nix-prefetch-git https://github.com/input-output-hk/stackage.nix | tee stackage-src.json
109+```
110+
111+The resulting JSON files will correspond to the latest revision of
112+[hackage.nix][] and [stackage.nix][]. See
113+[Architecture](architecture.md) for more information about how
114+these Git repositories correspond to the actual Hackage and Stackage.
115+
116+[hackage.nix]: https://github.com/input-output-hk/hackage.nix
117+[stackage.nix]: https://github.com/input-output-hk/stackage.nix
73118
74119```nix
75−let
76− # Import the file you will create in the stack-to-nix or cabal-to-nix step.
77− my-pkgs = import ./nix/pkgs.nix;
78−
79− # Stack projects use the mkStackPkgSet helper function
80− pkgSet = haskell.mkStackPkgSet {
81− stack-pkgs = my-pkgs;
82− pkg-def-overlays = [];
83− modules = [];
84− };
120+{ pkgs ? import <nixpkgs> {} }:
85121
86− # Cabal projects use mkPkgSet
87− pkgSet = haskell.mkPkgSet {
88− pkg-def = my-pkgs.pkg-def;
89− pkg-def-extras = [
90− # these extras will provide additional packages
91− # ontop of the package set. E.g. extra-deps
92− # for stack packages. or local packages for
93− # cabal.projects
94− my-pkgs.extras
95− ];
96− modules = [
97− # specific package overrides would go here
98− # example:
99− # packages.cbors.patches = [ ./one.patch ];
100− # packages.cbors.flags.optimize-gmp = false;
101− ];
102− };
122+import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz) {
123+ inherit pkgs;
124+ hackageSourceJSON = ./hackage-src.json;
125+ stackageSourceJSON = ./stackage-src.json;
126+}
127+```
128+
129+## Using `nix repl`
103130
104−in pkgSet.config.hsPkgs // { _config = pkgSet.config; }
131+It's sometimes useful to load [Haskell.nix][] in the REPL to explore
132+attrsets and try examples.
133+
134+```
135+# example.nix
136+{ pkgs ? import <nixpkgs> {} }:
137+rec {
138+ haskell = import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz) { inherit pkgs; };
139+ pkgNames = pkgs.lib.attrNames haskell.snapshots."lts-13.18";
140+}
105141```
106142
107−With this setup you can then start building the components of
108−interest:
143+Load the example file:
109144
110−```bash
111−nix build -f default.nix $pkg.components.library
112145```
146+$ nix repl '<nixpkgs>' example.nix
147+Welcome to Nix version 2.3pre6631_e58a7144. Type :? for help.
113148
114−to build the library for `$pkg` or
149+Loading '<nixpkgs>'...
150+Added 10403 variables.
115151
116−```bash
117−nix build -f default.nix $pkg.components.exes.$exe
152+Loading 'example2.nix'...
153+Added 2 variables.
154+
155+nix-repl> lib.take 5 pkgNames
156+[ "ALUT" "ANum" "Allure" "Boolean" "BoundedChan" ]
157+
158+nix-repl>
118159```
119160
120−to build a specific executable. The same holds for test suites and benchmarks.
161+Now that you have `nix-tools` and are able to import [Haskell.nix][],
162+you can continue to the next chapter.