みなさん Nix は使用していますか?
シェル環境を非破壊的にセットアップできて便利ですよね。
Nix はそれだけでなく、自作ソフトウェアのビルドツールとして利用でき、パッケージの作成と配布の手段としても利用できます。
Nix のパッケージリポジトリ ーとしてはみなさんご存じ Nixpkgs があります。
search.nixos.org
でも、使われるか分からない自作ソフトウェアを Nixpkgs に公開するのはちょっと気が引けるわけです。
そういうときのために Nix User Repository(NUR)があります。
nur.nix-community.org
どういうパッケージを NUR に登録するとよいかはドキュメントに次のように書いてあります。
Packages that are only interesting for a small audience
Pre-releases
Old versions of packages that are no longer in Nixpkgs, but needed for legacy reason (i.e. old versions of GCC /LLVM )
Automatic generated package sets (i.e. generate packages sets from PyPi or CPAN )
Software with opinionated patches
Experiments
ここまでは、「パッケージを公開したいけど Nixpkgs に公開するほどでもない」という側面から NUR の存在意義を見ました。
逆に次のように思う人もいるはずです。
「pkgs.fetchzip
や(Flakes なら)inputs
で任意のパッケージを取ってこれるんだからわざわざ NUR に登録しなくてもいいのでは?」
確かにそれはそうで、その上で NUR に登録する利点としては NUR のウェブ UI で検索ができるのでユーザーが存在に気付きやすくなるなどです。
Package search for NUR
NUR を使うとき
一旦 NUR を使うときはどう使うのかを見ていきましょう。
次のコードは NUR のパッケージをシェルで使う場合の例で、NUR 公式ドキュメント からの引用です。
(1) の箇所で NUR を取得し、(2) の箇所でオーバーレイを追加し、(3) の箇所でパッケージ pkgs.nur.repos.mic92.hello-nur
を参照しています。mic92
がリポジトリ ー名(通常はユーザー名と同じ)で hello-nur
がパッケージ名です。
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
nur = { # (1)
url = "github:nix-community/NUR";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = { self, nixpkgs, flake-utils, nur }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs {
inherit system;
overlays = [ nur.overlay ]; # (2)
};
in
{
devShells.default = pkgs.mkShell {
packages = [ pkgs.nur.repos.mic92.hello-nur ]; # (3)
};
}
);
}
パッケージのほかにも Nix ライブラリーや Nix OS モジュール・Nixpkgs オーバーレイが提供され(でき)ます。詳しくは公式ドキュメント を参照してください。
NUR のしくみ
NUR は NUR の Git リポジトリー で完結するわけではありません。NUR Git リポジトリ ーは個々人のリポジトリ ーへのリンクを repos.json に持ち定期的に個々人のリポジトリ ーをマージします。
{
"repos ": {
⋮
"kakkun61 ": {
"github-contact ": "kakkun61 ",
"url ": "https://github.com/kakkun61/nur-packages "
} ,
⋮
}
個々人のリポジトリ ーでは default.nix で lib
modules
overlays
それからパッケージのデリベーションを提供します。
{ pkgs ? import <nixpkgs> { } }:
{
lib = import ./lib { inherit pkgs; }; # functions
modules = import ./modules; # NixOS modules
overlays = import ./overlays; # nixpkgs overlays
wd = pkgs.callPackage ./pkgs/wd { };
}
自作パッケージの追加のしかた
まずは前述の「個々人のリポジトリ ー」を自分用に作成します。リポジトリ ーのテンプレートが用意されているのでそれを利用します。
github.com
そして自作ソフトウェアのパッケージを default.nix で提供できるようにします。そのとき、default.nix は pkgs
を引数に取ること・builtins.fetchTarball
ではなく pkgs.fetchzip
を使うこと・デリベーションは broken = true;
に設定すること、などルールがあるのでドキュメントやテンプレートのコメントを読みましょう。 自分の場合は次のようなファイルを pkgs/wd/default.nix に用意しました。
{ pkgs, fetchzip }:
let
version = "80e0814140c33201adf0e5213c426fb7bd5f47cf";
project =
fetchzip {
url = "https://github.com/kakkun61/wd/tarball/${version}";
sha256 = "sha256-usZTBF9pk0IsGdZb6IqEHBEaBX7mnXutykpm9TJHAWk=";
extension = "tar.gz";
};
in
(import "${project}/linux" { inherit pkgs; }).default.overrideAttrs {
broken = true;
}
そしてルートの default.nix でこのファイルを読んでいます。
そしてこれらがちゃんと評価実行ができるか確認します。
ここまでできたら NUR に自分のリポジトリ ーを登録する PR を出します。PR タイトルのフォーマットが指定されているだけで特に概要に追記することなどはありませんでした。自分の PR はこれです。
github.com
PR がマージされれば NUR が取り込んでくれるのを待ちます。すぐに更新してほしい場合は HTTP エンドポイントがあるので通知します。テンプレートの GitHub Actions に実装されているのでしたい人はセットアップしましょう。
自分のページ が NUR のウェブサイトに表示されましたか?おめでとうございます!