Skip to content

Nix flake fix dev shells #2655

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 18 commits into from
Feb 16, 2022
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
12 changes: 8 additions & 4 deletions .github/workflows/nix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,15 +103,19 @@ jobs:
authToken: ${{ secrets.HLS_CACHIX_AUTH_TOKEN }}
- name: Build development shell
run: nix develop --print-build-logs --profile dev
- name: Build development shell (GHC 9.0.1)
run: nix develop --print-build-logs .#haskell-language-server-901-dev --profile dev
- name: Build all development shell (without nix dependencies)
run: nix develop --print-build-logs .#all-simple-dev-shells --profile dev
# We only build nix dev shell for current GHC version because some are
# failing with different GHC version on darwin.
- name: Build development shell with nix dependencies for current GHC version
run: nix develop --print-build-logs .#all-nix-dev-shells --profile dev
- name: Push development shell
if: ${{ env.HAS_TOKEN == 'true' }}
run: cachix push haskell-language-server dev
- name: Build binaries
run: nix build --print-build-logs
- name: Build binaries (GHC 9.0.1)
run: nix build --print-build-logs .#haskell-language-server-901
- name: Build all binaries
run: nix build --print-build-logs .#all-haskell-language-server
- name: Push binaries
if: ${{ env.HAS_TOKEN == 'true' }}
run: nix path-info --json | jq -r '.[].path' | cachix push haskell-language-server
Expand Down
2 changes: 2 additions & 0 deletions configuration-ghc-901.nix
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ let
hpkgsOverride = hself: hsuper:
with pkgs.haskell.lib;
{
hlsDisabledPlugins = disabledPlugins;

fourmolu = hself.fourmolu_0_4_0_0;
primitive-extras = hself.primitive-extras_0_10_1_2;

Expand Down
17 changes: 14 additions & 3 deletions configuration-ghc-921.nix
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,39 @@ let
disabledPlugins = [
"hls-brittany-plugin"
"hls-stylish-haskell-plugin"
"hls-hlint-plugin"
"hls-haddock-comments-plugin"
"hls-tactics-plugin"
# That one is not technically a plugin, but by putting it in this list, we
# get it removed from the top level list of requirement and it is not pull
# in the nix shell.
"shake-bench"
];

hpkgsOverride = hself: hsuper:
with pkgs.haskell.lib;
{
hlsDisabledPlugins = disabledPlugins;

fourmolu = hself.callCabal2nix "fourmolu" inputs.fourmolu {};
primitive-extras = hself.primitive-extras_0_10_1_2;
ghc-exactprint = hself.callCabal2nix "ghc-exactprint" inputs.ghc-exactprint {};
constraints-extras = hself.callCabal2nix "constraints-extras" inputs.constraints-extras {};
retrie = hself.callCabal2nix "retrie" inputs.retrie {};

# Hlint is still broken
hlint = doJailbreak (hself.callCabal2nix "hlint" inputs.hlint {});
hiedb = hself.hiedb_0_4_1_0;

# Re-generate HLS drv excluding some plugins
haskell-language-server =
hself.callCabal2nixWithOptions "haskell-language-server" ./.
(pkgs.lib.concatStringsSep " " [
"-f-brittany"
"-f-stylishhaskell"
"-f-stylishHaskell"
"-f-hlint"
"-f-haddockComments"
"-f-alternateNumberFormat"
"-f-eval"
"-f-tactics"
]) { };

# YOLO
Expand Down
13 changes: 13 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

149 changes: 109 additions & 40 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@
url = "https://hackage.haskell.org/package/hlint-3.3.6/hlint-3.3.6.tar.gz";
flake = false;
};
implicit-hie-cradle = {
url = "https://hackage.haskell.org/package/implicit-hie-cradle-0.3.0.5/implicit-hie-cradle-0.3.0.5.tar.gz";
flake = false;
};
};
outputs =
inputs@{ self, nixpkgs, flake-compat, flake-utils, pre-commit-hooks, gitignore, ... }:
Expand Down Expand Up @@ -113,11 +117,7 @@
lsp-types = hsuper.callCabal2nix "lsp-types" inputs.lsp-types {};
lsp-test = hsuper.callCabal2nix "lsp-test" inputs.lsp-test {};

implicit-hie-cradle = hself.callCabal2nix "implicit-hie-cradle"
(builtins.fetchTarball {
url = "https://hackage.haskell.org/package/implicit-hie-cradle-0.3.0.5/implicit-hie-cradle-0.3.0.5.tar.gz";
sha256 = "15a7g9x6cjk2b92hb2wilxx4550msxp1pmk5a2shiva821qaxnfq";
}) { };
implicit-hie-cradle = hself.callCabal2nix "implicit-hie-cradle" inputs.implicit-hie-cradle {};

# https://github.com/NixOS/nixpkgs/issues/140774
ormolu =
Expand Down Expand Up @@ -236,76 +236,145 @@
dontInstall = true;
};

mkDevShell = hpkgs: cabalProject: with pkgs; mkShell {
name = "haskell-language-server-dev-ghc${hpkgs.ghc.version}";
# For theses tools packages, we use ghcDefault
# This removes a rebuild with a different GHC version
# Theses programs are tools, used as binary, independently of the
# version of GHC.
# The drawback of this approach is that our shell may pull two GHC
# version in scope (the default one, and the one defined in
# `hpkgs`.)
# The advantage is that we won't have to rebuild theses tools (and
# dependencies) with a recent GHC which may not be supported by
# them.
buildInputs = [
# our compiling toolchain
hpkgs.ghc
pkgs.cabal-install
# @guibou: I'm not sure hie-bios is needed
ghcDefault.hie-bios
# Dependencies needed to build some parts of hackage
gmp zlib ncurses
# Changelog tooling
(gen-hls-changelogs ghcDefault)
# For the documentation
pythonWithPackages
# @guibou: I'm not sure this is needed.
hlint
ghcDefault.opentelemetry-extra
capstone tracy
# ormolu
# stylish-haskell
];


shellHook = ''
# @guibou: I'm not sure theses lines are needed
export LD_LIBRARY_PATH=${gmp}/lib:${zlib}/lib:${ncurses}/lib:${capstone}/lib
export DYLD_LIBRARY_PATH=${gmp}/lib:${zlib}/lib:${ncurses}/lib:${capstone}/lib
export PATH=$PATH:$HOME/.local/bin

# Enable the shell hooks
${(pre-commit-check ghcDefault).shellHook}

# If the cabal project file is not the default one.
# Print a warning and generate an alias.
if [ ${cabalProject} != "cabal.project" ]
then
echo "Cabal won't be able to build your project without using the project file "${cabalProject}", such as:"
echo " cabal --project-file=${cabalProject}"
echo "An alias "cabal_project" is available. Use it like:"
echo " cabal_project build"

alias cabal_project='cabal --project-file=${cabalProject}'
fi
'';
};

# Create a development shell of hls project
# See https://github.com/NixOS/nixpkgs/blob/5d4a430472cafada97888cc80672fab255231f57/pkgs/development/haskell-modules/make-package-set.nix#L319
mkDevShell = hpkgs:
mkDevShellWithNixDeps = hpkgs: cabalProject:
with pkgs;
let simpleShell = mkDevShell hpkgs cabalProject;
in
hpkgs.shellFor {
name = "haskell-language-server-dev-nix-ghc${hpkgs.ghc.version}";
inherit (simpleShell) shellHook buildInputs;

doBenchmark = true;
packages = p:
with builtins;
map (name: p.${name}) (attrNames
(if hpkgs.ghc.version == "9.0.1" then
removeAttrs hlsSources ghc901Config.disabledPlugins
else if hpkgs.ghc.version == "9.2.1" then
removeAttrs hlsSources ghc921Config.disabledPlugins
else
hlsSources));
buildInputs = [ gmp zlib ncurses capstone tracy (gen-hls-changelogs hpkgs) pythonWithPackages ]
++ (with hpkgs; [
cabal-install
hie-bios
hlint
# ormolu
# stylish-haskell
opentelemetry-extra
]);
# Disable dependencies should not be part of the shell.
(removeAttrs hlsSources (hpkgs.hlsDisabledPlugins or [])));

src = null;
shellHook = ''
export LD_LIBRARY_PATH=${gmp}/lib:${zlib}/lib:${ncurses}/lib:${capstone}/lib
export DYLD_LIBRARY_PATH=${gmp}/lib:${zlib}/lib:${ncurses}/lib:${capstone}/lib
export PATH=$PATH:$HOME/.local/bin
${if hpkgs.ghc.version != "9.0.1" then (pre-commit-check hpkgs).shellHook else ""}
'';
};
# Create a hls executable
# Copied from https://github.com/NixOS/nixpkgs/blob/210784b7c8f3d926b7db73bdad085f4dc5d79418/pkgs/development/tools/haskell/haskell-language-server/withWrapper.nix#L16
mkExe = hpkgs:
with pkgs.haskell.lib;
justStaticExecutables (overrideCabal hpkgs.haskell-language-server
(enableSharedExecutables (overrideCabal hpkgs.haskell-language-server
(_: {
postInstall = ''
remove-references-to -t ${hpkgs.ghc} $out/bin/haskell-language-server
remove-references-to -t ${hpkgs.shake.data} $out/bin/haskell-language-server
remove-references-to -t ${hpkgs.js-jquery.data} $out/bin/haskell-language-server
remove-references-to -t ${hpkgs.js-dgtable.data} $out/bin/haskell-language-server
remove-references-to -t ${hpkgs.js-flot.data} $out/bin/haskell-language-server
'';
}));
}))).overrideAttrs(old: {
pname = old.pname + "-ghc${hpkgs.ghc.version}";
});
in with pkgs; rec {
# Developement shell with only compiler
simpleDevShells = {
haskell-language-server-dev = mkDevShell ghcDefault "cabal.project";
haskell-language-server-884-dev = mkDevShell ghc884 "cabal.project";
haskell-language-server-8107-dev = mkDevShell ghc8107 "cabal.project";
haskell-language-server-901-dev = mkDevShell ghc901 "cabal-ghc90.project";
haskell-language-server-921-dev = mkDevShell ghc921 "cabal-ghc921.project";
};

packages = {
# dev shell
haskell-language-server-dev = mkDevShell ghcDefault;
haskell-language-server-884-dev = mkDevShell ghc884;
haskell-language-server-8107-dev = mkDevShell ghc8107;
haskell-language-server-901-dev = mkDevShell ghc901;
haskell-language-server-921-dev = mkDevShell ghc921;
# Developement shell, haskell packages are also provided by nix
nixDevShells = {
haskell-language-server-dev-nix = mkDevShellWithNixDeps ghcDefault "cabal.project";
haskell-language-server-884-dev-nix = mkDevShellWithNixDeps ghc884 "cabal.project";
haskell-language-server-8107-dev-nix = mkDevShellWithNixDeps ghc8107 "cabal.project";
haskell-language-server-901-dev-nix = mkDevShellWithNixDeps ghc901 "cabal-ghc90.project";
haskell-language-server-921-dev-nix = mkDevShellWithNixDeps ghc921 "cabal-ghc921.project";
};

# hls package
allPackages = {
haskell-language-server = mkExe ghcDefault;
haskell-language-server-884 = mkExe ghc884;
haskell-language-server-8107 = mkExe ghc8107;
haskell-language-server-901 = mkExe ghc901;
haskell-language-server-921 = mkExe ghc921;
};

devShells = simpleDevShells // nixDevShells;

packages = allPackages // {
# See https://github.com/NixOS/nix/issues/5591
# nix flake cannot build a list/set of derivation in one command.
# Using a linkFarmFromDrvs, I'm creating a unique entry point to
# build all HLS versions.
# This is used in CI to test and populate cache for packages
# distributed using nix.
all-haskell-language-server = linkFarmFromDrvs "all-haskell-language-server" (lib.unique (builtins.attrValues allPackages));

# Same for all shells
# We try to build as much as possible, but not much shells are
# working (especially on darwing), so this list is limited.
all-nix-dev-shells = linkFarmFromDrvs "all-dev-shells" (builtins.map (shell: shell.inputDerivation) (lib.unique [nixDevShells.haskell-language-server-dev-nix]));

# docs
all-simple-dev-shells = linkFarmFromDrvs "all-dev-shells" (builtins.map (shell: shell.inputDerivation) (lib.unique (builtins.attrValues simpleDevShells)));
docs = docs;
};

defaultPackage = packages.haskell-language-server;

devShell = packages.haskell-language-server-dev;
devShell = devShells.haskell-language-server-dev;
});
}