From 408055a9ddf855e32a59e07e564ad893b2cb2cdf Mon Sep 17 00:00:00 2001 From: Valentin Gagarin Date: Mon, 18 Sep 2023 20:08:48 +0200 Subject: [PATCH] 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. --- doc/manual/src/command-ref/nix-env/install.md | 60 ++++++++++++++++++- 1 file changed, 57 insertions(+), 3 deletions(-) diff --git a/doc/manual/src/command-ref/nix-env/install.md b/doc/manual/src/command-ref/nix-env/install.md index 5dc04c385..95648e9e0 100644 --- a/doc/manual/src/command-ref/nix-env/install.md +++ b/doc/manual/src/command-ref/nix-env/install.md @@ -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 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 output paths are installed. Currently installed derivations with a name equal to the name of a derivation being added are removed unless the option `--preserve-installed` is specified. + [derivation]: @docroot@/language/derivations.md + 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 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 are [realised](@docroot@/command-ref/nix-store/realise.md) and installed. - - By default all outputs are installed for each derivation. That can - be reduced by setting `meta.outputsToInstall`. + - By default all outputs are installed for each derivation. + This can be overridden by adding a `meta.outputsToInstall` attribute on the derivation listing a subset of the output names. + + + + Example: + + The file `example.nix` defines a [derivation] with two outputs `foo` and `bar`, each containing a file. + + ```nix + # example.nix + let + pkgs = import {}; + 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