|
25 | 25 |
|
26 | 26 | selectedPackages = packages hsPkgs;
|
27 | 27 | additionalPackages = additional hsPkgs;
|
28 |
| - selectedComponents = components hsPkgs; |
| 28 | + directlySelectedComponents = components hsPkgs; |
29 | 29 |
|
30 |
| - # The configs of all the selected components |
31 |
| - selectedConfigs = map (c: c.config) selectedComponents |
32 |
| - ++ lib.optionals packageSetupDeps (map (p: p.setup.config) selectedPackages); |
33 |
| - |
34 |
| - name = if lib.length selectedPackages == 1 |
35 |
| - then "ghc-shell-for-${(lib.head selectedPackages).identifier.name}" |
36 |
| - else "ghc-shell-for-packages"; |
37 |
| - |
38 |
| - # Given a `packages = [ a b ]` we construct a shell with the dependencies of `a` and `b`. |
| 30 | + # Given `directlySelectedComponents = [ a b ]`, we construct a shell that includes all of their dependencies |
39 | 31 | #
|
40 |
| - # But if `a` depends on `b`, we don't want to include `b`, because |
| 32 | + # But we want to exclude `a` if it is a transitive dependecy of `b` |
| 33 | + # because: |
41 | 34 | # - cabal will end up ignoring that built version;
|
42 | 35 | # - The user has indicated that's what they're working on, so they probably don't want to have to build
|
43 | 36 | # it first (and it will change often).
|
44 |
| - # Generally we never want to include any of (the components of) the selected packages as dependencies. |
| 37 | + # Generally we never want to include any of `directlySelectedComponents` as dependencies. |
| 38 | + # |
| 39 | + # We do this by defining a set of `selectedComponents`, where `x` is in `selectedComponents` if and only if: |
| 40 | + # - `x` is in `directlySelectedComponents` |
| 41 | + # - `x` is a transitive dependency of something in `directlySelectedComponents` |
| 42 | + # and `x` transitively depends on something in `directlySelectedComponents` |
| 43 | + # We use the dependencies of `selectedComponents` filtering out members of `selectedComponents` |
45 | 44 | #
|
46 | 45 | # Furthermore, if `a` depends on `b`, `a` will include the library component of `b` in its `buildInputs`
|
47 | 46 | # (to make `propagatedBuildInputs` of `pkgconfig-depends` work). So we also need to filter those
|
48 | 47 | # (the pkgconfig depends of `b` will still be included in the
|
49 | 48 | # system shell's `buildInputs` via `b`'s own `buildInputs`).
|
50 |
| - # We have to do this slightly differently because we will be looking at the actual components rather |
51 |
| - # than the packages. |
52 | 49 |
|
53 |
| - # Given a list of `depends`, removes those which are components of packages which were selected as part of the shell. |
| 50 | + |
| 51 | + # all packages that are indirectly depended on by `directlySelectedComponents` |
| 52 | + # including `directlySelectedComponents` |
| 53 | + transitiveDependenciesComponents = |
| 54 | + builtins.listToAttrs |
| 55 | + (builtins.map (x: lib.nameValuePair (x.name) x) |
| 56 | + (haskellLib.flatLibDepends {depends = directlySelectedComponents;})); |
| 57 | + |
| 58 | + selectedComponentsBitmap = |
| 59 | + lib.mapAttrs |
| 60 | + (_: x: (builtins.any |
| 61 | + (dep: selectedComponentsBitmap."${(haskellLib.dependToLib dep).name}") x.config.depends)) |
| 62 | + transitiveDependenciesComponents |
| 63 | + // builtins.listToAttrs (map (x: lib.nameValuePair x.name true) directlySelectedComponents); # base case |
| 64 | + |
| 65 | + selectedComponents = |
| 66 | + lib.filter (x: selectedComponentsBitmap."${x.name}") (lib.attrValues transitiveDependenciesComponents); |
| 67 | + |
| 68 | + # Given a list of `depends`, removes those which are selected components |
54 | 69 | removeSelectedInputs =
|
55 |
| - # All the components of the selected packages: we shouldn't add any of these as dependencies |
56 |
| - let selectedPackageComponents = map (x: x.name) selectedComponents; |
57 |
| - in lib.filter (input: |
58 |
| - !(builtins.elem ((haskellLib.dependToLib input).name or null) selectedPackageComponents)); |
| 70 | + lib.filter (input: !(selectedComponentsBitmap."${((haskellLib.dependToLib input).name or null)}")); |
| 71 | + |
| 72 | + # The configs of all the selected components |
| 73 | + selectedConfigs = map (c: c.config) selectedComponents |
| 74 | + ++ lib.optionals packageSetupDeps (map (p: p.setup.config) selectedPackages); |
| 75 | + |
| 76 | + name = if lib.length selectedPackages == 1 |
| 77 | + then "ghc-shell-for-${(lib.head selectedPackages).identifier.name}" |
| 78 | + else "ghc-shell-for-packages"; |
59 | 79 |
|
60 |
| - # We need to remove any dependencies which are selected packages (see above). |
| 80 | + # We need to remove any dependencies which would bring in selected components (see above). |
61 | 81 | packageInputs = removeSelectedInputs (lib.concatMap (cfg: cfg.depends) selectedConfigs)
|
62 | 82 | ++ additionalPackages;
|
63 | 83 |
|
|
0 commit comments