-
Notifications
You must be signed in to change notification settings - Fork 1
/
test.nix
153 lines (140 loc) · 6.26 KB
/
test.nix
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# This file is used for testing the transpiled PureScript code.
# Check the documentation below on each overlay to see exactly what attributes
# each overlay defines, and how to build them.
#
# Before using this file, you must build the PureScript library
# `./purescript-cabal-parser`. See the README.md for instructions on how to do
# this.
let
flake-lock = builtins.fromJSON (builtins.readFile ./flake.lock);
nixpkgs-src = builtins.fetchTarball {
url = "https://github.com/NixOS/nixpkgs/archive/${flake-lock.nodes.nixpkgs.locked.rev}.tar.gz";
sha256 = flake-lock.nodes.nixpkgs.locked.narHash;
};
# This is the compiled output of the
# `./purescript-cabal-parser/src/Main.purs` file. Note that PureNix takes
# PureScript files and transpiles them to Nix files as a record set, with
# each attribute name being a PureScript function name. See the call to
# `rawCabalFileToPkgDef` in `haskellPkgDrv` below for an example of using
# a function from `purenixMain`.
#
# Try importing this `./purescript-cabal-parser/output/Main/default.nix` file
# in the Nix repl and playing around with it.
#
# It feels pretty neat being able to call functions written in PureScript
# from Nix.
purenix-Main = import ./purescript-cabal-parser/output/Main;
overlays = [
# This overlay adds a top-level package called `exampleHaskellPackageFromNix`.
#
# This top-level Haskell package is built by parsing the
# `example-haskell-package.cabal` file using the PureScript function
# `rawCabalFileToPkgDef`.
#
# This overlay is similar to the `exampleNixpkgsOverlay`, except it is
# defined in Nix instead of PureScript. Check the
# `./purescript-cabal-parser/src/Main.purs` file to compare how the
# `exampleNixpkgsOverlay` function is written in PureScript.
#
# You can build `exampleHakellPackageFromNix` like the following:
#
# ```
# $ nix-build ./test.nix -A exampleHaskellPackageFromNix
# /nix/store/xb0yxkpzdz3zjqmcxwa9z6r6r98yfizz-example-cabal-library-0.1.0.0
# ```
(final: prev: {
exampleHaskellPackageFromNix =
let
# `rawCabalFile` is just a string that contains the raw contents of the
# cabal file for our example-cabal-library Haskell package.
rawCabalFile =
builtins.readFile ./example-cabal-library/example-cabal-library.cabal;
# This uses the PureScript function `rawCabalFileToPkgDef` here from Nix.
# This function parses a raw Cabal file, and turns it into something
# that you can pass to `haskellPackages.callPackage`.
#
# `haskellPkgDrv` will become a function similar to this:
#
# ```
# { mkDerivation, aeson, base, lib }:
# mkDerivation {
# pname = "example-cabal-library";
# version = "0.1.0.0";
# src = ./example-cabal-library;
# isLibrary = false;
# isExecutable = true;
# executableHaskellDepends = [ aeson base ];
# license = lib.licenses.bsd3;
# }
# ```
haskellPkgDrv =
purenix-Main.rawCabalFileToPkgDef rawCabalFile ./example-cabal-library;
in
final.haskellPackages.callPackage haskellPkgDrv {};
})
# This overlay adds a top-level package called `exampleHaskellPackage`.
#
# This is exactly the same as the previous overlay, except it is defined in
# PureScript. Check `./purescript-cabal-parser/src/Main.purs` to see how
# this overlay is defined.
#
# You can build `exampleHakellPackage` like the following:
#
# ```
# $ nix-build ./test.nix -A exampleHaskellPackage
# /nix/store/xb0yxkpzdz3zjqmcxwa9z6r6r98yfizz-example-cabal-library-0.1.0.0
# ```
purenix-Main.exampleNixpkgsOverlay
# This overlay is similar to `exampleNixpkgsOverlay`, but instead of
# adding a top-level package, it adds a Haskell package to `haskellPackages`.
# Adding a Haskell package is significantly more involved than adding a
# top-level package. Check out the source in
# `./purescript-cabal-parser/src/Main.purs` to see how this is defined.
#
# You can build this Haskell package like the following:
#
# ```
# $ nix-build ./test.nix -A haskellPackages.exampleHaskellPackage
# /nix/store/xb0yxkpzdz3zjqmcxwa9z6r6r98yfizz-example-cabal-library-0.1.0.0
# ```
purenix-Main.exampleNixpkgsHaskellOverlay
# This overlay is almost the exact same as `exampleNixpkgsHaskellOverlay`,
# but the PureScript code defining it is strongly typed.
# `exampleNixpkgsHaskellOverlay` uses mostly dynamically-typed Nix values
# like `AttrSet` and unsafe getters. But `exampleNixpkgsHaskellOverlayTyped`
# uses realistic types for each attribute set. This is possible because of
# PureScripts row types.
#
# See `./purescript-cabal-parser/src/Main.purs` for all the gory details.
#
# You can build the Haskell package added in this overlay like the following:
#
# ```
# $ nix-build ./test.nix -A haskellPackages.exampleHaskellPackageTyped
# /nix/store/xb0yxkpzdz3zjqmcxwa9z6r6r98yfizz-example-cabal-library-0.1.0.0
# ```
purenix-Main.exampleNixpkgsHaskellOverlayTyped
# This is an example overlay that shows how the normal `callCabal2nix`
# function is used to build a Haskell package.
#
# This is useful because you can tell Nix to disallow IFD and confirm
# this call fails:
#
# ```
# $ nix-build --option allow-import-from-derivation false ./test.nix -A exampleHaskellPackageWithIFD
# error: cannot build '/nix/store/q5hq65ynrqnnnjs3kl1ggsx2pkwlw702-cabal2nix-example-cabal-library.drv'
# during evaluation because the option 'allow-import-from-derivation' is disabled
# ```
#
# Now, you can go back and try building all the above packages with
# `allow-import-from-derivation` disabled. You'll see that they all
# still successfully build, because they are not using IFD. Instead,
# the `.cabal` file is parsed using the Nix code produced from PureNix.
(final: prev: {
exampleHaskellPackageWithIFD =
final.haskellPackages.callCabal2nix "example-cabal-library" ./example-cabal-library { };
})
];
pkgs = import nixpkgs-src { inherit overlays; };
in
pkgs