mcpField
N
nix-setup

nix-setup

github.com/mizchi开发41659 次安装1 周前更新
代码仓库

关于 nix-setup

为开发者提供可复现 Nix 开发环境的设置指南,涵盖 devbox 与纯 flake 两种路径。附带多语言模板及容器环境安装说明,帮助按项目需求选择配置方式。

主要功能

  1. 01devbox 与 flake 选型指导
  2. 02多语言 flake 模板
  3. 03沙盒环境 Nix 安装脚本
  4. 04项目级依赖与环境配置
  5. 05GitHub Actions 配置示例

适用场景

  1. 01为新项目创建可复现开发环境
  2. 02在容器或 Claude Code web 中设置 Nix
  3. 03配置语言工具链与项目依赖
  4. 04通过 GitHub Actions 运行 devbox 任务

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mizchi/skills --skill nix-setup

安装后在 Claude Code 中输入/nix-setup确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

README.md
assets/
apm.nix
setup_nix.sh
assets/devbox/
devbox.json
gh_action_example.yaml
assets/haskell/
.envrc
flake.nix
assets/home-manager/
.gitignore
ccweb.nix
common.nix
flake.nix
macos.nix
assets/moonbit/
.envrc
flake.nix
assets/ocaml/
.envrc
.gitignore
flake.nix
assets/oxcaml/
.envrc
.gitignore
flake.nix
assets/python-uv/
.envrc
flake.nix
assets/rust/
.envrc
flake.nix
assets/typescript/
.envrc
flake.nix
evals/
eval.yaml
ledger.yaml
evals/tasks/
scenario-a-devbox-default.yaml
scenario-b-flake-overlay.yaml

详细介绍

Nix 设置技能

用于设置可复现开发环境的参考。两种方案共用同一个 Nix 后端:

  • devbox — Nix 之上的轻量层;devbox.json 是简洁的 JSON。新项目的默认选择。
  • 纯 flake.nix — 完整的 Nix 表达式能力;assets/ 下提供各语言模板,可直接通过 cp 引导项目。

选择:devbox 还是纯 flake?

devbox 运行于 Nix 之上(内部使用 Nix 存储和 nixpkgs),因此二者之间的选择是用户体验上的选择,而不是技术栈上的选择。mizchi/ 的默认建议:

情况使用
新项目,标准 nixpkgs 包足以满足需求devbox
需要自定义派生、输入覆盖、overlay 或 buildNpmPackageflake.nix
需要将 flake.lock 作为权威的可复现性来源(而不是 devbox.lock)flake.nix
目标是 Claude Code web / 沙盒环境,devbox 安装程序过于臃肿搭配 setup_nix.sh 使用 flake.nix
已有可用的 flake;团队使用 direnvflake.nix

devbox.json 中的包与 nixpkgs 属性路径几乎一一对应,因此之后切换到 flake.nix 很简单。

选择纯 flake.nix 时,请在提案中写明 devbox is rejected 的理由(一行即可)。 例如:“这里选择纯 flake.nix,因为无法在 devbox.json 中表达 rust-overlay 的输入覆盖。” 这样评审者就不必重新推导为何选择更复杂的 flake 方案,也能确保有意识地应用决策表,而不是凭直觉选择。

适用场景

  • “创建 nix 开发 Shell” / “编写 flake.nix” / “设置 devbox”
  • “为新项目添加可复现环境”
  • “让 nix 在 claude code web / 容器中正常运行”
  • 关于 flake.nix / flake.lock / .envrc / devbox.json 的一般问题
  • 排查 nix develop / nix build / devbox shell 问题

assets/ 中的内容

assets/
├── setup_nix.sh              # Installer that sets up single-user Nix with sandbox disabled (for container / CCW)
├── apm.nix                   # Nix derivation for microsoft/apm (Agent Package Manager)
├── moonbit/{flake.nix,.envrc}        # moonbit-overlay + moon
├── rust/{flake.nix,.envrc}           # rust-overlay + stable pinned + cargo-nextest/watch
├── typescript/{flake.nix,.envrc}     # nodejs_24 + pnpm (top-level)
├── python-uv/{flake.nix,.envrc}      # python3 + uv
├── haskell/{flake.nix,.envrc}        # GHC + cabal + HLS + hlint + ormolu
├── ocaml/{flake.nix,.envrc,.gitignore}  # OCaml 5 + dune + merlin + ocaml-lsp + utop
├── oxcaml/{flake.nix,.envrc,.gitignore} # Jane Street OxCaml (opam source build)
└── home-manager/             # multi-host home-manager flake (macos + ccweb)
    ├── flake.nix
    ├── common.nix
    ├── macos.nix             # aarch64-darwin: full desktop
    ├── ccweb.nix             # x86_64-linux: minimal sandbox
    └── .gitignore            # Excludes private.nix / *.secret.nix

每个模板都附带 just、ast-grep 和 apm(通用运维工具)。

模板假定你将 flake.nix 和 apm.nix 并排放在项目根目录。如果要替换语言相关部分,apm.nix 可以直接复用。

apm.nix 是可选的:对于不使用 APM 技能的项目,可以删除它。在这种情况下,从 flake.nix 中移除 apm = import ./apm.nix ... 和 packages 中的 apm 条目。如果只想保留 just / ast-grep,则无需改动。

assets/devbox/ 中包含一个 devbox.json 模板,以及一段用于 devbox 方案的 GitHub Actions 代码片段。

使用 devbox

devbox 基于 Nix 为每个项目提供隔离、可复现的环境,无需编写 Nix 表达式。

安装
curl -fsSL https://get.jetify.com/devbox | bash
基本命令
devbox init                       # creates devbox.json
devbox add nodejs@20              # add packages by name@version
devbox add [email protected] [email protected]
devbox rm nodejs                  # remove
devbox shell                      # enter the env shell
devbox run -- npm test            # run a one-shot command
devbox run test                   # run a named script
devbox services start             # start process-compose services
devbox search nodejs              # search packages

包搜索索引:https://www.nixhub.io。

devbox.json 结构
{
  "$schema": "https://raw.githubusercontent.com/jetify-com/devbox/main/.schema/devbox.schema.json",
  "packages": [
    "nodejs@20",
    "[email protected]",
    "github:NixOS/nixpkgs#hello"
  ],
  "env": {
    "DATABASE_URL": "postgresql://localhost:5432/dev",
    "NODE_ENV": "development"
  },
  "shell": {
    "init_hook": [
      "export API_KEY=$(<.api_key)"
    ],
    "scripts": {
      "test": "npm test",
      "dev": "npm run dev",
      "lint": ["eslint .", "prettier --check ."]
    }
  }
}
服务(process-compose.yaml)
processes:
  web:
    command: npm run dev
  db:
    command: postgres -D /tmp/pgdata
devbox services start | stop | ls
GitHub Actions

使用 jetify-com/devbox-install-action。完整工作流见 assets/devbox/gh_action_example.yaml。

steps:
  - uses: actions/checkout@v7
  - uses: jetify-com/[email protected]
    # with:
    #   enable-cache: true   # caches the Nix store
  - run: devbox run test
常用标志
标志描述
--config <path>非默认 devbox.json 的路径
--quiet禁止输出
--print-env打印此 devbox 将设置的环境
Devbox 参考资料

快速安装

macOS / Linux(推荐)

使用 Determinate Systems 安装程序。默认启用 experimental-features = nix-command flakes,且易于卸载。

curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install
Claude Code web / 其他沙盒环境

对于缺少 systemd、仅有 root 权限或禁止嵌套命名空间的环境,请使用 assets/setup_nix.sh。

  • 单用户模式下设置 build-users-group =(空值)
  • 设置 sandbox = false,这样就不需要 chroot
  • 将 experimental-features = nix-command flakes 写入 /etc/nix/nix.conf 和 $HOME/.config/nix/nix.conf
  • 写入 /etc/profile.d/nix.sh,以确保后续 Shell 中的 PATH 可用
cp ~/.claude/skills/nix-setup/assets/setup_nix.sh .
bash setup_nix.sh
. "$HOME/.nix-profile/etc/profile.d/nix.sh"  # apply to the current shell too
nix --version

最简 flake 骨架

{
  description = "...";

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
    flake-utils.url = "github:numtide/flake-utils";
  };

  outputs = { self, nixpkgs, flake-utils }:
    flake-utils.lib.eachDefaultSystem (system:
      let pkgs = import nixpkgs { inherit system; };
      in {
        devShells.default = pkgs.mkShell {
          packages = [ /* ... */ ];
          shellHook = ''...'';
        };
      });
}

nix develop 会将你带入 devShells.default。使用 direnv 时,将 use flake 写入 .envrc,然后运行 direnv allow。

共享工具(每个模板均包含)

工具用途始终包含的原因
just任务运行器justfile 是项目标准
ast-grep结构化搜索 / lint静态强制执行无法用 grep 编写的规则
apmAgent 依赖管理器通过 apm.yml 可复现地分发技能 / 提示词

使用各语言模板

安装模板只需将 flake.nix + apm.nix 并排放在项目根目录:

# Example: MoonBit project
cp ~/.claude/skills/nix-setup/assets/apm.nix .
cp ~/.claude/skills/nix-setup/assets/moonbit/flake.nix .

nix develop           # builds on the first run
# If you're a direnv user:
echo 'use flake' > .envrc && direnv allow
MoonBit
  • 使用 moonbit-overlay.packages.${system}.moon-patched_latest
  • 该 overlay 固定在已知可用的修订版本(50118f5c3c0298b5cb17cc6f1c346165801014c8)。最新 HEAD 有时依赖 nixpkgs-unstable 中标记为损坏的软件包(例如 tcc),因此求值可能会在一段时间内失败。更新前请先验证。
  • 当存在 moon.mod.json 时自动运行 moon update(仅首次运行)
  • 参考:vibe-lang 的 flake.nix
Rust
  • 通过 rust-overlay 管理工具链
  • 默认使用 stable.latest.default + rust-analyzer / clippy / rustfmt
  • 固定到特定版本:rust-bin.stable."1.91.0".default
  • rust-toolchain.toml 集成:rust-bin.fromRustupToolchainFile ./rust-toolchain.toml
  • WASM 目标:targets = [ "wasm32-wasip1" "wasm32-unknown-unknown" ]
TypeScript
  • nodejs_24 + pkgs.pnpm(顶层)
  • nodePackages.* 已于 2025 年从 nixpkgs 中移除——nodePackages.pnpm 不再可用
  • 将 PNPM_HOME 指向项目本地路径($PWD/.pnpm),避免污染 $HOME
  • 如需切换到 npm / yarn,请移除 pkgs.pnpm 并使用 pkgs.nodejs_24 自带的 npm,或添加 pkgs.yarn
Python + uv
  • pkgs.python3 + pkgs.uv
  • uv 自行管理 Python 版本,因此 nix 端只需提供备用版本
  • UV_PROJECT_ENVIRONMENT=$PWD/.venv、UV_CACHE_DIR=$PWD/.uv-cache 可保持 $HOME 整洁
Haskell
  • pkgs.haskellPackages.{ghc,cabal-install,haskell-language-server,hlint,ormolu,ghcid}
  • 使用 nixpkgs 默认值(haskellPackages)。要固定 GHC 版本,可替换为 pkgs.haskell.packages.ghc98 等。
  • 如需更严格的可复现性,可考虑 haskell.nix(IOHK),但学习曲线和复杂度会大幅增加。
  • 要使用 stack,请添加 pkgs.stack,并通过 stack.yaml 的 resolver 固定 GHC 版本。
  • 在 macOS 上,stdenv.cc.cc.lib 不在 PATH 中,可能导致某些 FFI 场景出错 → 添加类似 buildInputs = [ pkgs.zlib ] 的配置。
OCaml
  • pkgs.ocamlPackages.{ocaml,dune_3,findlib,merlin,ocaml-lsp,ocamlformat,utop} + pkgs.opam
  • nixpkgs 默认使用 OCaml 5.x 系列。可使用 pkgs.ocaml-ng.ocamlPackages_5_2 等固定版本。
  • opam 管理:shellHook 将 OPAMROOT=$PWD/.opam 设置为项目专用目录,并在首次运行时自动执行 opam init + opam switch create default --empty。后续运行只会 eval opam env。
  • 使用空 switch 可直接使用 nix 提供的 ocaml,避免双重编译器管理。
  • .gitignore 包含 .opam/,避免意外提交状态文件。
  • 其他库通过 opam install <pkg> 安装到项目本地。
  • merlin 是 ocaml-lsp 的依赖。安装两者即可获得完整的编辑器集成。
OxCaml(Jane Street 的分支)
  • 不在 nixpkgs 中。遵循官方推荐的“opam + 源码构建”流程;Nix 端仅提供 opam 和构建工具链(autoconf、automake、m4、pkg-config、gmp、libffi)。
  • 首次运行 shellHook 时:
    1. 创建 $OPAMROOT/.opam
    2. 创建空的 oxcaml-dev switch
    3. 使用 opam pin add -ny git+https://github.com/oxcaml/oxcaml 固定上游仓库
    4. 使用 opam switch set-invariant --packages oxcaml-dev 设置不变量
  • 不会自动运行实际的编译器构建(耗时 5–20 分钟 / 约 1 GB)。用户需要显式运行:
    opam install oxcaml-dev
    opam install dune merlin ocaml-lsp-server ocamlformat utop
    
  • 支持:arm64 macOS / arm64 Linux / x86_64 Linux。x86_64 macOS 可以运行,但不属于官方支持范围。
  • ocaml 模板使用“相同的 opam 基础设施,但采用不同的 switch”,因此你可以在两个模板之间切换。

apm.nix 的工作原理

microsoft/apm 不是以 npm 包的形式分发,而是一个由 PyInstaller 打包的原生二进制文件。

  • _internal/ 附带 Python 3.12 运行时和依赖库
  • apm 二进制文件本身会引用同级目录中的 _internal,因此无法单独提取并使用
  • 在 Linux 上,autoPatchelfHook 会重写指向 glibc / libstdc++ / zlib 的链接,使其指向 nix store
  • 所有内容都放在 $out/libexec/apm/ 下,$out/bin/apm 是指向该目录的 makeWrapper 包装器
  • 必须设置 dontStrip = true + dontPatchELF = true——PyInstaller 会在 Mach-O / ELF 文件末尾附加一个 PKG 归档。stdenv 默认的 strip / patchelf 会截断文件末尾,因此如果不禁用这些操作,二进制文件在运行时会报错:Could not load PyInstaller's embedded PKG archive。

版本更新流程:

# 1. Fetch the SHA256s for the new release
for a in darwin-arm64 darwin-x86_64 linux-arm64 linux-x86_64; do
  curl -sSL "https://github.com/microsoft/apm/releases/download/vX.Y.Z/apm-${a}.tar.gz.sha256"
done

# 2. Replace version and sources.*.sha256 in assets/apm.nix

使用 Nix 处理 npm 工具(截至 2026 年)

nodePackages.* 被移除后的正确做法:

  1. pkgs.pnpm / 顶层包——先尝试这个。如果它在 nixpkgs 中,就使用它。
  2. buildNpmPackage + importNpmLock——自行使用锁文件构建官方包。完全锁定版本。
  3. 在 shellHook 中设置 NPM_CONFIG_PREFIX="$PWD/.npm-global"——不纯,但作用域限于项目。当追查哈希的成本太高时,可将其作为备用方案。
  4. npx / pnpm dlx——适用于很少使用的 CLI。

避免:直接在 shellHook 中编写 npm install -g(会污染用户的 $HOME)、引用 nodePackages.*(已移除),以及在新项目中采用 dream2nix / node2nix(维护工作正在减少)。

buildNpmPackage 骨架
my-cli = pkgs.buildNpmPackage {
  pname = "my-cli";
  version = "1.2.3";
  src = pkgs.fetchFromGitHub {
    owner = "owner"; repo = "my-cli"; rev = "v1.2.3";
    hash = "sha256-...";
  };
  # To switch to a lockfile-based build:
  # npmDeps = pkgs.importNpmLock { npmRoot = ./.; };
  npmDepsHash = "sha256-...";
  dontNpmBuild = true;   # no build needed for a pure CLI
};

home-manager(可选)

如果你想用 Nix 以声明式方式管理整个用户环境(zsh / git / starship / CLI 包),请使用 assets/home-manager/。与 chezmoi 配合时,先对 dot_zshrc 等文件运行 chezmoi forget,将管理权交给 home-manager。

文件布局
  • flake.nix——两个输出:macOS 桌面配置(macos)和 Claude Code Web / 临时 Linux 配置(ccweb)
  • common.nix——主机间共享的配置(zsh、git、starship、direnv、fzf、基本 CLI)
  • macos.nix——aarch64-darwin 专属配置(helix、neovim 等大型工具)
  • ccweb.nix——精简的 x86_64-linux 配置(保持轻量,目标是冷启动时间 < 2 分钟)
用法
# 1. Copy
cp -r ~/.claude/skills/nix-setup/assets/home-manager ~/.config/home-manager
cd ~/.config/home-manager

# 2. Edit `username` / `email` at the top of flake.nix
$EDITOR flake.nix

# 3. Apply
home-manager switch --flake .#macos     # macOS
home-manager switch --flake .#ccweb     # Linux for Claude Code web, etc.
在公共仓库中管理时的注意事项

此模板不包含任何机密信息(username / email 是 flake.nix 变量;没有主机名、令牌或 known_hosts)。可以安全地放在公共 GitHub 仓库中。

通过以下任一方式管理你自己的机密信息(SSH 配置、内部主机、API 令牌):

  1. 创建 ./private.nix 并通过 imports 加载。在 .gitignore 中排除它(模板已包含此设置)。
  2. 使用 sops-nix / agenix 加密后提交。
Claude Code 网页版的冷启动时间估算
步骤使用 cache.nixos.org不使用缓存
setup_nix.sh20-40 s相同
flake 求值 + 替代下载30-90 s2-8 min
激活(符号链接展开)几秒相同
总计1-2 min4-12 min

向 ccweb.nix 添加的重量级软件包越多,冷启动就越慢。将共享部分放在 common.nix 中,只在 ccweb.nix 中编写额外的软件包。

添加到现有仓库

与新项目(cp assets/<lang>/flake.nix .)不同,现有仓库有以下几个容易踩坑的地方。

1. cp 之前保存现有文件

模板 cp 会覆盖现有的 .envrc / flake.nix / .gitignore。按“保存 → 合并”的顺序操作:

# Save the existing one
[ -f .envrc ] && cp .envrc .envrc.pre-nix

# Drop the template in
cp ~/.claude/skills/nix-setup/assets/typescript/flake.nix .
cp ~/.claude/skills/nix-setup/assets/typescript/.envrc .

# Restore existing exports, etc.
# Merge by hand with .envrc.pre-nix as reference
2. .envrc 合并策略

如果现有 .envrc 中有 export DATABASE_URL=... 之类的内容,请将 use flake 放在最前面,并将现有的 export 留在其后(devShell 环境是基础,仓库特定的值会覆盖它)。

# Correct order
use flake                              # start the devShell first
dotenv_if_exists .env.local            # secrets
export DATABASE_URL="postgres://..."   # preserve existing exports

反过来,先写 export 则有被 use flake 覆盖的风险。

3. 锁文件迁移(npm → pnpm 等)

同时存在 package-lock.json 和 pnpm-lock.yaml 会导致未定义行为。如果要迁移,请将其与 Nix 工作放在单独的 PR 中:

git switch -c chore/pnpm-migration
rm package-lock.json && rm -rf node_modules
corepack enable && corepack prepare pnpm@10 --activate
pnpm install                          # re-resolve
pnpm why <critical-dep>               # check for major drift
pnpm build && pnpm test               # verify
git add pnpm-lock.yaml package.json && git rm package-lock.json
git commit -m "chore: migrate npm -> pnpm lockfile"

如果 rebase 时 pnpm-lock.yaml 发生冲突,不要手动修复——运行 pnpm install 重新生成,然后执行 git add。

4. 在 CI 中替换 actions/setup-node

使用 Nix 化改动重写现有 ci.yml 中与 Node 相关的步骤:

-      - uses: actions/setup-node@v7
-        with:
-          node-version: 24
-          cache: pnpm
-      - run: pnpm install --frozen-lockfile
-      - run: pnpm test
+      - uses: DeterminateSystems/nix-installer-action@main
+      - uses: DeterminateSystems/magic-nix-cache-action@main
+      - run: nix develop --command just ci

在 just ci 中定义 pnpm install --frozen-lockfile && pnpm build && pnpm test(将其移入 justfile)。避免冷构建的诀窍是通过 actions/cache 单独保留 pnpm store。

5. 单仓库多项目处理

对于使用 pnpm-workspace.yaml / turborepo / Nx 的单仓库多项目,在根目录放置单个 flake.nix,即可让所有工作区共用 nix develop。将各软件包的开发工具保留在 package.json devDependencies 中,并将 nix 限定为语言运行时和跨项目工具(just / ast-grep)。

6. 与现有 .gitignore 合并

复制 assets/ocaml/.gitignore 或 assets/oxcaml/.gitignore 会覆盖现有的 .gitignore。必须进行合并。

  • 始终添加 result / result-*(Nix 构建产物)
  • 添加 .direnv/(nix-direnv 缓存)

direnv 集成

每种语言的模板都包含一个 .envrc。将它与 flake.nix 一起复制后,进入目录时会自动应用 devShell。

cp ~/.claude/skills/nix-setup/assets/apm.nix .
cp ~/.claude/skills/nix-setup/assets/rust/flake.nix .
cp ~/.claude/skills/nix-setup/assets/rust/.envrc .
direnv allow                             # approve once at the start

必须使用 nix-direnv——裸用 direnv 会在每次进入目录时重新求值 flake,耗时 10-60 s。nix-direnv 会缓存结果并创建 GC 根,将耗时缩短至 < 100 ms。在 assets/home-manager/common.nix 中,已通过 programs.direnv.nix-direnv.enable = true 启用。

随附的 .envrc 中使用了以下模式:

  • moonbit:仅使用 use flake(最简)
  • rust:使用 use flake + watch_file rust-toolchain.toml——工具链切换时自动重新加载
  • typescript / python-uv:使用 use flake + dotenv_if_exists .env.local——加载本地 API 密钥等
编辑器集成

安装 VS Code 的 direnv.direnv 扩展,或 Helix / Neovim 的 direnv 插件,可让 LSP 服务继承 devShell 的 PATH。rust-analyzer 会从 flake.nix 获取 rustToolchain,moon ide 会获取 overlay 版本的 moon,等等。

GC 根清理
nix-direnv-prune     # detect and remove unused .direnv

大约每六个月清理一次。当 /nix/store 开始变得臃肿时。

GitHub Actions

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7

      - uses: DeterminateSystems/nix-installer-action@main
      - uses: DeterminateSystems/magic-nix-cache-action@main

      - name: Run tests in dev shell
        run: nix develop --command just test

magic-nix-cache-action 会将 Nix store 放入免费的 GitHub Actions 缓存中。对于个人项目来说绰绰有余。对于大规模场景,可考虑 Cachix / attic。

故障排除

error: experimental Nix feature 'nix-command' is disabled
mkdir -p ~/.config/nix
echo 'experimental-features = nix-command flakes' >> ~/.config/nix/nix.conf
error: cannot build on ... due to sandbox

在容器 / rootless 环境中,sandbox 无法运行。在 /etc/nix/nix.conf 中添加 sandbox = false(setup_nix.sh 会执行此操作)。

error: attribute 'pnpm' missing / 未找到 nodePackages.pnpm

在 nixpkgs >= 24.11 中,nodePackages.* 已被移除。请使用顶层的 pkgs.pnpm。

macOS 上 /nix/store 的权限错误

建议使用 Determinate 安装器。在 Apple Silicon 上手动安装需要拆分 APFS 卷。

autoPatchelfHook 失败(libstdc++.so.6 not found)

将 stdenv.cc.cc.lib 添加到 buildInputs。这与 apm.nix 中使用的修复方法相同。

对于 PyInstaller 打包的二进制文件(如 apm),内嵌的 CPython _ssl / _hashlib 模块也会链接到 libssl.so.3 / libcrypto.so.3,因此还要将 pkgs.openssl 添加到 buildInputs。macOS 会跳过 autoPatchelfHook,因此只有在 Linux 上(例如在 CI 中)才会暴露这个问题。

更新 flake 输入
nix flake update              # all inputs
nix flake update nixpkgs      # individual
direnv-2.37.x 在 macOS Nix 沙箱中构建时会无限期挂起

在 macOS 上使用 Determinate Nix 沙箱本地构建 direnv 2.37.x 时,./test/direnv-test.zsh 会无限期阻塞。表现为:building '/nix/store/...-direnv-2.37.x.drv'... 的 CPU 占用接近 0,持续数十分钟;zsh ./test/direnv-test.zsh 子进程则会永远停留在 0:00.01。

修复方法:通过 overlay 全局关闭 direnv 的 doCheck。仅对 programs.direnv.package 进行此设置不够——nix-direnv 会将原始 direnv 作为传播依赖,因此仍会通过该路径运行测试阶段。

# common.nix (home-manager) or any nixpkgs consumer
nixpkgs.overlays = [
  (_: prev: {
    direnv = prev.direnv.overrideAttrs (_: { doCheck = false; });
  })
];

当 cache.nixos.org 为你的平台提供预构建的 direnv 2.37.x 后,移除此覆盖。

direnv 2.37.x 不再读取 DIRENV_LOG_FORMAT / DIRENV_LOG_FILTER

从 2.37.x 起,设置 export DIRENV_LOG_FORMAT="" 不再能让 direnv 静默——环境变量的处理方式已重做,direnv 现在只读取 direnv.toml。每次启动 shell 时出现的 direnv: loading … / using devbox / export +AR +AS +CC … 等杂乱信息不受影响,仍会显示。

修复方法:改为写入 ~/.config/direnv/direnv.toml。使用 home-manager 时:

programs.direnv.config.global.log_format = "";

不使用 home-manager 时:

# ~/.config/direnv/direnv.toml
[global]
log_format = ""

错误和警告仍会显示;只有常规状态信息会被隐藏。

参考资料

评论

支持 Markdown