docs: document the cursed file syntax for new CLI

This documents that all installables in the nix3 commands, in their
--file/-f form accept an extended syntax for the file argument,
which is the same as it is for nix-build and friends, some of which were
well known in their nix-build forms (e.g. `nix-build '<nixpkgs>' -A hello)
but are not well known in their nix3 forms (people rarely know that you
can `nix build -f '<nixpkgs>' firefox`).

Like the old CLI syntax, as documented in [1], file arguments also
accept https:// tarball URLs, `flake:` prefixed flakerefs, and the
cursed `channel:` prefixed hardened URLs.

[1]: Ib6d68594a16132805ba5d97526e16f7b3633117e

Change-Id: Ib81a5db1f60d5916f0f792d82054f3ac65717121
This commit is contained in:
Qyriad 2024-05-22 22:31:19 -06:00
parent 48d419feb8
commit 6c8685dd22
2 changed files with 44 additions and 1 deletions

View file

@ -4,6 +4,7 @@
this also links to nix-build.md for the full explanation.
This include file is manually duplicated in nix-env/opt-common.md because list indentation sadness.
It is also manually duplicated in src/nix/nix.md, because those files don't support include?? busted.
-->
- A normal filesystem path, like `/home/meow/nixfiles/default.nix`
- Including a directory, like `/home/meow/nixfiles`, equivalent to above

View file

@ -158,16 +158,58 @@ Example: `/nix/store/p7gp6lxdg32h4ka1q398wd9r2zkbbz2v-hello-2.10.drv^*`
Example: `--file /path/to/nixpkgs hello`
When the option `-f` / `--file` *path* \[*attrpath*...\] is given, installables are interpreted as the value of the expression in the Nix file at *path*.
When the option `-f` / `--file` *fileish* \[*attrpath*...\] is given, installables are interpreted as the value of the Nix file specified by *fileish*.
If attribute paths are provided, commands will operate on the corresponding values accessible at these paths.
The Nix expression in that file, or any selected attribute, must evaluate to a derivation.
The *fileish* itself may take one of a few different forms, the first being a simple filesystem path, e.g. `nix build /tmp/some-file.nix`.
Like the [import builtin](../../language/builtins.md#builtins-import), specifying a directory is equivalent to specify `default.nix` within that directory.
It may also be a [search path](../env-common.md#env-NIX_PATH) (also known as a lookup path), like `<nixpkgs>`.
Unlike using `<nixpkgs>` in a `--expr` argument, this does not require `--impure`.
To emulate the `nix-build '<nixpkgs>' -A hello` pattern, use:
```console
$ nix build -f '<nixpkgs>' hello
```
If a *fileish* starts with `http://` or `https://`, it is interpreted as the URL of a tarball which will be fetched and unpacked.
Lix will then `import` the unpacked directory, so these tarballs must include at least a single top-level directory with a file called `default.nix`.
For example, you could build from a specific version of Nixpkgs with something like:
```console
$ nix build "https://github.com/NixOS/nixpkgs/archive/refs/heads/release-23.11.tar.gz" firefox
```
If a *fileish* starts with `flake:`, the rest of the argument is interpreted as a [flakeref](./nix3-flake.md#flake-reference) (see `nix flake --help` or `man nix3-flake`), which requires the "flakes" experimental feature to be enabled.
This is is *not quite* the same as specifying a [flake output attrpath](#flake-output-attribute).
It does *not* access the flake directly, but instead fetches it and `import`s the unpacked directory.
In other words, it assumes that the flake has a `default.nix` file, and then interprets the attribute path relative to what `default.nix` evaluates to.
For many flakes — including Nixpkgs — this will end up evaluating to the same thing.
These two commands build the same derivation, but one from the flake, and the other from `default.nix`:
```console
$ nix build 'nixpkgs#firefox' # from flake.nix
$ nix build flake:nixpkgs firefox # from default.nix in the flake directory
```
Finally, for legacy reasons, if a *fileish* starts with `channel:`, the rest of the argument is interpreted as the name of a channel to fetch from `https://nixos.org/channels/$CHANNEL_NAME/nixexprs.tar.gz`.
This is a **hard coded URL** pattern and is *not* related to the subscribed channels managed by the [nix-channel](../nix-channel.md) command.
> **Note**: any of the special syntaxes may always be disambiguated by prefixing the path.
> For example: a file in the current directory literally called `<nixpkgs>` can be addressed as `./<nixpkgs>`, to escape the special interpretation.
In summary, a file path argument may be one of:
- A normal filesystem path, like `/home/meow/nixfiles/default.nix`
- Including a directory, like `/home/meow/nixfiles`, equivalent to above
- A single lookup path, like `<nixpkgs>` or `<nixos>`
- A URL to a tarball, like `https://github.com/NixOS/nixpkgs/archive/refs/heads/release-23.11.tar.gz`
- A flakeref, introduced by the prefix `flake:`, like `flake:git+https://git.lix.systems/lix-project/lix`
- A channel name, introduced by the prefix `channel:`, like `channel:nixpkgs-unstable`.
- This uses a hard-coded URL pattern and is *not* related to the subscribed channels managed by the [nix-channel](@docroot@/command-ref/nix-channel.md) command.
### Nix expression
Example: `--expr 'import <nixpkgs> {}' hello`