|
2 | 2 | lib
|
3 | 3 | , haskellLib
|
4 | 4 | }: {
|
| 5 | + # Provide a devshell profile (https://github.com/numtide/devshell), |
| 6 | + # adapted from the project normal shell. |
5 | 7 | devshell = final: prev: {
|
6 | 8 | 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 |
| - ''; |
63 | 9 | 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 ]); |
65 | 15 | env = lib.mapAttrsToList lib.nameValuePair {
|
66 | 16 | inherit (final.shell) CABAL_CONFIG NIX_GHC_LIBDIR;
|
67 | 17 | };
|
68 |
| - commands = [ |
69 |
| - { |
70 |
| - package = cabalWrapper; |
71 |
| - category = "development"; |
72 |
| - } |
73 |
| - ]; |
74 | 18 | };
|
75 | 19 | };
|
76 | 20 |
|
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: |
78 | 25 | 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; |
112 | 34 | };
|
113 | 35 |
|
114 | 36 | }
|
0 commit comments