Skip to content

Commit 9958922

Browse files
committed
nix: restore dev shell
This commit restores a working behavior for `nix-shell` or `nix develop`, for all supported GHC versions. When entering a `nix-shell`, or `nix develop .#haskell-language-server-ghcXxX-dev` you will get an environment with all the dependencies needed to run `cabal build`. This commit simplifies the mechanism. Before, the shell was populated with multiples GHC packages built by nix. These packages are the dependencies which are used by `nix build` to build haskell-language-server. However, cabal may ignore theses dependencies according to its build plan, so this approach had the following limitations: - It was building dependencies which were not used during the build - The nix shell may fail to start if an (possibly unneeded) dependency was failing to build. This new approach does not try to build Haskell dependencies with nix and use cabal for that. This changes the following: - cabal is responsible for the dependencies in the shell. As a developer using nix, you'll have the same workflow / dependencies as what will be used by a developer using another build environment (i.e. `cabal` or `stack` without nix). - nix won't try to build haskell dependencies and hence won't fail if dependencies cannot be built. - A bit of the code has been simplified, because we do not try to load Haskell dependencies in the nix-shell, we can remove all the logic used to detect dependencies (and take into account broken plugins). It however means that the dependencies used by `nix build` won't be tried until we effectively call `nix build` (or someone try to build haskell-language-server using a nix flake). Entering nix-shell also generates an alias command `cabal_project` which runs cabal with the correct project file if needed (e.g. for GHC 9.0 and 9.2). Users are
1 parent 6c6bc0f commit 9958922

File tree

3 files changed

+52
-64
lines changed

3 files changed

+52
-64
lines changed

configuration-ghc-901.nix

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,9 @@
22
{ pkgs }:
33

44
let
5-
disabledPlugins = [
6-
"hls-brittany-plugin"
7-
"hls-stylish-haskell-plugin"
8-
];
9-
105
hpkgsOverride = hself: hsuper:
116
with pkgs.haskell.lib;
127
{
13-
hlsDisabledPlugins = disabledPlugins;
14-
158
fourmolu = hself.fourmolu_0_4_0_0;
169
primitive-extras = hself.primitive-extras_0_10_1_2;
1710

@@ -31,6 +24,5 @@ let
3124
});
3225
};
3326
in {
34-
inherit disabledPlugins;
3527
tweakHpkgs = hpkgs: hpkgs.extend hpkgsOverride;
3628
}

configuration-ghc-921.nix

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,9 @@
22
{ pkgs, inputs }:
33

44
let
5-
disabledPlugins = [
6-
"hls-brittany-plugin"
7-
"hls-stylish-haskell-plugin"
8-
"hls-hlint-plugin"
9-
"hls-haddock-comments-plugin"
10-
"hls-alternate-number-format-plugin"
11-
"hls-eval-plugin"
12-
"hls-tactics-plugin"
13-
# That one is not technically a plugin, but by putting it in this list, we
14-
# get it removed from the top level list of requirement and it is not pull
15-
# in the nix shell.
16-
"shake-bench"
17-
];
18-
195
hpkgsOverride = hself: hsuper:
206
with pkgs.haskell.lib;
217
{
22-
hlsDisabledPlugins = disabledPlugins;
23-
248
fourmolu = hself.callCabal2nix "fourmolu" inputs.fourmolu {};
259
primitive-extras = hself.primitive-extras_0_10_1_2;
2610
ghc-exactprint = hself.callCabal2nix "ghc-exactprint" inputs.ghc-exactprint {};
@@ -52,6 +36,5 @@ let
5236
});
5337
};
5438
in {
55-
inherit disabledPlugins;
5639
tweakHpkgs = hpkgs: hpkgs.extend hpkgsOverride;
5740
}

flake.nix

Lines changed: 52 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -236,47 +236,60 @@
236236
dontInstall = true;
237237
};
238238

239-
# Create a development shell of hls project
240-
# See https://github.com/NixOS/nixpkgs/blob/5d4a430472cafada97888cc80672fab255231f57/pkgs/development/haskell-modules/make-package-set.nix#L319
241-
mkDevShell = hpkgs: cabalProject:
242-
with pkgs;
243-
hpkgs.shellFor {
244-
doBenchmark = true;
245-
packages = p:
246-
with builtins;
247-
map (name: p.${name}) (attrNames
248-
# Disable dependencies should not be part of the shell.
249-
(removeAttrs hlsSources (hpkgs.hlsDisabledPlugins or [])));
250-
# For theses tools packages, we use ghcDefault
251-
# This removes a rebuild with a different GHC version
252-
# Theses programs are tools, used as binary, independently of the
253-
# version of GHC.
254-
# The drawback of this approach is that our shell may pull two GHC
255-
# version in scope (the `ghcDefault` one, and the one defined in
256-
# `hpkgs`.)
257-
# The advantage is that we won't have to rebuild theses tools (and
258-
# dependencies) with a recent GHC which may not be supported by
259-
# them.
260-
buildInputs = [ gmp zlib ncurses capstone tracy (gen-hls-changelogs ghcDefault) pythonWithPackages ]
261-
++ [
262-
pkgs.cabal-install
263-
ghcDefault.hie-bios
264-
hlint
265-
# ormolu
266-
# stylish-haskell
267-
ghcDefault.opentelemetry-extra
268-
];
239+
mkDevShell = hpkgs: cabalProject: with pkgs; mkShell {
240+
# For theses tools packages, we use ghcDefault
241+
# This removes a rebuild with a different GHC version
242+
# Theses programs are tools, used as binary, independently of the
243+
# version of GHC.
244+
# The drawback of this approach is that our shell may pull two GHC
245+
# version in scope (the default one, and the one defined in
246+
# `hpkgs`.)
247+
# The advantage is that we won't have to rebuild theses tools (and
248+
# dependencies) with a recent GHC which may not be supported by
249+
# them.
250+
buildInputs = [
251+
# our compiling toolchain
252+
hpkgs.ghc
253+
pkgs.cabal-install
254+
# @guibou: I'm not sure hie-bios is needed
255+
ghcDefault.hie-bios
256+
# Dependencies needed to build some parts of hackage
257+
gmp zlib ncurses
258+
# Changelog tooling
259+
(gen-hls-changelogs ghcDefault)
260+
# For the documentation
261+
pythonWithPackages
262+
# @guibou: I'm not sure this is needed.
263+
hlint
264+
ghcDefault.opentelemetry-extra
265+
capstone tracy
266+
# ormolu
267+
# stylish-haskell
268+
];
269269

270-
src = null;
271-
shellHook = ''
272-
export LD_LIBRARY_PATH=${gmp}/lib:${zlib}/lib:${ncurses}/lib:${capstone}/lib
273-
export DYLD_LIBRARY_PATH=${gmp}/lib:${zlib}/lib:${ncurses}/lib:${capstone}/lib
274-
export PATH=$PATH:$HOME/.local/bin
275-
${(pre-commit-check ghcDefault).shellHook}
276270

277-
alias cabal='cabal --project-file=${cabalProject}'
278-
'';
279-
};
271+
shellHook = ''
272+
# @guibou: I'm not sure theses lines are needed
273+
export LD_LIBRARY_PATH=${gmp}/lib:${zlib}/lib:${ncurses}/lib:${capstone}/lib
274+
export DYLD_LIBRARY_PATH=${gmp}/lib:${zlib}/lib:${ncurses}/lib:${capstone}/lib
275+
export PATH=$PATH:$HOME/.local/bin
276+
277+
# Enable the shell hooks
278+
${(pre-commit-check ghcDefault).shellHook}
279+
280+
# If the cabal project file is not the default one.
281+
# Print a warning and generate an alias.
282+
if [ ${cabalProject} != "cabal.project" ]
283+
then
284+
echo "Cabal won't be able to build your project without using the project file "${cabalProject}", such as:"
285+
echo " cabal --project-file=${cabalProject}"
286+
echo "An alias "cabal_project" is available. Use it like:"
287+
echo " cabal_project build"
288+
289+
alias cabal_project='cabal --project-file=${cabalProject}'
290+
fi
291+
'';
292+
};
280293
# Create a hls executable
281294
# Copied from https://github.com/NixOS/nixpkgs/blob/210784b7c8f3d926b7db73bdad085f4dc5d79418/pkgs/development/tools/haskell/haskell-language-server/withWrapper.nix#L16
282295
mkExe = hpkgs:

0 commit comments

Comments
 (0)