🧑‍🍼

Nix flakeの冗長なRevisionをfollowsを使って解消する

2024/10/07に公開

Nix flakeに複数のinputを入れて使っていると、flake.lockにnixpkgs_2のような依存ができていることがあります。

flake.nix 例
{
  inputs = {
    package1.url = "github:foobar/package1";
    package2.url = "github:foobar/package2";
  };
  // 略…
}
flake.lock 例
"nixpkgs": {
  "locked": {
    "lastModified": 1727811607,
    "narHash": "sha256-2ByOBflaIUJKeF9q6efVcYHljZXGZ7MnCWtseRvmpm8=",
    "owner": "NixOS",
    "repo": "nixpkgs",
    "rev": "1839883cd0068572aed75fb9442b508bbd9ef09c",
    "type": "github"
  },
  // 略…
},
"nixpkgs_2": {
  "locked": {
    "lastModified": 1719082008,
    "narHash": "sha256-jHJSUH619zBQ6WdC21fFAlDxHErKVDJ5fpN0Hgx4sjs=",
    "owner": "NixOS",
    "repo": "nixpkgs",
    "rev": "9693852a2070b398ee123a329e68f0dab5526681",
    "type": "github"
  },
  // 略…
},

複数のパッケージがそれぞれnixpkgsに依存している場合に起こります。flake.lockを探すと、以下のような箇所があるはずです。

flake.lock 例
"package1": {
  "inputs": {
    "nixpkgs": "nixpkgs"
  },
  // 略…
},
"package2": {
  "inputs": {
    "nixpkgs": "nixpkgs_2"
  },
  // 略…
},

特に別々のrevisionにする理由がない場合、以下のようにinputs.nixpkgs.follows = "nixpkgs"と設定することで、各々のパッケージの依存を自分がinputsに定義したnixpkgsに向けることができ、nixpkgs_2のような依存がなくなります。

flake.nix 変更後
{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
    package1 = {
      url = "github:foobar/package1";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    package2 = {
      url = "github:foobar/package2";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };
  // 略…
}

実装例↓

https://github.com/kawarimidoll/vim-overlay/commit/2e741f49c20d329b22d4a1e3fc422a5389bf5b36

なお、このような重複が発生するのはnixpkgsに限りません。筆者の観測範囲では、flake-compatやgit-hooksといったユーティリティ系パッケージでも同様の事象が発生しました。

対応例↓

https://github.com/kawarimidoll/dotfiles/commit/8e05cfc27784fe88651026b6fb42ec0cc825529a

Discussion