Nixpkgs Maintainer Scripts 实战指南:get-maintainer.sh 元数据查询与 sha-to-sri.py 哈希格式迁移
2026/9/19 22:45:43 网站建设 项目流程

Nixpkgs Maintainer Scripts 实战指南:get-maintainer.sh 元数据查询与 sha-to-sri.py 哈希格式迁移

【免费下载链接】nixpkgsNix Packages collection & NixOS项目地址: https://gitcode.com/GitHub_Trending/ni/nixpkgs

导读

本文聚焦 Nixpkgs 仓库中 maintainers/scripts 目录下维护者常用脚本的实战用法,核心讲解两个工具:通过 get-maintainer.sh 以任意字段精确查询维护者元数据(等价于lib.maintainers.${x} // { handle = x; }),以及通过 sha-to-sri.py 将 Nix 表达式中旧式十六进制/Nix32/Base64 哈希批量、原子化地改写为 SRI 格式。读完本文,你将掌握这两个脚本的全部命令行参数、底层实现原理、配套数据文件结构,以及维护者元数据在仓库中的校验与消费方式。

目录概览:maintainer 工具箱

Nixpkgs 的维护者相关脚本统一收纳在 maintainers/scripts 目录下,其中包括:

  • 元数据查询类:get-maintainer.sh(精确查找维护者信息)
  • 哈希格式迁移类:sha-to-sri.py(SRI 哈希格式改写)
  • 数据校验类:check-maintainer-github-handles.sh(批量核对 GitHub 用户名有效性)
  • 辅助数据文件:maintainer-list.nix(约 3.2 万行的维护者注册表)、computed-team-list.nixgithub-teams.json

需要特别强调的是,README.md 明确声明:这些脚本并非稳定接口(not a stable interface),随时可能被修改或移除。因此在自动化流程或 CI 中引用它们时,应做好容错与版本锁定,不要把脚本行为当作长期契约。README 也注明其给出的仅是一份"远不完整"的概览,目录内其余脚本(如nixpkgs-lint.plremove-old-aliases.py等)未在文中一一展开。

get-maintainer.sh:精确查询维护者元数据

基本用法与命令格式

get-maintainer.sh的命令行格式为:

get-maintainer.sh [selector] value

其中selector指定查询字段,value是待匹配的取值。运行后脚本返回一个描述该维护者的 JSON 对象,其内容等价于 Nix 表达式:

lib.maintainers.${x} // { handle = x; }

即:取lib.maintainers属性集中该维护者的完整属性集,再并入其属性名handle,一并序列化为 JSON。相比用文本搜索直接 grep maintainer-list.nix,这种方式能基于真实字段值做精确匹配,结果更正确也更健壮。

支持的 selector 与匹配规则

selector必须是以下取值之一:

selector匹配依据说明
handle(默认)维护者在lib.maintainers中的属性名不传 selector 时默认使用
email维护者对象中的邮箱字段精确匹配
name维护者姓名精确匹配
githubGitHub 用户名精确匹配
githubIdGitHub 用户数字 ID精确匹配(数字比较)
matrixMatrix 用户 ID精确匹配

各字段的定义见 maintainer-list.nix 头部注释:handle是用于 Nix 表达式中的属性名,name是公开姓名,github是 GitHub 用户名,githubId是 GitHub 数字 ID,另有可选的emailmatrix与 PGP/GPGkeys指纹列表。

实战示例

按默认的handle查询(不传 selector):

❯ ./get-maintainer.sh nicoo { "email": "nicoo@debian.org", "github": "nicoonoclaste", "githubId": 1155801, "keys": [ { "fingerprint": "E44E 9EA5 4B8E 256A FB73 49D3 EC9D 3708 72BC 7A8C" } ], "name": "nicoo", "handle": "nicoo" }

按姓名查询(传入nameselector):

❯ ./get-maintainer.sh name 'Silvan Mosberger' { "email": "contact@infinisil.com", "github": "infinisil", "githubId": 20525370, "keys": [ { "fingerprint": "6C2B 55D4 4E04 8266 6B7D DA1A 422E 9EDA E015 7170" } ], "matrix": "@infinisil:matrix.org", "name": "Silvan Mosberger", "handle": "infinisil" }

从输出可以看到,handle字段被合并进结果对象中,便于在 JSON 管道里拿到维护者的属性名本身。

底层实现:nix-instantiate + jq 管道

查看 get-maintainer.sh 源码(一个nix-shell声明式脚本,依赖jqncurses),可以还原其完整调用链:

  1. 数据加载listAsJSON()调用

    nix-instantiate --eval --strict --json "${MAINTAINERS_DIR}/maintainer-list.nix"

    将 maintainer-list.nix 以 strict + json 模式求值,得到整个维护者属性集的 JSON 表示。MAINTAINERS_DIR被解析为脚本所在目录的上一级,即maintainers/

  2. 参数解析parseArgs()接受 1 或 2 个参数;参数个数为 1 时selector默认为handle。selector 若不在handle/email/github/githubId/matrix/name之内,脚本会列出合法值并以红色错误信息退出(set -euo pipefail全程开启)。

  3. jq 查询构造query()先执行"爆炸"变换

    to_entries[] | .value + { "handle": .key }

    { handle: {...} }形式展开为"每条记录 + 附带 handle 字段"的流;再按 selector 构造select表达式。值得注意的实现细节是:githubId使用数字比较select(.githubId == $value)),而其余字段均按字符串比较(select(.${selector} == "$value")),这与githubIdmaintainer-list.nix中是整数、其余字段是字符串的数据类型完全对应。

  4. 执行过滤:最终通过jq -e执行"$explode | $select"-e保证在无匹配(输出为空)时返回非零退出码,方便在脚本中做错误处理。源码中还留有一条 TODO 注释,说明name字段目前不支持近似匹配。

数据源:maintainer-list.nix 与 lib 集成

查询的数据源头 maintainer-list.nix 本身就是 Nixpkgs 中lib.maintainers的定义所在:lib/default.nix 中的

maintainers = import ../maintainers/maintainer-list.nix;

将其挂入lib.maintainers,因此get-maintainer.sh的返回等价于对lib.maintainers.${x}的求值。该文件要求字段保持字母序排列(keep-sorted),并且维护者注册遵循"必须有 GitHub 账号"的硬性约定——因为新维护者会被邀请加入@NixOS/nixpkgs-maintainers团队、可被请求 review、CI 也会对由其维护的包请求其审查。

配套的数据完整性校验位于 lib/tests/maintainers.nix,运行nix-build lib/tests/release.nix即可执行,其检查项包括:

  • 指定了github就必须同时提供githubId(缺失时脚本会调用 GitHub API 反查 ID 并打印修正提示);
  • emailgithubmatrix三者至少提供其一,确保维护者可被联系到;
  • 邮箱不得使用noreply.github.com这类不可达地址;
  • githubgithubIdemailmatrix在全表中必须唯一,否则lib.maintainers求值直接抛错。

sha-to-sri.py:哈希属性到 SRI 格式的批量迁移

背景:为什么需要 SRI 哈希

Nix 表达式中,固定输出派生式的哈希历史上存在多种写法(十六进制串、Nix 特有的 nix32 字母表串、Base64 串),且属性名可能是hashsha1sha256sha512之一。sha-to-sri.py的作用是把这些旧格式统一改写为 SRI(Subresource Integrity)格式,形如:

hash = "sha256-{base64 encoded value}";

"{hash name}-{base64 编码后的摘要}"。SRI 格式自带哈希算法前缀,消除了歧义,这也是当前 Nixpkgs 推荐并广泛采用的写法。

命令行用法

sha-to-sri.py path ...
  • path可以指向单个 Nix 文件,也可以指向目录——目录会被自动递归遍历(实际仅处理其中**/*.nix文件);
  • 可同时传入多个path
  • 脚本会原子化改写匹配到的哈希属性:先在原文件同目录创建临时文件写入新内容,成功后再替换原文件,保证中途失败不会破坏原文件(见源码 atomicFileUpdate 的实现:使用NamedTemporaryFile写入,正常退出时tmpPath.replace(target)完成原子替换,异常时删除临时文件并抛出)。

匹配与改写规则

从源码看,sha-to-sri.py 使用正则_DEF_RE匹配形如sha256 = "..."的属性定义,具体规则:

  • 属性名支持hashsha1sha256sha512(README 摘要所述;源码中_HASHES实际启用的是 SHA-256 与 SHA-512 两套算法族);
  • 值可以是十六进制(长度 2n)、Nix 的 nix32 编码(长度1 + (8*n)/5,字母表0123456789abcdfghijklmnpqrsvwxyz,注意无eotu)或Base64(含标准填充=);
  • 改写时把摘要解码为原始字节,再重新以f"{hashName}-{base64}"形式输出;
  • 值两侧的引号(单引号或双引号)会被保留并围绕新值重新闭合。

例如,仓库 pkgs/by-name/_0/_0x/package.nix 中的 SRI 写法:

hash = "sha256-im9F0MQYddCcBthSldeQ6T0BIswhBSGc/LKUlJg/754=";

就是本脚本目标形态的典型样例——算法名sha256-前缀加上 Base64 摘要。

自动跳过策略

sha-to-sri.py内置了两层跳过机制,防止误改自动生成的文件:

  1. 内容启发式:若文件首个非空行包含generated bydo not edit(大小写不敏感),则整文件跳过;
  2. 目录遍历启发式:递归目录时,文件名恰为yarn.nix(源码中另有gemset.nix)或文件名含generated的文件一律跳过。

该策略对应源码中的_SKIP_RE_IGNORE集合,同时_IGNOREyarn.nixgemset.nix的排除也保护了由打包工具自动生成的依赖锁定文件。

运行环境

脚本头部是 nix-shell shebang:

#! nix-shell -i "python3 -I" -p "python3.withPackages(p: p; [ rich structlog ])"

依赖python3(隔离模式-I)、richstructlog(用于结构化日志输出),因此可以直接以./sha-to-sri.py path方式在装有 Nix 的环境中运行,无需手工准备虚拟环境。

延伸:维护者数据的其他消费方式

maintainer-list.nix 头部注释推荐阅读 check-maintainer-github-handles.sh 作为"如何消费lib.maintainers数据"的示例。该脚本展示了另一条更重型的查询路径:

nix-instantiate -A lib.maintainers --eval --strict --json \ | jq -r '.[]|.github|select(.)' \ | parallel -j5 checkUser

它通过nix-instantiate -A lib.maintainers直接取出整个维护者集合,用 jq 提取所有 GitHub 用户名,再以parallel并发向 GitHub 发起请求,检查用户名是否有效(404 即失效)以及该用户在 Nixpkgs 是否有提交记录,用于清理失效维护者条目。这与get-maintainer.sh的单点精确查询形成互补:一个面向全量扫描,一个面向精确检索。

小结

  • 查询维护者元数据:使用 get-maintainer.sh,支持handle(默认)、emailnamegithubgithubIdmatrix六种 selector 的精确匹配,返回带handle字段的完整 JSON;其实现依托nix-instantiate --eval --strict --json求值 maintainer-list.nix 后交给 jq 过滤。
  • 统一哈希格式:使用 sha-to-sri.py,对单个 Nix 文件或目录递归改写hash/sha(1|256|512)为 SRI 格式,原子化写入,并自动跳过自动生成文件与yarn.nix/gemset.nix
  • 牢记非稳定接口:以上脚本仅面向 Nixpkgs 维护者日常工作,不提供稳定性保证,README 明确其可能随时变更或移除,自动化引用时务必注意。

【免费下载链接】nixpkgsNix Packages collection & NixOS项目地址: https://gitcode.com/GitHub_Trending/ni/nixpkgs

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询