nix-direnv
direnv
的use_nix
和use_flake
的一个更快、持久化的实现,用于替代内置版本。
主要特点:
- 通过缓存
nix-shell
环境,在首次运行后显著提高速度 - 通过在用户的
gcroots
中创建结果shell派生的符号链接,防止构建依赖被垃圾回收(生命太短暂了,不能在没有网络连接的飞机上丢失项目的构建缓存)
为什么不使用lorri
?
与lorri相比,nix-direnv更简单(不需要外部守护进程)并且支持flakes。此外,lorri有时会在每次更改时重新评估整个nixpkgs(导致持续高CPU负载)。
安装
注意:nix-direnv需要现代版本的Bash。macOS自带的是2007年的bash 3.2版本。作为解决方案,我们建议macOS用户通过Nix或Homebrew安装
direnv
。安装nix-direnv有多种方式,选择你喜欢的方式:
通过home-manager(推荐)
通过home-manager
请注意,虽然推荐使用home-manager集成,但某些用例可能需要只在特定版本的nix-direnv中存在的功能。使用这种方法很难控制安装的nix-direnv版本。如果你需要这种特定控制,请使用其他安装nix-direnv的方法。
在$HOME/.config/home-manager/home.nix
中添加
{
# ...其他配置...
programs = {
direnv = {
enable = true;
enableBashIntegration = true; # 关于其他shell的注意事项见下文
nix-direnv.enable = true;
};
bash.enable = true; # 关于其他shell的注意事项见下文
};
}
查看当前的Home Manager选项以了解与Bash以外的shell的集成。确保也让home-manager
管理你的shell,设置programs.<你的shell>.enable = true
。
Direnv的source_url
Direnv source_url
在你的.envrc
中添加以下行:
if ! has nix_direnv_version || ! nix_direnv_version 3.0.5; then
source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.5/direnvrc" "sha256-RuwIS+QKFj/T9M2TFXScjBsLR6V3A17YVoEW/Q6AZ1w="
fi
通过NixOS的系统配置
通过NixOS的系统配置
对于NixOS 23.05+,只需要
{
programs.direnv.enable = true;
}
其他可用选项有:
{ pkgs, ... }: {
#设置为默认值
programs.direnv = {
package = pkgs.direnv;
silent = false;
loadInNixShell = true;
direnvrcExtra = "";
nix-direnv = {
enable = true;
package = pkgs.nix-direnv;
};
}
使用`nix profile`
使用nix profile
以非root用户执行以下操作:
nix profile install nixpkgs#nix-direnv
然后将nix-direnv添加到$HOME/.config/direnv/direnvrc
:
source $HOME/.nix-profile/share/nix-direnv/direnvrc
从源码安装
从源码安装
将仓库克隆到某个目录,然后在你自己的~/.config/direnv/direnvrc
中引用这个仓库中的direnvrc:
# 将此添加到 ~/.config/direnv/direnvrc
source $HOME/nix-direnv/direnvrc
使用示例
在项目目录中添加shell.nix
或default.nix
:
# 将此保存为shell.nix
{ pkgs ? import <nixpkgs> {}}:
pkgs.mkShell {
packages = [ pkgs.hello ];
}
然后在你的envrc中添加use nix
行:
$ echo "use nix" >> .envrc
$ direnv allow
如果你以前没有使用过direnv,请确保先将其挂钩到你的shell。
使用非标准文件名
你可以在.envrc
中传递文件名,使用不同于shell.nix
或default.nix
的文件名,例如:
$ echo "use nix foo.nix" >> .envrc
Flakes支持
nix-direnv还提供了另一种use_flake
实现。代码已经过测试并且可以正常工作,但上游flake API尚未最终确定,所以我们无法保证在nix升级后的稳定性。
与use_nix
类似,我们的use_flake
将防止下载的包被垃圾回收,包括flake输入。
创建新的原生flake项目
这个仓库附带了一个flake模板,它提供了一个带有devShell集成和基本.envrc
的基础flake。
要使用此模板,你可以执行以下命令:
$ nix flake new -t github:nix-community/nix-direnv <desired output path>
与现有flake集成
$ echo "use flake" >> .envrc && direnv allow
use flake
行还可以接受一个额外的任意flake参数,因此你可以如下指向外部flakes:
use flake ~/myflakes#project
高级用法
use flake
在底层,use_flake
调用nix print-dev-env
。use_flake
函数的第一个参数是要使用的flake表达式,其他所有参数都会传递给print-dev-env
调用。你可以利用这一点进行一些更复杂的调用。
例如,如果你有一个在某些条件下需要不纯调用的flake,你可能希望向print-dev-env
调用传递--impure
参数,以便传入调用shell的环境。
你可以这样做:
$ echo "use flake . --impure" > .envrc
$ direnv allow
use nix
与use flake
类似,use nix
现在也使用nix print-dev-env
。由于历史原因,参数解析模仿了nix shell
。
这导致了我们在解析方面的一些限制。
目前,所有单词参数和一些众所周知的双参数将被解释或传递。
手动重新加载nix环境
为了避免在意外时间延迟和耗时重建,你可以在"手动重新加载"模式下使用nix-direnv。nix-direnv会在nix环境不再是最新时通知你。然后你可以自己决定何时重新加载nix环境。
要激活手动模式,在你的.envrc
中使用nix_direnv_manual_reload
,如下所示:
nix_direnv_manual_reload
use nix # 或 use flake
要重新加载你的nix环境,使用nix-direnv-reload
命令:
$ nix-direnv-reload
已知参数
-p
:开始要安装的包列表;消耗所有剩余参数--include
/-I
:将以下路径添加到<...>
文件名的查找位置列表中--attr
/-A
:指定要使用的输出属性
--command
、--run
、--exclude
、--pure
、-i
和--keep
被明确忽略。
所有单词参数(如-j4
、--impure
等)都会传递给底层的nix调用。
跟踪的文件
为了方便,nix-direnv
自动将常见文件添加到direnv的监视文件列表中。
额外跟踪的文件列表如下:
-
对于
use nix
:~/.direnvrc
~/.config/direnv/direnvrc
.envrc
- 单个nix文件。按优先顺序:
- 传递给
use nix
的文件参数 - 如果存在,则为
default.nix
- 如果存在,则为
shell.nix
- 传递给
-
对于
use flake
:~/.direnvrc
~/.config/direnv/direnvrc
.envrc
flake.nix
flake.lock
- 如果存在,则为
devshell.toml
用户可以自由使用direnv的内置watch_file
函数来跟踪其他文件。watch_file
必须在use flake
或use nix
之前调用才能生效。
环境变量
nix-direnv设置以下环境变量供用户使用。所有其他环境变量要么是底层nix调用的产物,要么纯粹是偶然的,不应依赖。
NIX_DIRENV_DID_FALLBACK
:当你的nix shell或flake的devShell的当前版本无效,并且nix-direnv已加载最后一个已知的工作shell时设置。
一般direnv提示
- 更改direnv存储缓存的位置
- 在新的nix项目中快速设置direnv
- 禁用差异通知(需要direnv 2.34+):注意,这需要放入direnv的TOML配置中!