nix pkgs のソースコードを探索する - pkgs.bats.passthru.withLibraries - passthru・symlinkJoin・wrapProgram を学ぶ

637 Views

January 09, 26

スライド概要

Nix 日本語コミュニティゼミ 資料
2026/1/9

profile-image

社内SE 仕事:Python/Snowflake/Azure 趣味:C#/Docker/Nix

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

ダウンロード

関連スライド

各ページのテキスト
1.

nix pkgs のソースコードを探索する pkgs.bats.passthru.withLibraries passthru・symlinkJoin・wrapProgram を学ぶ ryu 2026/1/9 Nix 日本語コミュニティゼミ

2.

Nix 日本語コミュニティゼミ 自己紹介: ryu バックグラウンド: 非 IT 系企業の社内 SE エンジニア歴 1 年 Nix が好き GitHub: ryuryu333 Zenn: trifolium 2026/1/9 ryu(@ryu_trifolium) 2

3.

Nix 日本語コミュニティゼミ ことの始まり Bash シェルスクリプト のテストツール Bats を導入した ヘルパーライブラリ bats-assert 等だけ見つからない! 2026/1/9 ryu(@ryu_trifolium) 3

4.

Nix 日本語コミュニティゼミ pkgs.Bats のソースコードを見てみる bats-assert を利用しているコードを発見 passthru.tests = { # ... bats.withLibraries (p: [ p.bats-support p.bats-assert p.bats-file p.bats-detik ]) # ... 2026/1/9 ryu(@ryu_trifolium) 4

5.

Nix 日本語コミュニティゼミ 使い方を真似てみる ビルドが通った! シェルスクリプトで load bats-asset も出来た devShells.default = pkgs.mkShell { packages = with pkgs; [ (bats.withLibraries (p: [ p.bats-assert p.bats-support ])) ]; }; 2026/1/9 ryu(@ryu_trifolium) 5

6.

Nix 日本語コミュニティゼミ めでたしめでたし? 2026/1/9 ryu(@ryu_trifolium) 6

7.

Nix 日本語コミュニティゼミ なんでこれで動くのか気になりますよね? →ソースコードを読んでみる リンク:nixpkgs/pkgs/by-name/ba/bats/package.nix 2026/1/9 ryu(@ryu_trifolium) 7

8.
[beta]
Nix 日本語コミュニティゼミ

bats.withLibraries を探す
passthru.withLibraries =
selector:
symlinkJoin {
name = "bats-with-libraries-${bats.version}";
paths = [
bats
]
++ selector bats.libraries;
nativeBuildInputs = [
makeWrapper
];
postBuild = ''
wrapProgram "$out/bin/bats" \
--suffix BATS_LIB_PATH : "$out/share/bats"
'';
};

2026/1/9 ryu(@ryu_trifolium)

8

9.

Nix 日本語コミュニティゼミ passthru とは(リファレンス) 関数を定義できる Nix pkgs で慣習的に使われるモノ passthru.tests passthru.updateScript 追加機能を加えるモノ passthru.withPackages 等(e.g. python.withPackages) ビルド実行時には無視される 中身を書き換えても rebuild されない (passed through される) 2026/1/9 ryu(@ryu_trifolium) 9

10.
[beta]
Nix 日本語コミュニティゼミ

passthru のサンプル
{ stdenv, fetchGit }:
let
hello = stdenv.mkDerivation {
# src
...
passthru = {
foo = "bar";
baz = {
value1 = 4;
value2 = 5;
};
};
};
in
hello.baz.value1 # result 4

等

2026/1/9 ryu(@ryu_trifolium)

10

11.
[beta]
Nix 日本語コミュニティゼミ

bats.withLibraries
passthru.withLibraries =
selector:
symlinkJoin {
name = "bats-with-libraries-${bats.version}";
paths = [
bats
]
++ selector bats.libraries;
nativeBuildInputs = [
makeWrapper
];
postBuild = ''
wrapProgram "$out/bin/bats" \
--suffix BATS_LIB_PATH : "$out/share/bats"
'';
};

2026/1/9 ryu(@ryu_trifolium)

11

12.

Nix 日本語コミュニティゼミ symlinkJoin とは(リファレンス) 複数の derivation を一つの derivation に配置 paths にリストしたパッケージへの symlinks を作成 2026/1/9 ryu(@ryu_trifolium) 12

13.
[beta]
Nix 日本語コミュニティゼミ

symlinkJoin のサンプル
symlinkJoin {
name = "myexample";
paths = [
pkgs.hello
pkgs.stack
];
postBuild = "echo links added";
}
/nix/store/sglsr5g079a5235hy29da3mq3hv8sjmm-myexample
|-- bin
|
|-- hello -> /nix/store/qy93dp4a3rqyn2mz63fbxjg228hffwyw-hello-2.10/bin/hello
|
`-- stack -> /nix/store/6lzdpxshx78281vy056lbk553ijsdr44-stack-2.1.3.1/bin/stack

2026/1/9 ryu(@ryu_trifolium)

13

14.

Nix 日本語コミュニティゼミ bats.withLibraries の symlinkJoin bats.withLibraries (p: [ p.bats-assert ]) [ bats bats-assert ] が paths に渡される それぞれのツールのビルドが行われる と呼ぶと symlinkJoin { paths = [ bats ] ++ selector bats.libraries; 2026/1/9 ryu(@ryu_trifolium) 14

15.

Nix 日本語コミュニティゼミ bats/package.nix(リンク) install.sh は bats のシェルスクリプト bin/bats を配置したりする resholve.mkDerivation rec { pname = "bats"; version = "1.12.0"; src = ... installPhase = '' ./install.sh $out ''; 2026/1/9 ryu(@ryu_trifolium) 15

16.
[beta]
Nix 日本語コミュニティゼミ

bats/libraries.nix(リンク)
bat-assert を share/bats/bats-assert に配置
bats-assert = stdenv.mkDerivation (finalAttrs: {
pname = "bats-assert";
version = "2.1.0";
src = ...
installPhase = ''
runHook preInstall
mkdir -p "$out/share/bats/bats-assert"
cp load.bash "$out/share/bats/bats-assert"
cp -r src "$out/share/bats/bats-assert"
runHook postInstall
'';

2026/1/9 ryu(@ryu_trifolium)

16

17.

Nix 日本語コミュニティゼミ ビルド産物の配置 symlinkJoin が無い場合の配置 /nix/store/fnj6f2gr439m0xyf931mrfsas9a30vpk-bats-1.12.0/bin/bats /nix/store/c25dr9pr55qz2pm3b2h56fchf7nd2588-bats-assert-2.1.0/share/bats/bats-assert これらが symlinkJoin があることで一か所に集まる /nix/store/yghky3in844mf0apjvnr3mq8mna6k4qx-bats-with-libraries-1.12.0/bin/bats /nix/store/yghky3in844mf0apjvnr3mq8mna6k4qx-bats-with-libraries-1.12.0/share/bats/bats-assert 2026/1/9 ryu(@ryu_trifolium) 17

18.
[beta]
Nix 日本語コミュニティゼミ

symlinkJoin - postBuild

wrapProgram により、環境変数
が設定されている
を使って bats は bats-assert を見つける
BATS_LIB_PATH

BATS_LIB_PATH

symlinkJoin {
# paths ...
nativeBuildInputs = [
makeWrapper
];
postBuild = ''
wrapProgram "$out/bin/bats" \
--suffix BATS_LIB_PATH : "$out/share/bats"
'';

2026/1/9 ryu(@ryu_trifolium)

18

19.

Nix 日本語コミュニティゼミ wrapProgram とは(リンク) オリジナルのバイナリをラップする before: bats コマンド -> bin/bats after: bats コマンド -> bin/bats -> bin/.bats-wrapped 2026/1/9 ryu(@ryu_trifolium) 19

20.
[beta]
Nix 日本語コミュニティゼミ

wrapProgram

bin/bats にて
を設定した後
bin/.bats-wrapped が呼ばれ、bats 本体が実行される
BATS_LIB_PATH

bats ->
/nix/store/yghky3in844mf0apjvnr3mq8mna6k4qx-bats-with-libraries-1.12.0/bin/bats ->
/nix/store/yghky3in844mf0apjvnr3mq8mna6k4qx-bats-with-libraries-1.12.0/bin/.bats-wrapped

#! /nix/store/lw117lsr8d585xs63kx5k233impyrq7q-bash-5.3p3/bin/bash -e
BATS_LIB_PATH=${BATS_LIB_PATH:+':'$BATS_LIB_PATH':'}
if [[ $BATS_LIB_PATH != *':''/nix/store/yghky3in844mf0apjvnr3mq8mna6k4qx-bats-with-libraries-1.12.0/share/bats'':'* ]]; then
BATS_LIB_PATH=$BATS_LIB_PATH'/nix/store/yghky3in844mf0apjvnr3mq8mna6k4qx-bats-with-libraries-1.12.0/share/bats'
fi
BATS_LIB_PATH=${BATS_LIB_PATH#':'}
BATS_LIB_PATH=${BATS_LIB_PATH%':'}
export BATS_LIB_PATH
exec -a "$0" "/nix/store/yghky3in844mf0apjvnr3mq8mna6k4qx-bats-with-libraries-1.12.0/bin/.bats-wrapped" "$@"

2026/1/9 ryu(@ryu_trifolium)

20

21.

Nix 日本語コミュニティゼミ wrapProgram wrapProgram を使用した際の .bats-wrapped は wrapProgram 未使用時の bin/bats と同じ内容が記載されたファイル bats -> /nix/store/yghky3in844mf0apjvnr3mq8mna6k4qx-bats-with-libraries-1.12.0/bin/bats -> /nix/store/yghky3in844mf0apjvnr3mq8mna6k4qx-bats-with-libraries-1.12.0/bin/.bats-wrapped wrapProgram を使わない場合 bats -> /nix/store/fnj6f2gr439m0xyf931mrfsas9a30vpk-bats-1.12.0/bin/bats 2026/1/9 ryu(@ryu_trifolium) 21

22.
[beta]
Nix 日本語コミュニティゼミ

bats.withLibraries(振り返り)
passthru.withLibraries =
selector:
symlinkJoin {
name = "bats-with-libraries-${bats.version}";
paths = [
bats
]
++ selector bats.libraries; # [ bats bats-assert ]
nativeBuildInputs = [
makeWrapper
]; # wrapProgram
postBuild = ''
wrapProgram "$out/bin/bats" \
--suffix BATS_LIB_PATH : "$out/share/bats"
''; # bats
BATS_LIB_PATH
};

の様なリストが出来る

を利用可能にする

実行時に

2026/1/9 ryu(@ryu_trifolium)

を自動的に設定するラッパーを作る

22

23.

Nix 日本語コミュニティゼミ 今日話さなかったこと という呼び出し方 withLibraries の引数である selector の役割 selector bats.libraries の意味 bats.withLibraries (p: [ p.bats-assert ]) passthru.withLibraries = selector: symlinkJoin { # ... これらは次回掘り下げます (関数の引数・返り値、無名関数、callPackages...) 2026/1/9 ryu(@ryu_trifolium) 23

24.

Nix 日本語コミュニティゼミ 詳細は記事にまとめています https://zenn.dev/trifolium/articles/01f4505c6f2eb9 2026/1/9 ryu(@ryu_trifolium) 24

25.

Nix 日本語コミュニティゼミ ご清聴ありがとうございました 2026/1/9 ryu(@ryu_trifolium) 25