Skip to content

Add haskell-nix.project (and project') #703

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jun 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/tutorials/clean-git.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ packages:
Then in `repoA/default.nix` we can use:

```
haskell-nix.cabalProject {
haskell-nix.project {
src = haskell-nix.haskellLib.cleanSourceWith {
src = haskell-nix.haskellLib.cleanGits {
name = "root";
Expand Down
45 changes: 24 additions & 21 deletions docs/tutorials/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,19 @@ $ cachix use iohk

## Scaffolding

The following configuration will use `stack.yaml` if it exists,
otherwise fallback to `cabal.project`.
The following work with `stack.yaml` and `cabal.project` based
projects.

Add `default.nix`:

```nix
{ haskellCompiler ? "ghc865"
{ # Default version of GHC to use (when not otherwise specified)
defaultCompilerNixName ? "ghc865"

# Fetch the latest haskell.nix and import its default.nix
, haskellNix ? import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz) {}
, haskellNix ? import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz) {
inherit defaultCompilerNixName;
}

# haskell.nix provides access to the nixpkgs pins which are used by our CI, hence
# you will be more likely to get cache hits when using these.
Expand All @@ -40,26 +43,26 @@ Add `default.nix`:

# import nixpkgs with overlays
, pkgs ? import nixpkgsSrc nixpkgsArgs
}: pkgs.haskell-nix.project {
# 'cleanGit' cleans a source directory based on the files known by git
src = pkgs.haskell-nix.haskellLib.cleanGit {
name = "haskell-nix-project";
src = ./.;
};
}
```

Or a shorter `default.nix` that uses the default nixpkgs and default GHC:

# 'cleanGit' cleans a source directory based on the files known by git
, src ? pkgs.haskell-nix.haskellLib.cleanGit {
```nix
{ haskellNix ? import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz) {}
, pkgs ? haskellNix.pkgs
}: pkgs.haskell-nix.project {
src = pkgs.haskell-nix.haskellLib.cleanGit {
name = "haskell-nix-project";
src = ./.;
}
, hasStack ? builtins.pathExists (./. + "/cabal.project")
, hasCabalProject ? builtins.pathExists (./. + "/stack.yaml")
}:

assert (if hasStack && hasCabalProject then throw "This project has both stack.yaml and cabal.project. Edit default.nix to pick the one you'd like to use." else true);

if hasStack
then pkgs.haskell-nix.stackProject
{ inherit src;
}
else pkgs.haskell-nix.cabalProject
{ inherit src;
compiler-nix-name = haskellCompiler;
}
};
}
```

!!! note "git dependencies"
Expand Down
20 changes: 10 additions & 10 deletions docs/tutorials/materialization.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ of an IFD (import from derviation).

## Why use materialization?

Using functions like `cabalProject`, `stackProject` and `hackage-package`
results in a lot of dependencies (all the dependencies of nix-tools
for instance).
Using functions like `project`, `cabalProject`, `stackProject`
and `hackage-package` results in a lot of dependencies (all the
dependencies of nix-tools for instance).

* They can be slow to calculate (even if no work needs to be done it
is not unusual for it to take 5 seconds per project).
Expand Down Expand Up @@ -59,8 +59,8 @@ trace: Using index-state: 2020-04-15T00:00:00Z for hlint
```

To materialize the nix files we need to take care to pin down the
inputs. For `cabalProject` and `hackage-package` this means
we must specify the `index-state` of hackage we want to use:
inputs. For cabal projects this means we must specify the
`index-state` of hackage we want to use:

```nix
let inherit (import ./. {}) sources nixpkgsArgs;
Expand Down Expand Up @@ -88,7 +88,7 @@ $ nix-hash --base32 --type sha256 /nix/store/8z6p4237rin3c6c1lmjwshmj8rdqrhw2-hl
```

We can add the hash as `plan-sha256` or (`stack-sha256` for
`stackProject`)
stack projects)

```nix
let inherit (import ./. {}) sources nixpkgsArgs;
Expand Down Expand Up @@ -191,10 +191,10 @@ the time, we would be better off just removing `materialized` and `plan-sha256`.

## How can we update the nix files with a script?

There are versions of the functions (`cabalProject'`, `stackProject'`
and `hackage-project`) that also return the nix as `plan-nix` or
`stack-nix`. By calling one of these functions without the
hash and materialized nix we can find out what nix files should be.
There are versions of the functions (`project'`, `cabalProject'`,
`stackProject'` and `hackage-project`) that also return the nix as
`plan-nix` or `stack-nix`. By calling one of these functions without
the hash and materialized nix we can find out what nix files should be.
For instance:

```nix
Expand Down
23 changes: 11 additions & 12 deletions docs/tutorials/source-repository-hashes.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ that we wish to use. This is mostly handled automatically by
system that is configured to use restricted mode (typically hydra)
it will need an aditionaly hash.

When using `cabalProject` or `stackProject` functions you can include
the hash needed in a comment.
When using `project`, `cabalProject` or `stackProject` functions
you can include the hash needed in a comment.

To calculate the hash use `nix-prefetch-git`:

Expand All @@ -24,7 +24,7 @@ $ nix-prefetch-git https://github.com/input-output-hk/haskell.nix.git bc01ebc05a
}
```

If you are using `cabalProject` add a `--sha256` comment to the
If you have a cabal project add a `--sha256` comment to the
`cabal.project` file:

```
Expand All @@ -36,7 +36,7 @@ source-repository-package
--sha256: 003lm3pm024vhbfmii7xcdd9v2rczpflxf7gdl2pyxia7p014i8z
```

If you are using `stackProject` add a `# nix-sha256` comment to the
If you have a stack project add a `# nix-sha256` comment to the
`stack.yaml` file:

```
Expand All @@ -48,12 +48,12 @@ extra-deps:
# nix-sha256: 003lm3pm024vhbfmii7xcdd9v2rczpflxf7gdl2pyxia7p014i8z
```

## lookupSha256
## sha256map

In some cases we cannot modify the `cabal.project` file to add the
`--sha256` comments. As an alternative we can pass in a `lookupSha256`
function to get them. For instance pandoc includes a `cabal.project`
file in hackage includes a `source-package-reference` to `pandoc-citeproc`:
In some cases we cannot modify the `cabal.project` or `stack.yaml` file
to add sha256 comments. As an alternative we can pass in a `sha256map`
For instance pandoc includes a `cabal.project` file in hackage includes a
`source-package-reference` to `pandoc-citeproc`:

```
{ haskell-nix, testSrc } :
Expand All @@ -64,10 +64,9 @@ let
index-state = "2020-04-15T00:00:00Z";
# Function that returns a sha256 string by looking up the location
# and tag in a nested attrset
lookupSha256 = { location, tag, ... }:
sha256map =
{ "https://github.com/jgm/pandoc-citeproc"."0.17"
= "0dxx8cp2xndpw3jwiawch2dkrkp15mil7pyx7dvd810pwc22pm2q"; }
."${location}"."${tag}";
= "0dxx8cp2xndpw3jwiawch2dkrkp15mil7pyx7dvd810pwc22pm2q"; };
};
in
pandoc.components.exes.pandoc
Expand Down
41 changes: 41 additions & 0 deletions overlays/haskell.nix
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,47 @@ final: prev: {
shells.ghc = p.hsPkgs.shellFor {};
};

# `project'` and `project` automatically select between `cabalProject`
# and `stackProject` (when possible) by looking for `stack.yaml` or
# `cabal.project` files. If both exist we can pass in one of:
# `projectFileName = "stack.yaml;"`
# `projectFileName = "cabal.project";`
# to let it know which to choose (or pick another name). If the
# selected file ends in a `.yaml` it is assumed to be for `stackProject`.
# If niether `stack.yaml` nor `cabal.project` exist `cabalProject` is
# used (as it will use a default `cabal.project`).
project' = { src, projectFileName ? null, ... }@args:
let
dir = __readDir (src.origSrcSubDir or src);
exists = fileName: builtins.elem (dir.${fileName} or "") ["regular" "symlink"];
stackYamlExists = exists "stack.yaml";
cabalProjectExists = exists "cabal.project";
selectedFileName =
if projectFileName != null
then projectFileName # Prefer the user selected project file name
else
if stackYamlExists && cabalProjectExists
then throw ("haskell-nix.project : both `stack.yaml` and `cabal.project` files exist "
+ "set `projectFileName = \"stack.yaml\";` or `projectFileName = \"cabal.project\";`")
else
if stackYamlExists
then "stack.yaml" # stack needs a stack.yaml
else "cabal.project"; # the cabal.project file is optional
in
if final.lib.hasSuffix ".yaml" selectedFileName
then stackProject' (args // { stackYaml = selectedFileName; })
else cabalProject' (args // { cabalProjectFileName = selectedFileName; });

# This is the same as the `cabalPackage` and `stackPackage` wrappers
# for `cabalPackage` and `stackPackage`.
project = args: let p = project' args;
in p.hsPkgs // {
# Provide `nix-shell -A shells.ghc` for users migrating from the reflex-platform.
# But we should encourage use of `nix-shell -A shellFor`
shells.ghc = p.hsPkgs.shellFor {};
} // final.lib.optionalAttrs (p ? stack-nix) { inherit (p) stack-nix; }
// final.lib.optionalAttrs (p ? plan-nix ) { inherit (p) plan-nix; };

# Like `cabalProject'`, but for building the GHCJS compiler.
# This is exposed to allow GHCJS developers to work on the GHCJS
# code in a nix-shell with `shellFor`.
Expand Down
4 changes: 2 additions & 2 deletions test/cabal-simple/default.nix
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Test a package set
{ stdenv, util, mkCabalProjectPkgSet, cabalProject', haskellLib, recurseIntoAttrs, testSrc }:
{ stdenv, util, mkCabalProjectPkgSet, project', haskellLib, recurseIntoAttrs, testSrc }:

with stdenv.lib;

Expand All @@ -12,7 +12,7 @@ let
}
];

project = cabalProject' {
project = project' {
src = testSrc "cabal-simple";
inherit modules;
};
Expand Down
3 changes: 2 additions & 1 deletion test/haskell-language-server/cabal.nix
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
{ testSrc, evalPackages, buildPackages }:

(buildPackages.haskell-nix.cabalProject {
(buildPackages.haskell-nix.project {
src = evalPackages.fetchgit {
url = "https://github.com/haskell/haskell-language-server.git";
fetchSubmodules = true;
rev = "d2654185eef1b0d703cebc694e85438e20600e37";
sha256 = "0s0k2i0imkcn9zykhrlqq0r4ssv25mwbpdyc675xkzgl1vj1l8kd";
};
projectFileName = "cabal.project";
sha256map = {
"https://github.com/wz1000/shake"."fb3859dca2e54d1bbb2c873e68ed225fa179fbef" = "0sa0jiwgyvjsmjwpfcpvzg2p7277aa0dgra1mm6afh2rfnjphz8z";
"https://github.com/peti/cabal-plan"."894b76c0b6bf8f7d2f881431df1f13959a8fce87" = "06iklj51d9kh9bhc42lrayypcpgkjrjvna59w920ln41rskhjr4y";
Expand Down
4 changes: 2 additions & 2 deletions test/haskell-language-server/stack.nix
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{ testSrc, haskell-nix, evalPackages, buildPackages }:

(buildPackages.haskell-nix.stackProject {
(buildPackages.haskell-nix.project {
src = evalPackages.fetchgit {
url = "https://github.com/haskell/haskell-language-server.git";
fetchSubmodules = true;
rev = "d2654185eef1b0d703cebc694e85438e20600e37";
sha256 = "0s0k2i0imkcn9zykhrlqq0r4ssv25mwbpdyc675xkzgl1vj1l8kd";
};
stackYaml = "stack-${haskell-nix.ghc.version}.yaml";
projectFileName = "stack-${haskell-nix.ghc.version}.yaml";
sha256map = {
"https://github.com/wz1000/shake.git"."fb3859dca2e54d1bbb2c873e68ed225fa179fbef" = "0sa0jiwgyvjsmjwpfcpvzg2p7277aa0dgra1mm6afh2rfnjphz8z";
"https://github.com/peti/cabal-plan.git"."894b76c0b6bf8f7d2f881431df1f13959a8fce87" = "06iklj51d9kh9bhc42lrayypcpgkjrjvna59w920ln41rskhjr4y";
Expand Down
4 changes: 2 additions & 2 deletions test/stack-local-resolver/default.nix
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{ stackProject', recurseIntoAttrs, testSrc }:
{ project', recurseIntoAttrs, testSrc }:

let
project = stackProject' {
project = project' {
src = testSrc "stack-local-resolver";
};
packages = project.hsPkgs;
Expand Down