Skip to content

Commit ed4ae5d

Browse files
committed
Updated to callPackage pattern
1 parent 8e46825 commit ed4ae5d

File tree

7 files changed

+99
-92
lines changed

7 files changed

+99
-92
lines changed

.gitignore

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
/.env
2-
/result
3-
/result-*
2+
/result*
43
/*.cabal
54

65
dist
@@ -24,4 +23,4 @@ cabal.sandbox.config
2423
cabal.project.local
2524
cabal.project.local~
2625
.HTF/
27-
.ghc.environment.*
26+
.ghc.environment.*

README.md

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,37 +4,45 @@ This is an example Haskell project using Nix to setup a development environment.
44

55
This uses Nix and Cabal without Stack. This is because when using Nix, you don't need Stack, as Nix provides harmonious snapshots of Haskell packages. However Stack users can still develop on this project, they just have to generate an appropriate `stack.yaml` from the Cabal file.
66

7-
The first step is that we have to acquire `cabal2nix`, which we use to generate a `cabal.nix` file from the `package.yaml`. Note that the usage of `package.yaml` means we are using the [hpack format](https://github.com/sol/hpack). This format is transformed to a cabal file via the `hpack` command.
7+
The first step is that we have to acquire `cabal2nix`, which we use to generate a `default.nix` file from the `package.yaml`. Note that the usage of `package.yaml` means we are using the [hpack format](https://github.com/sol/hpack). This format is transformed to a cabal file via the `hpack` command.
88

99
```sh
1010
nix-shell -p cabal2nix
1111
# using --hpack ensures that we always use package.yaml
12-
cabal2nix --hpack . >./cabal.nix
12+
cabal2nix --hpack . >./default.nix
1313
```
1414

1515
The above command is also executed at the beginning of the `shellHook`.
1616

17-
This `cabal.nix` will be imported by the `default.nix` to be used as the core derivation. Unlike other `*2nix` tools, this still retains package sharing, because the generated `cabal.nix` expects the current package's dependencies to be passed down from a higher level package set.
18-
1917
If this is the first time you've ran `cabal`, then run `cabal update` to get the latest package list in `~/.cabal`.
2018

2119
## Installation
2220

23-
If on Nix, you can install just by using:
21+
Building the package:
2422

25-
```sh
26-
nix-env -f ./default.nix -i
23+
```
24+
nix-build -E '(import ./pkgs.nix).haskellPackages.callPackage ./default.nix {}'
2725
```
2826

29-
If you are not, then use `cabal`:
27+
Building the releases:
3028

31-
```sh
32-
# you need to first generate the cabal file
33-
hpack
34-
cabal install
29+
```
30+
nix-build --attr application
31+
nix-build --attr applicationStrict
32+
nix-build --attr docker
33+
```
34+
35+
Install into Nix user profile:
36+
37+
```
38+
nix-env -f ./release.nix --install --attr application
3539
```
3640

37-
It installs the executable into `~/.cabal/bin`.
41+
Install into Docker:
42+
43+
```
44+
docker load --input "$(nix-build ./release.nix --attr docker)"
45+
```
3846

3947
## Developing
4048

@@ -53,25 +61,25 @@ The `cabal-install` package installs the `cabal` command. This command and assoc
5361

5462
To use `cabal`, you need to generate the cabal file from the `package.yaml`. You can do this by running `hpack`. However this is also executed as part of the `shellHook`.
5563

56-
At this point, you need to run `cabal configure`. This will create a `dist` directory that will contain any build artifacts. This is also executed as part of the `shellHook`.
64+
At this point, you need to run `cabal v2-configure`. This will create a `dist` directory that will contain any build artifacts. This is also executed as part of the `shellHook`.
5765

5866
It's important to read the guide for Cabal as this is information relevant to the Haskell ecosystem: https://www.haskell.org/cabal/users-guide/developing-packages.html
5967

6068
The most important commands are:
6169

6270
```sh
6371
# this will launch GHCI for a given target
64-
cabal repl
72+
cabal v2-repl
6573
# this will build the executable and library and put them into ./dist
66-
cabal build
74+
cabal v2-build
6775
# this will run the executable (you can pass the name of the executable)
68-
cabal run
76+
cabal v2-run
6977
# this will run the tests
70-
cabal test
78+
cabal v2-test
7179
# deletes ./dist
72-
cabal clean
80+
cabal v2-clean
7381
# this will install the executable into the ~/.cabal/bin
74-
cabal install
82+
cabal v2-install
7583
```
7684

7785
Once you have finished developing, you can build the package using:
@@ -100,15 +108,15 @@ Remember that Haskell package versions conventionally use `Major.Major.Minor.Pat
100108

101109
## Using GHCi (or `cabal repl` or `stack ghci`)
102110

103-
The `cabal repl` only works against the build targets specified in the `package.yaml`. You have to specify the target name:
111+
The `cabal v2-repl` only works against the build targets specified in the `package.yaml`. You have to specify the target name:
104112

105113
```sh
106114
# targets the library
107-
cabal repl haskell-demo
115+
cabal v2-repl haskell-demo
108116
# targets the executable (which depends on the library)
109-
cabal repl haskell-demo-exe
117+
cabal v2-repl haskell-demo-exe
110118
# targets the tests (which depends on the library)
111-
cabal repl haskell-demo-test
119+
cabal v2-repl haskell-demo-test
112120
```
113121

114122
However you need to understand how modules work in GHCi to use the REPL well. The documentation here explains the necessary commands: https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/ghci.html#what-s-really-in-scope-at-the-prompt

cabal.nix

Lines changed: 0 additions & 15 deletions
This file was deleted.

default.nix

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,15 @@
1-
{
2-
pkgs ? import ./pkgs.nix,
3-
haskellPath ? "ghc843"
4-
}:
5-
with pkgs;
6-
let
7-
haskellPackages = lib.getAttrFromPath (lib.splitString "." haskellPath) haskell.packages;
8-
drv = haskellPackages.callPackage (import ./cabal.nix) {};
9-
in
10-
haskell.lib.buildStrictly (
11-
drv.overrideAttrs (attrs: {
12-
src = lib.cleanSourceWith {
13-
filter = (path: type:
14-
! (builtins.any
15-
(r: (builtins.match r (builtins.baseNameOf path)) != null)
16-
[
17-
"dist"
18-
"\.env"
19-
])
20-
);
21-
src = lib.cleanSource attrs.src;
22-
};
23-
})
24-
)
1+
{ mkDerivation, base, hpack, stdenv }:
2+
mkDerivation {
3+
pname = "haskell-demo";
4+
version = "0.1.0.0";
5+
src = ./.;
6+
isLibrary = true;
7+
isExecutable = true;
8+
libraryHaskellDepends = [ base ];
9+
libraryToolDepends = [ hpack ];
10+
executableHaskellDepends = [ base ];
11+
testHaskellDepends = [ base ];
12+
preConfigure = "hpack";
13+
homepage = "https://github.com/MatrixAI/Haskell-Demo#readme";
14+
license = stdenv.lib.licenses.asl20;
15+
}

pkgs.nix

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1-
import (fetchTarball https://github.com/NixOS/nixpkgs-channels/archive/4dd9cd3f69e51dcb69d29a88335f06a544b0e508.tar.gz) {}
1+
import (
2+
let rev = "d85e435b7bded2596d7b201bcd938c94d8a921c1"; in
3+
fetchTarball "https://github.com/NixOS/nixpkgs-channels/archive/${rev}.tar.gz"
4+
) {}

release.nix

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{ pkgs ? import ./pkgs.nix }:
2+
3+
with pkgs;
4+
let
5+
haskellPackages = haskell.packages.ghc865;
6+
strict = drv: haskell.lib.buildStrictly drv;
7+
drv = (haskellPackages.callPackage ./default.nix {}).overrideAttrs (attrs: {
8+
src = nix-gitignore.gitignoreSource [] ./.;
9+
});
10+
in
11+
rec {
12+
library = drv;
13+
libraryStrict = strict drv;
14+
application = drv;
15+
applicationStrict = strict drv;
16+
docker = dockerTools.buildImage {
17+
name = applicationStrict.name;
18+
contents = applicationStrict;
19+
config = {
20+
Cmd = [ "/bin/haskell-demo-exe" ];
21+
};
22+
};
23+
}

shell.nix

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,25 @@
1-
{
2-
pkgs ? import ./pkgs.nix,
3-
haskellPath ? "ghc843"
4-
}:
5-
with pkgs;
6-
let
7-
haskellPackages = lib.getAttrFromPath (lib.splitString "." haskellPath) haskell.packages;
8-
drv = (import ./default.nix { inherit pkgs haskellPath; }).env;
9-
in
10-
drv.overrideAttrs (attrs: {
11-
src = null;
12-
buildInputs = attrs.buildInputs ++ (with haskellPackages; [
13-
cabal2nix
14-
hpack
15-
cabal-install
16-
]);
17-
shellHook = attrs.shellHook + ''
18-
echo 'Entering ${attrs.name}'
19-
set -v
1+
{ pkgs ? import ./pkgs.nix }:
202

21-
cabal2nix --hpack . >./cabal.nix
22-
hpack --force
23-
cabal configure
3+
with pkgs;
4+
let
5+
haskellPackages = haskell.packages.ghc865;
6+
drv = (haskellPackages.callPackage ./default.nix {}).env;
7+
in
8+
drv.overrideAttrs (attrs: {
9+
src = null;
10+
nativeBuildInputs = attrs.nativeBuildInputs ++ (with haskellPackages; [
11+
cabal-install
12+
cabal2nix
13+
hpack
14+
]);
15+
shellHook = attrs.shellHook + ''
16+
echo 'Entering ${attrs.name}'
17+
set -v
2418
25-
set +v
26-
'';
27-
})
19+
cabal2nix --hpack . >./default.nix
20+
hpack --force
21+
cabal v2-configure
22+
23+
set +v
24+
'';
25+
})

0 commit comments

Comments
 (0)