diff --git a/doc/manual/src/command-ref/env-common.md b/doc/manual/src/command-ref/env-common.md
index d3f5f9c14..0b5017882 100644
--- a/doc/manual/src/command-ref/env-common.md
+++ b/doc/manual/src/command-ref/env-common.md
@@ -9,22 +9,26 @@ Most Nix commands interpret the following environment variables:
- [`NIX_PATH`](#env-NIX_PATH)
- A colon-separated list of directories used to look up the location of Nix
- expressions using [paths](@docroot@/language/types.md#type-path)
- enclosed in angle brackets (i.e., ``),
- e.g. `/home/eelco/Dev:/etc/nixos`. It can be extended using the
- [`-I` option](@docroot@/command-ref/opt-common.md#opt-I).
+ A colon-separated list of search path entries used to resolve [lookup paths](@docroot@/language/constructs/lookup-path.md).
- If `NIX_PATH` is not set at all, Nix will fall back to the following list in [impure](@docroot@/command-ref/conf-file.md#conf-pure-eval) and [unrestricted](@docroot@/command-ref/conf-file.md#conf-restrict-eval) evaluation mode:
+ This environment variable overrides the value of the [`nix-path` configuration setting](@docroot@/command-ref/conf-file.md#conf-nix-path).
- 1. `$HOME/.nix-defexpr/channels`
- 2. `nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixpkgs`
- 3. `/nix/var/nix/profiles/per-user/root/channels`
+ It can be extended using the [`-I` option](@docroot@/command-ref/opt-common.md#opt-I).
+
+ > **Example**
+ >
+ > ```bash
+ > $ export NIX_PATH=`/home/eelco/Dev:nixos-config=/etc/nixos
+ > ```
If `NIX_PATH` is set to an empty string, resolving search paths will always fail.
- For example, attempting to use `` will produce:
- error: file 'nixpkgs' was not found in the Nix search path
+ > **Example**
+ >
+ > ```bash
+ > $ NIX_PATH= nix-instantiate --eval ''
+ > error: file 'nixpkgs' was not found in the Nix search path (add it using $NIX_PATH or -I)
+ > ```
- [`NIX_IGNORE_SYMLINK_STORE`](#env-NIX_IGNORE_SYMLINK_STORE)
diff --git a/doc/manual/src/command-ref/opt-common.md b/doc/manual/src/command-ref/opt-common.md
index a42909e2d..69a700207 100644
--- a/doc/manual/src/command-ref/opt-common.md
+++ b/doc/manual/src/command-ref/opt-common.md
@@ -37,7 +37,7 @@ Most Nix commands accept the following command-line options:
Print even more informational messages.
- `4` “Debug”
-
+
Print debug information.
- `5` “Vomit”
@@ -187,11 +187,12 @@ Most Nix commands accept the following command-line options:
For `nix-shell`, this option is commonly used to give you a shell in which you can build the packages returned by the expression.
If you want to get a shell which contain the *built* packages ready for use, give your expression to the `nix-shell --packages ` convenience flag instead.
-- [`-I`](#opt-I) *path*
+- [`-I` / `--include`](#opt-I) *path*
- Add an entry to the [Nix expression search path](@docroot@/command-ref/conf-file.md#conf-nix-path).
+ Add an entry to the list of search paths used to resolve [lookup paths](@docroot@/language/constructs/lookup-path.md).
This option may be given multiple times.
- Paths added through `-I` take precedence over [`NIX_PATH`](@docroot@/command-ref/env-common.md#env-NIX_PATH).
+
+ Paths added through `-I` take precedence over the [`nix-path` configuration setting](@docroot@/command-ref/conf-file.md#conf-nix-path) and the [`NIX_PATH` environment variable](@docroot@/command-ref/env-common.md#env-NIX_PATH).
- [`--option`](#opt-option) *name* *value*
diff --git a/src/libcmd/common-eval-args.cc b/src/libcmd/common-eval-args.cc
index decadd751..fcef92487 100644
--- a/src/libcmd/common-eval-args.cc
+++ b/src/libcmd/common-eval-args.cc
@@ -91,75 +91,11 @@ MixEvalArgs::MixEvalArgs()
.longName = "include",
.shortName = 'I',
.description = R"(
- Add *path* to the Nix search path. The Nix search path is
- initialized from the colon-separated [`NIX_PATH`](@docroot@/command-ref/env-common.md#env-NIX_PATH) environment
- variable, and is used to look up the location of Nix expressions using [paths](@docroot@/language/types.md#type-path) enclosed in angle
- brackets (i.e., ``).
+ Add *path* to search path entries used to resolve [lookup paths](@docroot@/language/constructs/lookup-path.md)
- For instance, passing
+ This option may be given multiple times.
- ```
- -I /home/eelco/Dev
- -I /etc/nixos
- ```
-
- will cause Nix to look for paths relative to `/home/eelco/Dev` and
- `/etc/nixos`, in that order. This is equivalent to setting the
- `NIX_PATH` environment variable to
-
- ```
- /home/eelco/Dev:/etc/nixos
- ```
-
- It is also possible to match paths against a prefix. For example,
- passing
-
- ```
- -I nixpkgs=/home/eelco/Dev/nixpkgs-branch
- -I /etc/nixos
- ```
-
- will cause Nix to search for `` in
- `/home/eelco/Dev/nixpkgs-branch/path` and `/etc/nixos/nixpkgs/path`.
-
- If a path in the Nix search path starts with `http://` or `https://`,
- it is interpreted as the URL of a tarball that will be downloaded and
- unpacked to a temporary location. The tarball must consist of a single
- top-level directory. For example, passing
-
- ```
- -I nixpkgs=https://github.com/NixOS/nixpkgs/archive/master.tar.gz
- ```
-
- tells Nix to download and use the current contents of the `master`
- branch in the `nixpkgs` repository.
-
- The URLs of the tarballs from the official `nixos.org` channels
- (see [the manual page for `nix-channel`](../nix-channel.md)) can be
- abbreviated as `channel:`. For instance, the
- following two flags are equivalent:
-
- ```
- -I nixpkgs=channel:nixos-21.05
- -I nixpkgs=https://nixos.org/channels/nixos-21.05/nixexprs.tar.xz
- ```
-
- You can also fetch source trees using [flake URLs](./nix3-flake.md#url-like-syntax) and add them to the
- search path. For instance,
-
- ```
- -I nixpkgs=flake:nixpkgs
- ```
-
- specifies that the prefix `nixpkgs` shall refer to the source tree
- downloaded from the `nixpkgs` entry in the flake registry. Similarly,
-
- ```
- -I nixpkgs=flake:github:NixOS/nixpkgs/nixos-22.05
- ```
-
- makes `` refer to a particular branch of the
- `NixOS/nixpkgs` repository on GitHub.
+ Paths added through `-I` take precedence over the [`nix-path` configuration setting](@docroot@/command-ref/conf-file.md#conf-nix-path) and the [`NIX_PATH` environment variable](@docroot@/command-ref/env-common.md#env-NIX_PATH).
)",
.category = category,
.labels = {"path"},
diff --git a/src/libexpr/eval-settings.hh b/src/libexpr/eval-settings.hh
index 30a8c5c58..0cfc14c1b 100644
--- a/src/libexpr/eval-settings.hh
+++ b/src/libexpr/eval-settings.hh
@@ -79,19 +79,24 @@ struct EvalSettings : Config
This setting determines the value of
[`builtins.nixPath`](@docroot@/language/builtins.md#builtins-nixPath) and can be used with [`builtins.findFile`](@docroot@/language/builtins.md#builtins-findFile).
- The default value is
+ - The configuration setting is overridden by the [`NIX_PATH`](@docroot@/command-ref/env-common.md#env-NIX_PATH)
+ environment variable.
+ - `NIX_PATH` is overridden by [specifying the setting as the command line flag](@docroot@/command-ref/conf-file.md#command-line-flags) `--nix-path`.
+ - Any current value is extended by the [`-I` option](@docroot@/command-ref/opt-common.md#opt-I) or `--extra-nix-path`.
- ```
- $HOME/.nix-defexpr/channels
- nixpkgs=$NIX_STATE_DIR/profiles/per-user/root/channels/nixpkgs
- $NIX_STATE_DIR/profiles/per-user/root/channels
- ```
+ If the respective paths are accessible, the default values are:
- It can be overridden with the [`NIX_PATH` environment variable](@docroot@/command-ref/env-common.md#env-NIX_PATH) or the [`-I` command line option](@docroot@/command-ref/opt-common.md#opt-I).
+ - `$HOME/.nix-defexpr/channels`
+ - `nixpkgs=$NIX_STATE_DIR/profiles/per-user/root/channels/nixpkgs`
+ - `$NIX_STATE_DIR/profiles/per-user/root/channels`
+
+ See [`NIX_STATE_DIR`](@docroot@/command-ref/env-common.md#env-NIX_STATE_DIR) for details.
> **Note**
>
- > If [pure evaluation](#conf-pure-eval) is enabled, `nixPath` evaluates to the empty list `[ ]`.
+ > If [restricted evaluation](@docroot@/command-ref/conf-file.md#conf-restrict-eval) is enabled, the default value is empty.
+ >
+ > If [pure evaluation](#conf-pure-eval) is enabled, `builtins.nixPath` *always* evaluates to the empty list `[ ]`.
)", {}, false};
Setting currentSystem{
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index 0b3b19b57..7ceb84f0e 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -1843,34 +1843,6 @@ static RegisterPrimOp primop_findFile(PrimOp {
.doc = R"(
Find *lookup-path* in *search-path*.
- A search path is represented list of [attribute sets](./types.md#attribute-set) with two attributes:
- - `prefix` is a relative path.
- - `path` denotes a file system location
- The exact syntax depends on the command line interface.
-
- Examples of search path attribute sets:
-
- - ```
- {
- prefix = "nixos-config";
- path = "/etc/nixos/configuration.nix";
- }
- ```
-
- - ```
- {
- prefix = "";
- path = "/nix/var/nix/profiles/per-user/root/channels";
- }
- ```
-
- The lookup algorithm checks each entry until a match is found, returning a [path value](@docroot@/language/types.md#type-path) of the match:
-
- - If *lookup-path* matches `prefix`, then the remainder of *lookup-path* (the "suffix") is searched for within the directory denoted by `path`.
- Note that the `path` may need to be downloaded at this point to look inside.
- - If the suffix is found inside that directory, then the entry is a match.
- The combined absolute path of the directory (now downloaded if need be) and the suffix is returned.
-
[Lookup path](@docroot@/language/constructs/lookup-path.md) expressions are [desugared](https://en.wikipedia.org/wiki/Syntactic_sugar) using this and [`builtins.nixPath`](#builtins-nixPath):
```nix
@@ -1882,6 +1854,119 @@ static RegisterPrimOp primop_findFile(PrimOp {
```nix
builtins.findFile builtins.nixPath "nixpkgs"
```
+
+ A search path is represented as a list of [attribute sets](./types.md#attribute-set) with two attributes:
+ - `prefix` is a relative path.
+ - `path` denotes a file system location
+
+ Examples of search path attribute sets:
+
+ - ```
+ {
+ prefix = "";
+ path = "/nix/var/nix/profiles/per-user/root/channels";
+ }
+ ```
+ - ```
+ {
+ prefix = "nixos-config";
+ path = "/etc/nixos/configuration.nix";
+ }
+ ```
+ - ```
+ {
+ prefix = "nixpkgs";
+ path = "https://github.com/NixOS/nixpkgs/tarballs/master";
+ }
+ ```
+ - ```
+ {
+ prefix = "nixpkgs";
+ path = "channel:nixpkgs-unstable";
+ }
+ ```
+ - ```
+ {
+ prefix = "flake-compat";
+ path = "flake:github:edolstra/flake-compat";
+ }
+ ```
+
+ The lookup algorithm checks each entry until a match is found, returning a [path value](@docroot@/language/types.md#type-path) of the match:
+
+ - If a prefix of `lookup-path` matches `prefix`, then the remainder of *lookup-path* (the "suffix") is searched for within the directory denoted by `path`.
+ The contents of `path` may need to be downloaded at this point to look inside.
+
+ - If the suffix is found inside that directory, then the entry is a match.
+ The combined absolute path of the directory (now downloaded if need be) and the suffix is returned.
+
+ > **Example**
+ >
+ > A *search-path* value
+ >
+ > ```
+ > [
+ > {
+ > prefix = "";
+ > path = "/home/eelco/Dev";
+ > }
+ > {
+ > prefix = "nixos-config";
+ > path = "/etc/nixos";
+ > }
+ > ]
+ > ```
+ >
+ > and a *lookup-path* value `"nixos-config"` will cause Nix to try `/home/eelco/Dev/nixos-config` and `/etc/nixos` in that order and return the first path that exists.
+
+ If `path` starts with `http://` or `https://`, it is interpreted as the URL of a tarball that will be downloaded and unpacked to a temporary location.
+ The tarball must consist of a single top-level directory.
+
+ The URLs of the tarballs from the official `nixos.org` channels can be abbreviated as `channel:`.
+ See [documentation on `nix-channel`](@docroot@/command-ref/nix-channel.md) for details about channels.
+
+ > **Example**
+ >
+ > These two search path entries are equivalent:
+ >
+ > - ```
+ > {
+ > prefix = "nixpkgs";
+ > path = "channel:nixpkgs-unstable";
+ > }
+ > ```
+ > - ```
+ > {
+ > prefix = "nixpkgs";
+ > path = "https://nixos.org/channels/nixos-unstable/nixexprs.tar.xz";
+ > }
+ > ```
+
+ Search paths can also point to source trees using [flake URLs](@docroot@/command-ref/new-cli/nix3-flake.md#url-like-syntax).
+
+
+ > **Example**
+ >
+ > The search path entry
+ >
+ > ```
+ > {
+ > prefix = "nixpkgs";
+ > path = "flake:nixpkgs";
+ > }
+ > ```
+ > specifies that the prefix `nixpkgs` shall refer to the source tree downloaded from the `nixpkgs` entry in the flake registry.
+ >
+ > Similarly
+ >
+ > ```
+ > {
+ > prefix = "nixpkgs";
+ > path = "flake:github:nixos/nixpkgs/nixos-22.05";
+ > }
+ > ```
+ >
+ > makes `` refer to a particular branch of the `NixOS/nixpkgs` repository on GitHub.
)",
.fun = prim_findFile,
});
@@ -4731,6 +4816,13 @@ void EvalState::createBaseEnv()
.doc = R"(
The value of the [`nix-path` configuration setting](@docroot@/command-ref/conf-file.md#conf-nix-path): a list of search path entries used to resolve [lookup paths](@docroot@/language/constructs/lookup-path.md).
+ > **Example**
+ >
+ > ```bash
+ > $ NIX_PATH= nix-instantiate --eval --expr "builtins.nixPath" -I foo=bar --no-pure-eval
+ > [ { path = "bar"; prefix = "foo"; } ]
+ > ```
+
Lookup path expressions are [desugared](https://en.wikipedia.org/wiki/Syntactic_sugar) using this and
[`builtins.findFile`](./builtins.html#builtins-findFile):
diff --git a/tests/functional/nix_path.sh b/tests/functional/nix_path.sh
index 7e6a0458d..90cba1f0c 100755
--- a/tests/functional/nix_path.sh
+++ b/tests/functional/nix_path.sh
@@ -22,13 +22,13 @@ nix-instantiate --eval -E '' --restrict-eval
#
# | precedence | hard-coded | nix-path in file | extra-nix-path in file | nix-path in env | extra-nix-path in env | NIX_PATH | nix-path | extra-nix-path | -I |
# |------------------------|------------|------------------|------------------------|-----------------|-----------------------|-----------|-----------|-----------------|-----------------|
-# | hard-coded | x | ^override | ^append | ^override | ^append | ^override | ^override | ^append | ^append |
-# | nix-path in file | | last wins | ^append | ^override | ^append | ^override | ^override | ^append | ^append |
-# | extra-nix-path in file | | | append in order | ^override | ^append | ^override | ^override | ^append | ^append |
-# | nix-path in env | | | | last wins | ^append | ^override | ^override | ^append | ^append |
-# | extra-nix-path in env | | | | | append in order | ^override | ^override | ^append | ^append |
-# | NIX_PATH | | | | | | x | ^override | ^append | ^append |
-# | nix-path | | | | | | | last wins | ^append | ^append |
+# | hard-coded | x | ^override | ^append | ^override | ^append | ^override | ^override | ^append | ^prepend |
+# | nix-path in file | | last wins | ^append | ^override | ^append | ^override | ^override | ^append | ^prepend |
+# | extra-nix-path in file | | | append in order | ^override | ^append | ^override | ^override | ^append | ^prepend |
+# | nix-path in env | | | | last wins | ^append | ^override | ^override | ^append | ^prepend |
+# | extra-nix-path in env | | | | | append in order | ^override | ^override | ^append | ^prepend |
+# | NIX_PATH | | | | | | x | ^override | ^append | ^prepend |
+# | nix-path | | | | | | | last wins | ^append | ^prepend |
# | extra-nix-path | | | | | | | | append in order | append in order |
# | -I | | | | | | | | | append in order |
@@ -59,6 +59,8 @@ echo "nix-path = test=$TEST_ROOT/from-nix-path-file" >> "$test_nix_conf"
# -I extends NIX_PATH
[[ $(NIX_PATH=test=$TEST_ROOT/from-NIX_PATH nix-instantiate -I test=$TEST_ROOT/from-I --find-file test/only-from-I.nix) = $TEST_ROOT/from-I/only-from-I.nix ]]
+# -I takes precedence over NIX_PATH
+[[ $(NIX_PATH=test=$TEST_ROOT/from-NIX_PATH nix-instantiate -I test=$TEST_ROOT/from-I --find-file test) = $TEST_ROOT/from-I ]]
# if -I does not have the desired entry, the value from NIX_PATH is used
[[ $(NIX_PATH=test=$TEST_ROOT/from-NIX_PATH nix-instantiate -I test=$TEST_ROOT/from-I --find-file test/only-from-NIX_PATH.nix) = $TEST_ROOT/from-NIX_PATH/only-from-NIX_PATH.nix ]]