Skip to content

Commit 287f4da

Browse files
committed
Workaround for cabal trying to build dependencies in nix-shell
For source-repository-package's, cabal tries to build them on its own, even when all dependencies are already provided by Nix. Relevant issues: - haskell/cabal#6049 - IntersectMBO/ouroboros-network#645 - haskell/cabal#5586 (comment) This seems to be a problem even with a cabal that includes haskell/cabal#6917 (see input-output-hk/haskell.nix#720 (comment) for how to test a cabal-install 3.4) The only known workaround is to remove the source-repository-package sections from cabal.project, but this should only be done for cabal when used from a nix-shell, not from cabal without a nix-shell, and not outside the nix-shell. To make this work smoothly, the script `scripts/nix-setup` can be used, which splits the source-repository-package sections into cabal.project.srcs, which is then again included from here (to make the Nix setup still work). Running the script again undoes it.
1 parent 4dce3b3 commit 287f4da

File tree

4 files changed

+77
-5
lines changed

4 files changed

+77
-5
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ dist-newstyle
88
.ghc.environment.*
99
cabal.project.local*
1010
cabal.project.local~
11+
cabal.project.srcs
1112
dist/
1213

1314
stack.yaml.local.lock

default.nix

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ let
1616
sha256 = "sha256-kFLfYQ+8ogz4uycvriAszwP3Af7yqRGrxH6l6HmnKuc=";
1717
})
1818
{ inherit system; };
19-
morphoPkgs = import ./nix/morpho-node.nix { inherit pkgs src haskellCompiler profile; };
20-
shell = morphoPkgs.shellFor {
19+
morphoPkgs = nixShell: import ./nix/morpho-node.nix { inherit pkgs src haskellCompiler nixShell profile; };
20+
shell = (morphoPkgs true).shellFor {
2121
packages = ps: with ps; [
2222
morpho-checkpoint-node
2323
];
@@ -39,8 +39,9 @@ let
3939
# Systemd won't build on darwin, checking first we're not on a
4040
# Darwin env.
4141
(pkgs.stdenv.lib.optional (!pkgs.stdenv.isDarwin) pkgs.systemd);
42-
#exactDeps = false;
42+
exactDeps = true;
4343
};
4444
# Instantiate a package set using the generated file.
45-
in
46-
morphoPkgs // { inherit shell pkgs mantis; }
45+
in morphoPkgs false // {
46+
inherit shell pkgs mantis;
47+
}

nix/morpho-node.nix

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,44 @@
22
, src
33
, haskellCompiler ? "ghc865"
44
, profile
5+
, nixShell
56
, ...
67
}:
78

89
pkgs.haskell-nix.cabalProject {
910
inherit src;
1011
name = "morpho-checkpoint-node";
1112
compiler-nix-name = haskellCompiler;
13+
14+
# For source-repository-package's, cabal tries to build them on its own, even
15+
# when all dependencies are already provided by Nix. Relevant issues:
16+
# - https://github.com/haskell/cabal/issues/6049
17+
# - https://github.com/input-output-hk/ouroboros-network/pull/645
18+
# - https://github.com/haskell/cabal/issues/5586#issuecomment-479576084
19+
#
20+
# This seems to be a problem even with a cabal that includes
21+
# https://github.com/haskell/cabal/pull/6917 (see
22+
# https://github.com/input-output-hk/haskell.nix/issues/720#issuecomment-745397468
23+
# for how to test a cabal-install 3.4)
24+
#
25+
# The only known workaround is to remove the source-repository-package
26+
# sections from cabal.project, but this should only be done for cabal when
27+
# used from a nix-shell, not from cabal without a nix-shell, and not outside
28+
# the nix-shell.
29+
#
30+
# To make this work smoothly, the script `scripts/nix-setup` can be used,
31+
# which splits the source-repository-package sections into cabal.project.srcs,
32+
# which is then again included from here (to make the Nix setup still work).
33+
# Running the script again undoes it.
34+
cabalProject =
35+
let
36+
exists = builtins.pathExists (../cabal.project.srcs);
37+
standard = builtins.readFile (src + "/cabal.project");
38+
sources = builtins.readFile (../cabal.project.srcs);
39+
in if exists then standard + "\n" + sources
40+
else if nixShell then throw "You need to run scripts/nix-setup first"
41+
else standard;
42+
1243
pkg-def-extras = [
1344
(hackage: {
1445
packages = {

scripts/nix-setup

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
tmp=$(mktemp -d)
5+
trap 'rm -rf "$tmp"' exit
6+
7+
if [[ ! -f cabal.project.srcs ]]; then
8+
# We later mark cabal.project as not having any changes, since we remove
9+
# source-repository-package sections from it but don't want the user to commit that
10+
# But if the user already has changes to it, that would make them not commit their own changes too
11+
# So make the user either stage or commit the changes to prevent this
12+
if ! git diff --exit-code --quiet cabal.project; then
13+
echo "cabal.project has unstaged changes. Stage or commit them first to use this script" >&2
14+
exit 1
15+
fi
16+
echo "Setting up cabal.project to work with nix-shell" >&2
17+
18+
# Splits the file at the first occurence of source-repository-package
19+
csplit -s -f "$tmp/cabal.project.split." cabal.project /source-repository-package/
20+
mv "$tmp/cabal.project.split.00" cabal.project
21+
mv "$tmp/cabal.project.split.01" cabal.project.srcs
22+
23+
# Prevent modification of these files since we later mark them as not having any changes
24+
chmod -w cabal.project cabal.project.srcs
25+
26+
# In order to prevent the user from committing the changes to cabal.project, tell git that it should assume it wasn't changed
27+
git update-index --assume-unchanged cabal.project
28+
else
29+
echo "Undoing cabal.project setup for nix-shell" >&2
30+
31+
# Combine the split files into one again
32+
cat cabal.project cabal.project.srcs > "$tmp/cabal.project"
33+
chmod +w cabal.project cabal.project.srcs
34+
rm cabal.project.srcs
35+
mv "$tmp/cabal.project" cabal.project
36+
37+
# Tell git to track changes to cabal.project again
38+
git update-index --no-assume-unchanged cabal.project
39+
fi

0 commit comments

Comments
 (0)