🔧

nixファイル内の位置情報取得関数 (builtins.unsafeGetAttrPos)

2023/09/07に公開

nixpkgs.lib.warnという関数が有るんですが、これがほぼ色つけるだけでどこでwarningが発生したかといった情報を出してくれません。

nixpkgs/lib/trivial.nix
  warn =
    if lib.elem (builtins.getEnv "NIX_ABORT_ON_WARN") ["1" "true" "yes"]
    then msg: builtins.trace "[1;31mwarning: ${msg}[0m" (abort "NIX_ABORT_ON_WARN=true; warnings are treated as unrecoverable errors.")
    else msg: builtins.trace "[1;31mwarning: ${msg}[0m";

ファイル内の位置情報が欲しいわけです。そこでChatGPT4に雑に聞いてみると(Tips: nixはドキュメントが異常に豊富なためか、ChatGPTに聞くと割と便利情報が返ってきます) builtins.unsafeGetAttrPos というものが存在することが判明(一緒に出力されたコードは動かなかったがまあ良し)。少し試してみます。

以下の様なファイルを用意します(ここにtestとして置いてあったものです)。

test.nix
let
  as = {
    foo = "bar";
  };
  pos = builtins.unsafeGetAttrPos "foo" as;
in { inherit (pos) column line; file = baseNameOf pos.file; }

nix evalで評価します

$ nix eval --file test.nix
{ column = 5; file = "test.nix"; line = 3; }

良いですね。unsafeとある様に純粋な関数ではないわけですが、warningに出力する分には問題無いでしょう。

Discussion