haskell.nix/builder/shell-for.nix
Hamish Mackenzie 94f4679618 Add setup-depends to shellFor (#259)
* Add failing test for shellFor with setup-depends

* Add setup-depends to shellFor
2019-10-13 20:01:25 +08:00

94 lines
3.0 KiB
Nix

{ lib, stdenv, glibcLocales, pkgconfig, ghcForComponent, makeConfigFiles, hsPkgs, hoogleLocal, haskellLib }:
{ packages ? ps:
let
selected = haskellLib.selectLocalPackages ps;
in
builtins.trace ("Shell for " + toString (builtins.attrNames selected))
(builtins.attrValues selected)
, additional ? _: []
, withHoogle ? true
, exactDeps ? false
, ... } @ args:
let
selected = packages hsPkgs;
additionalSelected = additional hsPkgs;
selectedConfigs = map (p: p.components.all.config) selected;
name = if lib.length selected == 1
then "ghc-shell-for-${(lib.head selected).identifier.name}"
else "ghc-shell-for-packages";
# If `packages = [ a b ]` and `a` depends on `b`, don't build `b`,
# because cabal will end up ignoring that built version, assuming
# new-style commands.
packageInputs = lib.filter
(input: lib.all (cfg: input.identifier != cfg.identifier) selected)
(lib.concatMap (cfg: cfg.depends) selectedConfigs
++ additionalSelected
++ lib.concatMap (cfg: cfg.setup.config.depends or []) selected
);
# Add the system libraries and build tools of the selected haskell
# packages to the shell.
systemInputs = lib.concatMap (p: p.components.all.buildInputs) selected;
nativeBuildInputs = lib.concatMap (p: p.components.all.executableToolDepends) selected;
# Set up a "dummy" component to use with ghcForComponent.
component = {
depends = packageInputs;
libs = [];
frameworks = [];
doExactConfig = false;
};
configFiles = makeConfigFiles {
fullName = args.name or name;
identifier.name = name;
inherit component;
};
ghcEnv = ghcForComponent {
inherit configFiles;
componentName = name;
postInstall = lib.optionalString withHoogle ''
ln -s ${hoogleIndex}/bin/hoogle $out/bin
'';
};
hoogleIndex = let
# Get the doc package for a component, and add attributes that
# hoogle.nix expects.
docPackage = p: lib.getOutput "doc" p // {
pname = p.identifier.name;
haddockDir = lib.const p.haddockDir;
};
in hoogleLocal {
packages = map docPackage (haskellLib.flatLibDepends component);
# Need to add hoogle to hsPkgs.
# inherit (hsPkgs) hoogle;
};
mkDrvArgs = builtins.removeAttrs args ["packages" "additional" "withHoogle"];
in
stdenv.mkDerivation (mkDrvArgs // {
name = mkDrvArgs.name or name;
buildInputs = systemInputs
++ mkDrvArgs.buildInputs or []
++ lib.optional withHoogle hoogleIndex;
nativeBuildInputs = [ ghcEnv ]
++ nativeBuildInputs
++ mkDrvArgs.nativeBuildInputs or [];
phases = ["installPhase"];
installPhase = "echo $nativeBuildInputs $buildInputs > $out";
LANG = "en_US.UTF-8";
LOCALE_ARCHIVE = lib.optionalString (stdenv.hostPlatform.libc == "glibc") "${glibcLocales}/lib/locale/locale-archive";
passthru = (mkDrvArgs.passthru or {}) // {
ghc = ghcEnv;
};
} // lib.optionalAttrs exactDeps {
CABAL_CONFIG = "${configFiles}/cabal.config";
})