自行过期的 Nix 覆盖
摘要
一篇博客文章,演示了一种 Nix 模式,使包覆盖在过时时发出警告,基于评估期间的条件版本或元数据检查。
<p><a href="https://lobste.rs/s/wnyesi/nix_overrides_expire_themselves">评论</a></p>
查看缓存全文
缓存时间: 2026/08/05 13:58
# 会自我过期的 Nix 覆盖项
Source: https://jezenthomas.com/2026/07/nix-overrides-that-expire-themselves/
Jezen Thomas (https://jezenthomas.com/)
## Jezen Thomas (https://jezenthomas.com/)
Supercede 的联合创始人兼 CTO。
我最近向 Hackage 发布了 `yesod-form-1.7.10`。我的项目从 nixpkgs 获取所有依赖,而 nixpkgs 会逐步从 Hackage 采纳 Haskell 包。这意味着,包进入 nixpkgs 和我需要在项目中使用它之间有一段时间差——而我现在就需要用它。
你可以在 `flake.nix` 中编写一个覆盖项来获取你需要的更新包,但当你最终升级 nixpkgs 版本、覆盖项变得多余时会发生什么?默认情况下,没有任何机制会警告你该移除这个覆盖项。
我的一位同事向我展示了这个模式,它能让覆盖项自行宣告过时。当 Nix 评估 flake 时,它会比较包版本,并在版本大于或等于你覆盖项中的版本时发出警告。
```
packageOverrides = prev.lib.composeExtensions prev.haskell.packageOverrides
(hfinal: hprev: {
# we require 1.7.10 for runFormPRG; the pinned nixpkgs only has
# 1.7.9.2.
yesod-form =
let
noOverride =
prev.lib.versionAtLeast hprev.yesod-form.version "1.7.10";
in
prev.lib.warnIf noOverride ''
yesod-form >= 1.7.10 is now in nixpkgs, the override can be removed.
''
(if noOverride then
hprev.yesod-form
else
prev.haskell.lib.dontCheck (hfinal.callHackageDirect
{
pkg = "yesod-form";
ver = "1.7.10";
sha256 = "sha256-9TqA7c2djVaLvrj/rj47LiJ7D1rLbrGhi585FvD9zRE=";
}
{ }));
});
```
在这个例子中,`hprev.yesod-form.version` 是所固定的 nixpkgs 提供的版本。`lib.versionAtLeast` 函数比较版本字符串,而 `lib.warnIf` 则在条件为真时于评估期间打印一条消息。
因此,当需要移除覆盖项时,你会看到类似这样的信息:
```
evaluation warning: yesod-form >= 1.7.10 is now in nixpkgs, the override can be removed.
```
这种方法并不局限于包版本。只要覆盖项的理由可以用条件来表达,你都可以在任何覆盖项上使用。例如,我们也用这种方法来清理那些在 nixpkgs 中被标记为 broken、后来又取消该标记的包的覆盖项。
```
markUnbrokenWithWarning = p: nixpkgs.lib.warnIfNot p.meta.broken ''
Package ${p.meta.name} is no longer broken.
The corresponding override can be removed.
''
(markUnbroken p);
```
当有人最终在上游修复了该包并移除了 `broken` 标志时,这条警告就会告诉我们删除相应的变通方案。
nix (https://jezenthomas.com/tags/nix/)
← 上一篇:Announcing DocCharm (https://jezenthomas.com/2026/07/announcing-doccharm/)
相似文章
Nixpkgs 的便捷覆盖
Gabriella439 介绍了 override-utils,这是一个简化 Nixpkgs 覆盖和叠加的新包,旨在提升 Nix 生态系统的易用性。
Nix 的 Substituter 列表不是路由表
一篇博客文章,解释了 Nix 的序列化二进制缓存查找的性能限制,并介绍了 ncro,一个用 Rust 编写的小型代理,它通过并行竞争上游缓存来减少延迟。
Nix 需要可重定位的二进制文件
文章指出了一个问题是 Nix 二进制文件不可重定位,当存储前缀改变时会导致哈希变化和重新编译,并提出使用带有 $ORIGIN 的相对路径在 RUNPATH 中实现可重定位,而不会使缓存失效。
使用Nix构建系统软件
一篇博客文章,讨论Nix如何帮助解决构建系统软件时的依赖和可重现性问题,特别是针对像BPF和io_uring这样快速演进的子系统。
Nix Flakes 及其在 Guix 中的对应物
详细比较 Nix Flakes 与 Guix 包管理系统中的对应物,涵盖依赖声明、锁定、纯净性、输出、开发环境和系统配置。