@@ -2,113 +2,35 @@
22 lib
33, haskellLib
44}: {
5+ # Provide a devshell profile (https://github.com/numtide/devshell),
6+ # adapted from the project normal shell.
57 devshell = final: prev: {
68 devshell = let
7− cabal-install = final.pkgs.buildPackages.haskell-nix.cabal-install.${final.args.compiler-nix-name};
8− inherit (final.pkgs.buildPackages) runCommand runtimeShell;
9− cabalWrapper = runCommand "cabal" { inherit (cabal-install) meta; } ''
10− mkdir -p $out/bin
11− cat << EOF > $out/bin/cabal
12− #!${runtimeShell}
13− set -euo pipefail
14−
15− find_up() {
16− while [[ \$PWD != / ]] ; do
17− if [[ -e "\$1" ]]; then
18− echo "\$PWD"
19− return
20− fi
21− cd ..
22− done
23− }
24−
25− toplevel=\$(find_up "cabal.project")
26−
27− if [[ -n "\$toplevel" ]]; then
28− cabal_project="\$toplevel/cabal.project"
29− nix_cabal_project=\$toplevel/.nix-cabal.project
30− extra_cabal_opts=("--project-file=\$nix_cabal_project")
31− awk '
32− # Add comment with explanation of file
33− BEGIN {
34− print "-- Generated from '"\$cabal_project"' by the wrapper script"
35− print "-- ${placeholder "out"}/cabal"
36− print "-- Add this file to your .gitignore\n"
37− }
38−
39− # Matches all section starts
40− /^[^ ]/ {
41− # Remember the section name (they can span multiple lines)
42− section = \$0
43− }
44− # Matches every line
45− // {
46− # Only print the line if it is not in the section we want to omit
47− if (section != "source-repository-package")
48− print \$0
49− }
50− ' "\$cabal_project" > "\$nix_cabal_project"
51− else
52− extra_cabal_opts=()
53− fi
54−
55− cabal=${placeholder "out"}/bin/.cabal
56− >&2 echo "\$cabal \''${extra_cabal_opts[@]} \$@"
57− exec "\$cabal" "\''${extra_cabal_opts[@]}" "\$@"
58− EOF
59− cp -rn ${cabal-install}/* $out/
60− cp ${cabal-install}/bin/cabal $out/bin/.cabal
61− chmod +x $out/bin/*
62− '';
639 in {
64− packages = final.shell.nativeBuildInputs;
10+ packages = final.shell.nativeBuildInputs
11+ # devshell does not use pkgs.mkShell / pkgs.stdenv.mkDerivation,
12+ # so we need to explicit required dependencies which
13+ # are provided implicitely when using the normal shell:
14+ ++ (with final.pkgs; [ binutils git gcc glibc gawk gnugrep bash coreutils pkg-config ]);
6515 env = lib.mapAttrsToList lib.nameValuePair {
6616 inherit (final.shell) CABAL_CONFIG NIX_GHC_LIBDIR;
6717 };
68− commands = [
69− {
70− package = cabalWrapper;
71− category = "development";
72− }
73− ];
7418 };
7519 };
7620
77− projectComponents = final: prev: let
21+ # Provides easily accessible attrset for each type of
22+ # components belonging to the project packages.
23+ projectComponents = final: prev: {
24+ # local project packages:
7825 packages = haskellLib.selectProjectPackages final.hsPkgs;
79− # used to materialize `packages-exes.nix` (project packages and exes list) to avoid some evaluations:
80− packagesExes = lib.genAttrs
81− (lib.attrNames final.packages)
82− (name: lib.attrNames final.hsPkgs.${name}.components.exes);
83− collectExes = packagesExes: lib.listToAttrs (lib.concatLists (lib.mapAttrsToList
84− (p: map (exe: lib.nameValuePair exe final.hsPkgs.${p}.components.exes.${exe})) packagesExes));
85− in {
86− # local project packages:
87− packages = haskellLib.selectProjectPackages final.hsPkgs;
88− # set of all exes (as first level entries):
89− exes = collectExes packagesExes;
90− # set of all exes (as first level entries), mapped from a materialized set of packages and exes set (generated via `generatePackagesExes`):
91− exesFrom = packagesExesMat: collectExes (import packagesExesMat);
92− # `tests` are the test suites which have been built.
93− tests = haskellLib.collectComponents' "tests" final.packages;
94− # `benchmarks` (only built, not run).
95− benchmarks = haskellLib.collectComponents' "benchmarks" final.packages;
96− # `checks` collect results of executing the tests:
97− checks = haskellLib.collectChecks' final.packages;
98−
99− generatePackagesExesMat = let
100− nixFile = builtins.toFile "packages-exes.nix" (lib.generators.toPretty {} packagesExes);
101− in final.pkgs.buildPackages.writeShellScript "generate-packages-exes" ''
102− set -euo pipefail
103−
104− TARGET="$1"
105− TARGET_DIR="$(dirname "$TARGET")"
106−
107− mkdir -p "$TARGET_DIR"
108− rm -rf "$TARGET"
109− cp -r ${nixFile} "$TARGET"
110− chmod -R +w "$TARGET"
111− '';
26+ # set of all exes (as first level entries):
27+ exes = lib.foldl' lib.mergeAttrs { } (map (p: p.components.exes) (lib.attrValues final.packages));
28+ # `tests` are the test suites which have been built.
29+ tests = haskellLib.collectComponents' "tests" final.packages;
30+ # `benchmarks` (only built, not run).
31+ benchmarks = haskellLib.collectComponents' "benchmarks" final.packages;
32+ # `checks` collect results of executing the tests:
33+ checks = haskellLib.collectChecks' final.packages;
11234 };
11335
11436}