Skip to content

Commit

Permalink
Remove components.all (#776)
Browse files Browse the repository at this point in the history
It causes a lot of issues. To make this work:

* `shellFor` is updated to use `getAllComponents` instead of `.all`.
* `getAllComponents` is updated to work on the package rather than
  the package config.
* Tests updated to not use `.library` or `.exes.X` where appropriate.
* Documentation updated.
* Out of date examples removed.

As a bonus `shellFor` now takes a `components` argument that might be
useful for limiting the dependencies of the shell to just the ones
needed for the components you intend to work on.
  • Loading branch information
hamishmack committed Jul 21, 2020
1 parent cacfba0 commit b6de6ef
Show file tree
Hide file tree
Showing 29 changed files with 56 additions and 618 deletions.
8 changes: 3 additions & 5 deletions builder/comp-builder.nix
Expand Up @@ -65,9 +65,7 @@ let
then builtins.trace ("Cleaning component source not supported for hpack package: " + name) src
else haskellLib.cleanCabalComponent package component src;

nameOnly = if haskellLib.isAll componentId
then "${package.identifier.name}-all"
else "${package.identifier.name}-${componentId.ctype}-${componentId.cname}";
nameOnly = "${package.identifier.name}-${componentId.ctype}-${componentId.cname}";

fullName = "${nameOnly}-${package.identifier.version}";

Expand Down Expand Up @@ -293,7 +291,7 @@ let
in ''
runHook preInstall
$SETUP_HS copy ${lib.concatStringsSep " " setupInstallFlags}
${lib.optionalString (haskellLib.isLibrary componentId || haskellLib.isAll componentId) ''
${lib.optionalString (haskellLib.isLibrary componentId) ''
$SETUP_HS register --gen-pkg-config=${name}.conf
${ghc.targetPrefix}ghc-pkg -v0 init $out/package.conf.d
if [ -d "${name}.conf" ]; then
Expand Down Expand Up @@ -326,7 +324,7 @@ let
echo "package-id $id" >> $out/envDep
fi
''}
${(lib.optionalString (haskellLib.isTest componentId || haskellLib.isBenchmark componentId || haskellLib.isAll componentId) ''
${(lib.optionalString (haskellLib.isTest componentId || haskellLib.isBenchmark componentId) ''
mkdir -p $out/bin
if [ -f ${testExecutable} ]; then
mkdir -p $(dirname $out/bin/${exeName})
Expand Down
18 changes: 14 additions & 4 deletions builder/shell-for.nix
@@ -1,11 +1,20 @@
{ lib, stdenv, glibcLocales, pkgconfig, ghcForComponent, makeConfigFiles, hsPkgs, hoogleLocal, haskellLib, buildPackages, compiler }:

{ packages ? ps:
{ # `packages` function selects packages that will be worked on in the shell itself.
# These packages will not be built by `shellFor`, but their
# dependencies will be included in the shell's `ghc-pkg list`.
packages ? ps:
let
selected = haskellLib.selectLocalPackages ps;
in
builtins.trace ("Shell for " + toString (builtins.attrNames selected))
(builtins.attrValues selected)
# `components` function selects components that will be worked on in the shell itself.
# By default `shellFor` will include the dependencies of all of the components
# in the selected packages. If only as subset of the components will be
# worked on in the shell then we can pass a different `components` function
# to select those.
, components ? ps: lib.concatMap haskellLib.getAllComponents (packages hsPkgs)
, additional ? _: []
, withHoogle ? true
, exactDeps ? false
Expand All @@ -16,8 +25,9 @@ let
# TODO find out why hoogle index creation can be made to work for cross compilers
withHoogle' = withHoogle && !haskellLib.isCrossHost;
selected = packages hsPkgs;
selectedComponents = components hsPkgs;
additionalSelected = additional hsPkgs;
selectedConfigs = map (p: p.components.all.config) selected;
selectedConfigs = map (c: c.config) selectedComponents;

name = if lib.length selected == 1
then "ghc-shell-for-${(lib.head selected).identifier.name}"
Expand Down Expand Up @@ -45,9 +55,9 @@ let
# Add the system libraries and build tools of the selected haskell
# packages to the shell.
systemInputs = removeSelectedInputs (lib.concatMap
(p: p.components.all.buildInputs ++ p.components.all.propagatedBuildInputs) selected);
(c: c.buildInputs ++ c.propagatedBuildInputs) selectedComponents);
nativeBuildInputs = removeSelected
(lib.concatMap (p: p.components.all.executableToolDepends) selected);
(lib.concatMap (c: c.executableToolDepends) selectedComponents);

# Set up a "dummy" component to use with ghcForComponent.
component = {
Expand Down
5 changes: 5 additions & 0 deletions changelog.md
@@ -1,6 +1,11 @@
This file contains a summary of changes to Haskell.nix and `nix-tools`
that will impact users.

## July 21, 2020
* Removed `components.all`, use `symlinkJoin` on components.exes or
`shellFor` if you need a shell.
* Added `components` arguemnt to `shellFor`.

## July 21, 2020
* Added GHC 8.8.4 and replaced 8.8.3 in tests and as the ghc
used to build nix-tools for stack projects.
Expand Down
5 changes: 1 addition & 4 deletions docs/reference/library.md
Expand Up @@ -70,7 +70,6 @@ components = {
exes = { NAME = COMPONENT; };
tests = { NAME = COMPONENT; };
benchmarks = { NAME = COMPONENT; };
all = COMPONENT;
}
```

Expand All @@ -80,9 +79,6 @@ In [Haskell.nix][], a _component_ is a derivation corresponding to a
[Cabal component](https://www.haskell.org/cabal/users-guide/developing-packages.html)
of a package.

[Haskell.nix][] also defines a special `all` component, which is the
union of all components in the package.

## Identifier

A package identifier is an attrset pair of `name` and `version`.
Expand Down Expand Up @@ -427,6 +423,7 @@ shellFor =
| Argument | Type | Description |
|----------------|------|---------------------|
| `packages` | Function | Package selection function. It takes a list of [Haskell packages](#haskell-package) and returns a subset of these packages. |
| `components` | Function | Similar to `packages`, by default all the components of the selected packages are selected. |
| `additional` | Function | Similar to `packages`, but the selected packages are built and included in `ghc-pkg list` (not just their dependencies). |
| `withHoogle` | Boolean | Whether to build a Hoogle documentation index and provide the `hoogle` command. |
| `exactDeps` | Boolean | Prevents the Cabal solver from choosing any package dependency other than what are in the package set. |
Expand Down
20 changes: 2 additions & 18 deletions docs/tutorials/development.md
Expand Up @@ -24,25 +24,9 @@ it exists in a file called `default.nix`.
on it. Starting Cabal 3.0 `cabal build` will work out of the box, as
new style builds are the default.

## How to get a development shell for a package
## How to get a development shell

Run a `nix‑shell` on `components.all` of your package. `all` is a
synthetic component whose dependencies are the union of the
dependencies of all components in the package. Therefore, you will be
able to build the test suites because their dependencies will be
included.

```nix
# shell.nix
let
hsPkgs = import ./default.nix {};
in
hsPkgs.my-package.components.all
```

## How to get a development shell for a multi-package project

If you have a Cabal or Stack project with multiple packages
If you have a Cabal or Stack project with one or more packages
(i.e. multiple `.cabal` files, not a single package with multiple
components), then you will need a development environment that
contains the _dependencies_ of your packages, but not the packages
Expand Down
41 changes: 0 additions & 41 deletions examples/Cabal-install-folder.diff

This file was deleted.

150 changes: 0 additions & 150 deletions examples/cardano-sl-args.nix

This file was deleted.

3 changes: 0 additions & 3 deletions examples/cardano-sl-mingw32.nix

This file was deleted.

3 changes: 0 additions & 3 deletions examples/cardano-sl.nix

This file was deleted.

0 comments on commit b6de6ef

Please sign in to comment.