Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reword documentation on nix-path config option #7772

Merged
merged 2 commits into from
Jul 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 15 additions & 11 deletions doc/manual/src/command-ref/env-common.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,26 @@ Most Nix commands interpret the following environment variables:

- <span id="env-NIX_PATH">[`NIX_PATH`](#env-NIX_PATH)</span>

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., `<path>`),
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 `<nixpkgs>` will produce:

error: file 'nixpkgs' was not found in the Nix search path
> **Example**
>
> ```bash
> $ NIX_PATH= nix-instantiate --eval '<nixpkgs>'
> error: file 'nixpkgs' was not found in the Nix search path (add it using $NIX_PATH or -I)
> ```

- <span id="env-NIX_IGNORE_SYMLINK_STORE">[`NIX_IGNORE_SYMLINK_STORE`](#env-NIX_IGNORE_SYMLINK_STORE)</span>

Expand Down
9 changes: 5 additions & 4 deletions doc/manual/src/command-ref/opt-common.md
Original file line number Diff line number Diff line change
Expand Up @@ -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”
Expand Down Expand Up @@ -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.

- <span id="opt-I">[`-I`](#opt-I)</span> *path*
- <span id="opt-I">[`-I` / `--include`](#opt-I)</span> *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).

- <span id="opt-option">[`--option`](#opt-option)</span> *name* *value*

Expand Down
70 changes: 3 additions & 67 deletions src/libcmd/common-eval-args.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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., `<nixpkgs>`).
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 `<nixpkgs/path>` 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:<channel-name>`. 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 `<nixpkgs>` 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"},
Expand Down
21 changes: 13 additions & 8 deletions src/libexpr/eval-settings.hh
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::string> currentSystem{
Expand Down
122 changes: 107 additions & 15 deletions src/libexpr/primops.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1843,45 +1843,130 @@ 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:
[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
<nixpkgs>
```

is equivalent to:

```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
The exact syntax depends on the command line interface.

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 = "";
path = "/nix/var/nix/profiles/per-user/root/channels";
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 *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 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.

[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):
> **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.

```nix
<nixpkgs>
```
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.

is equivalent to:
The URLs of the tarballs from the official `nixos.org` channels can be abbreviated as `channel:<channel-name>`.
See [documentation on `nix-channel`](@docroot@/command-ref/nix-channel.md) for details about channels.

```nix
builtins.findFile builtins.nixPath "nixpkgs"
```
> **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 `<nixpkgs>` refer to a particular branch of the `NixOS/nixpkgs` repository on GitHub.
)",
.fun = prim_findFile,
});
Expand Down Expand Up @@ -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):

Expand Down
16 changes: 9 additions & 7 deletions tests/functional/nix_path.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ nix-instantiate --eval -E '<by-relative-path/simple.nix>' --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 |

Expand Down Expand Up @@ -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 ]]

Expand Down
Loading