add clarifying example to nix-env output selection

there is a very confusing warning in the Nixpkgs manual that
mischaracterises `nix-env` behavior, and this example shows what's
really happening.

note that it doesn't use `pkgs.runCommand` or other `pkgs.stdenv`
facilities, as deep down those set `meta.outputsToInstall` to very
particular defaults that do not generally apply to Nix.
This commit is contained in:
Valentin Gagarin 2023-09-18 20:08:48 +02:00
parent 2a52ec4e92
commit 408055a9dd

View file

@ -19,12 +19,15 @@ current generation of the active profile, to which a set of store paths
described by *args* is added. The arguments *args* map to store paths in described by *args* is added. The arguments *args* map to store paths in
a number of possible ways: a number of possible ways:
- By default, *args* is a set of derivation names denoting derivations
- By default, *args* is a set of [derivation] names denoting derivations
in the active Nix expression. These are realised, and the resulting in the active Nix expression. These are realised, and the resulting
output paths are installed. Currently installed derivations with a output paths are installed. Currently installed derivations with a
name equal to the name of a derivation being added are removed name equal to the name of a derivation being added are removed
unless the option `--preserve-installed` is specified. unless the option `--preserve-installed` is specified.
[derivation]: @docroot@/language/derivations.md
If there are multiple derivations matching a name in *args* that If there are multiple derivations matching a name in *args* that
have the same name (e.g., `gcc-3.3.6` and `gcc-4.1.1`), then the have the same name (e.g., `gcc-3.3.6` and `gcc-4.1.1`), then the
derivation with the highest *priority* is used. A derivation can derivation with the highest *priority* is used. A derivation can
@ -66,8 +69,59 @@ a number of possible ways:
- If *args* are store paths that are not store derivations, then these - If *args* are store paths that are not store derivations, then these
are [realised](@docroot@/command-ref/nix-store/realise.md) and installed. are [realised](@docroot@/command-ref/nix-store/realise.md) and installed.
- By default all outputs are installed for each derivation. That can - By default all outputs are installed for each derivation.
be reduced by setting `meta.outputsToInstall`. This can be overridden by adding a `meta.outputsToInstall` attribute on the derivation listing a subset of the output names.
<!-- TODO: add anchor link to `outputs` when #7320 is merged -->
Example:
The file `example.nix` defines a [derivation] with two outputs `foo` and `bar`, each containing a file.
```nix
# example.nix
let
pkgs = import <nixpkgs> {};
command = ''
${pkgs.coreutils}/bin/mkdir -p $foo $bar
echo foo > $foo/foo-file
echo bar > $bar/bar-file
'';
in
derivation {
name = "example";
builder = "${pkgs.bash}/bin/bash";
args = [ "-c" command ];
outputs = [ "foo" "bar" ];
system = builtins.currentSystem;
}
```
Installing from this Nix expression will make files from both outputs appear in the current profile.
```console
$ nix-env --install --file example.nix
installing 'example'
$ ls ~/.nix-profile
foo-file
bar-file
manifest.nix
```
Adding `meta.outputsToInstall` to that derivation will make `nix-env` only install files from the specified outputs.
```nix
# example-outputs.nix
import ./example.nix // { meta.outputsToInstall = [ "bar" ]; }
```
```console
$ nix-env --install --file example-outputs.nix
installing 'example'
$ ls ~/.nix-profile
bar-file
manifest.nix
```
# Flags # Flags