nix-direnv/README.md

331 lines
8.8 KiB
Markdown
Raw Normal View History

2019-09-27 10:43:48 +03:00
# nix-direnv
2019-09-27 11:03:55 +03:00
2020-04-01 18:17:18 +03:00
![Test](https://github.com/nix-community/nix-direnv/workflows/Test/badge.svg)
2023-11-29 09:13:20 +03:00
A faster, persistent implementation of `direnv`'s `use_nix` and `use_flake`, to
replace the built-in one.
2019-09-27 11:03:55 +03:00
Prominent features:
2023-11-29 09:13:20 +03:00
- significantly faster after the first run by caching the `nix-shell`
environment
2019-09-27 11:03:55 +03:00
- prevents garbage collection of build dependencies by symlinking the resulting
2023-11-29 09:13:20 +03:00
shell derivation in the user's `gcroots` (Life is too short to lose your
project's build cache if you are on a flight with no internet connection)
2019-09-27 11:03:55 +03:00
## Why not use `lorri` instead?
2023-11-29 09:13:20 +03:00
Compared to [lorri](https://github.com/nix-community/lorri), nix-direnv is
simpler (and requires no external daemon) and supports flakes. Additionally,
lorri can sometimes re-evaluate the entirety of nixpkgs on every change (leading
to perpetual high CPU load).
## Installation
2019-09-27 11:03:55 +03:00
> **Heads up**: nix-direnv requires a modern Bash. MacOS ships with bash 3.2
> from 2007. As a work-around we suggest that macOS users install `direnv` via
> Nix or Homebrew. There are different ways to install nix-direnv, pick your
> favourite:
2020-05-11 11:20:15 +03:00
<details>
<summary> Via home-manager (Recommended)</summary>
### Via home-manager
2020-05-11 11:20:15 +03:00
2023-11-29 09:13:20 +03:00
Note that while the home-manager integration is recommended, some use cases
require the use of features only present in some versions of nix-direnv. It is
2023-12-14 18:08:16 +03:00
much harder to control the version of nix-direnv installed with this method. If
2023-11-29 09:13:20 +03:00
you require such specific control, please use another method of installing
nix-direnv.
2020-05-11 11:20:15 +03:00
In `$HOME/.config/nixpkgs/home.nix` add
```Nix
{
# ...other config, other config...
2020-05-11 11:20:15 +03:00
2023-07-14 05:07:18 +03:00
programs = {
direnv = {
enable = true;
enableBashIntegration = true; # see note on other shells below
nix-direnv.enable = true;
};
2020-05-11 11:20:15 +03:00
bash.enable = true; # see note on other shells below
2023-07-14 05:07:18 +03:00
};
2020-05-11 11:20:15 +03:00
}
2019-09-27 11:03:55 +03:00
```
2023-11-29 09:13:20 +03:00
Check the current
[Home Manager Options](https://mipmip.github.io/home-manager-option-search/?query=direnv)
for integration with shells other than Bash. Be sure to also allow
`home-manager` to manage your shell with `programs.<your_shell>.enable = true`.
2020-03-11 13:30:45 +03:00
</details>
<details>
<summary>Direnv's source_url</summary>
2023-11-29 09:13:20 +03:00
### Direnv source_url
Put the following lines in your `.envrc`:
```bash
2024-01-03 00:46:30 +03:00
if ! has nix_direnv_version || ! nix_direnv_version 3.0.4; then
2024-01-03 00:46:50 +03:00
source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.4/direnvrc" "sha256-DzlYZ33mWF/Gs8DDeyjr8mnVmQGx7ASYqA5WlxwvBG4="
fi
```
</details>
<details>
2023-07-14 05:07:18 +03:00
<summary>Via system configuration on NixOS</summary>
### Via system configuration on NixOS
2023-11-29 09:13:20 +03:00
For NixOS 23.05+ all that's required is
2023-11-29 09:13:20 +03:00
```Nix
2023-07-14 05:07:18 +03:00
{
programs.direnv.enable = true;
}
```
other available options are:
```Nix
2023-07-14 05:07:18 +03:00
{ pkgs, ... }: {
#set to default values
programs.direnv = {
package = pkgs.direnv;
silent = false;
loadInNixShell = true;
direnvrcExtra = "";
nix-direnv = {
enable = true;
package = pkgs.nix-direnv;
};
}
```
2023-11-29 09:13:20 +03:00
</details>
2023-11-29 09:13:20 +03:00
<details>
2023-01-31 03:58:41 +03:00
<summary>With `nix profile`</summary>
### With `nix profile`
As **non-root** user do the following:
```shell
nix profile install nixpkgs#nix-direnv
```
Then add nix-direnv to `$HOME/.config/direnv/direnvrc`:
2023-01-31 03:58:41 +03:00
```bash
source $HOME/.nix-profile/share/nix-direnv/direnvrc
```
</details>
<details>
<summary>From source</summary>
### From source
2020-05-11 11:20:15 +03:00
2023-11-29 09:13:20 +03:00
Clone the repository to some directory and then source the direnvrc from this
repository in your own `~/.config/direnv/direnvrc`:
2020-05-11 11:20:15 +03:00
```bash
# put this in ~/.config/direnv/direnvrc
2020-05-11 11:20:15 +03:00
source $HOME/nix-direnv/direnvrc
```
</details>
2020-12-31 09:54:49 +03:00
2020-08-10 11:56:24 +03:00
## Usage example
2022-06-21 16:10:49 +03:00
Either add `shell.nix` or a `default.nix` to the project directory:
2020-08-10 11:56:24 +03:00
2023-11-29 09:13:20 +03:00
```nix
2020-08-10 11:56:24 +03:00
# save this as shell.nix
2020-10-25 23:08:08 +03:00
{ pkgs ? import <nixpkgs> {}}:
2020-08-10 11:56:24 +03:00
pkgs.mkShell {
2023-01-12 22:10:51 +03:00
packages = [ pkgs.hello ];
2020-08-10 11:56:24 +03:00
}
```
Then add the line `use nix` to your envrc:
2020-08-10 11:56:24 +03:00
```console
$ echo "use nix" >> .envrc
$ direnv allow
```
2023-11-29 09:13:20 +03:00
If you haven't used direnv before, make sure to
[hook it into your shell](https://direnv.net/docs/hook.html) first.
2021-04-17 15:24:10 +03:00
2021-10-19 14:47:02 +03:00
### Using a non-standard file name
2023-11-29 09:13:20 +03:00
You may use a different file name than `shell.nix` or `default.nix` by passing
the file name in `.envrc`, e.g.:
2021-10-19 14:47:02 +03:00
```console
$ echo "use nix foo.nix" >> .envrc
```
2020-12-25 19:29:44 +03:00
## Flakes support
2020-08-10 11:56:24 +03:00
2023-11-29 09:13:20 +03:00
nix-direnv also comes with an alternative `use_flake` implementation. The code
2023-12-14 18:08:16 +03:00
is tested and does work but the upstream flake api is not finalized, so we
2023-11-29 09:13:20 +03:00
cannot guarantee stability after a nix upgrade.
2020-08-10 11:56:24 +03:00
2023-11-29 09:13:20 +03:00
Like `use_nix`, our `use_flake` will prevent garbage collection of downloaded
packages, including flake inputs.
2020-08-11 09:08:36 +03:00
### Creating a new flake-native project
2023-11-29 09:13:20 +03:00
This repository ships with a
[flake template](https://github.com/nix-community/nix-direnv/tree/master/templates/flake).
which provides a basic flake with devShell integration and a basic `.envrc`.
To make use of this template, you may issue the following command:
```console
$ nix flake new -t github:nix-community/nix-direnv <desired output path>
```
### Integrating with a existing flake
```console
$ echo "use flake" >> .envrc && direnv allow
2020-08-11 09:08:36 +03:00
```
2023-11-29 09:13:20 +03:00
The `use flake` line also takes an additional arbitrary flake parameter, so you
can point at external flakes as follows:
```bash
use flake ~/myflakes#project
```
### Advanced usage
#### use flake
2023-11-29 09:13:20 +03:00
Under the covers, `use_flake` calls `nix print-dev-env`. The first argument to
the `use_flake` function is the flake expression to use, and all other arguments
are proxied along to the call to `print-dev-env`. You may make use of this fact
for some more arcane invocations.
2023-11-29 09:13:20 +03:00
For instance, if you have a flake that needs to be called impurely under some
conditions, you may wish to pass `--impure` to the `print-dev-env` invocation so
that the environment of the calling shell is passed in.
You can do that as follows:
```console
$ echo "use flake . --impure" > .envrc
$ direnv allow
```
#### use nix
2023-11-29 09:13:20 +03:00
Like `use flake`, `use nix` now uses `nix print-dev-env`. Due to historical
reasons, the argument parsing emulates `nix shell`.
This leads to some limitations in what we can reasonably parse.
2023-11-29 09:13:20 +03:00
Currently, all single-word arguments and some well-known double arguments will
2023-12-14 18:08:16 +03:00
be interpreted or passed along.
#### Manual reload of the nix environment
To avoid delays and time consuming rebuilds at unexpected times, you can use
nix-direnv in the "manual reload" mode. nix-direnv will then tell you when the
nix environment is no longer up to date. You can then decide yourself when you
want to reload the nix environment.
2023-11-29 09:13:20 +03:00
To activate manual mode, use `nix_direnv_manual_reload` in your `.envrc` like
this:
```shell
nix_direnv_manual_reload
use nix # or use flake
```
To reload your nix environment, use the `nix-direnv-reload` command:
```console
$ nix-direnv-reload
```
##### Known arguments
- `-p`: Starts a list of packages to install; consumes all remaining arguments
2023-11-29 09:13:20 +03:00
- `--include` / `-I`: Add the following path to the list of lookup locations for
`<...>` file names
- `--attr` / `-A`: Specify the output attribute to utilize
2023-11-29 09:13:20 +03:00
`--command`, `--run`, `--exclude`, `--pure`, `-i`, and `--keep` are explicitly
ignored.
2020-03-11 13:30:45 +03:00
2023-11-29 09:13:20 +03:00
All single word arguments (`-j4`, `--impure` etc) are passed to the underlying
nix invocation.
2020-04-09 08:32:05 +03:00
#### Tracked files
2024-04-22 15:16:55 +03:00
As a convenience, `nix-direnv` adds common files to direnv's watched file list
automatically.
2024-04-22 15:16:55 +03:00
The list of additionally tracked files is as follows:
2023-11-29 09:13:20 +03:00
2024-04-22 15:16:55 +03:00
- for `use nix`:
2023-11-29 09:13:20 +03:00
- `~/.direnvrc`
- `~/.config/direnv/direnvrc`
- `.envrc`,
- A single nix file. In order of preference:
- The file argument to `use nix`
- `default.nix` if it exists
2024-04-22 15:16:55 +03:00
- `shell.nix` if it exists
2022-06-05 13:30:10 +03:00
2024-04-22 15:16:55 +03:00
- for `use flake`:
2023-11-29 09:13:20 +03:00
- `~/.direnvrc`
- `~/.config/direnv/direnvrc`
- `.envrc`
- `flake.nix`
- `flake.lock`
- `devshell.toml` if it exists
2024-04-22 15:16:55 +03:00
Users are free to use direnv's builtin `watch_file` function to track additional
files. `watch_file` must be invoked before either `use flake` or `use nix` to
take effect.
2024-04-22 15:16:55 +03:00
#### Environment Variables
2022-06-05 13:30:10 +03:00
2024-04-22 15:16:55 +03:00
nix-direnv sets the following environment variables for user consumption. All
other environment variables are either a product of the underlying nix
invocation or are purely incidental and should not be relied upon.
2022-06-05 13:30:10 +03:00
2024-04-22 15:16:55 +03:00
- `NIX_DIRENV_DID_FALLBACK`: Set when the current revision of your nix shell or
flake's devShell are invalid and nix-direnv has loaded the last known working
shell.
2022-06-05 13:30:10 +03:00
## General direnv tips
2020-04-09 08:32:05 +03:00
2024-04-22 15:16:55 +03:00
- [Changing where direnv stores its cache][cache_location]
- [Quickly setting up direnv in a new nix project][new_project]
- [Disable the diff notice (requires direnv 2.34+)][hide_diff_notice]: Note that
this goes into direnv's TOML configuration!
[cache_location]: https://github.com/direnv/direnv/wiki/Customizing-cache-location
[new_project]: https://github.com/nix-community/nix-direnv/wiki/Shell-integration
[hide_diff_notice]: https://direnv.net/man/direnv.toml.1.html#codehideenvdiffcode
## Other projects in the field
2021-08-30 02:14:51 +03:00
- [lorri](https://github.com/nix-community/lorri)
- [sorri](https://github.com/nmattia/sorri)
- [nixify](https://github.com/kalbasit/nur-packages/blob/master/pkgs/nixify/envrc)
- [lorelei](https://github.com/shajra/direnv-nix-lorelei)