😀
Nix で Setup スクリプトのある Custom Package を作る
はじめに
巷に溢れる Nix の記事には、カスタムパッケージを作るやり方はたくさんあるが、それに shellHook などをかぶせたやり方の解説はほとんど存在しない。
pythonPackage.venvShellHook
を参考にミニマムな setupHook
を含んだ package の作り方を紹介する。
サンプルコード
flake.nix
{
description = "Flake shell";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
inputs.flake-utils.url = "github:numtide/flake-utils";
outputs =
{ nixpkgs, flake-utils, ... }:
flake-utils.lib.eachDefaultSystem (
system:
let
pkgs = nixpkgs.legacyPackages."${system}";
in
rec {
defaultPackage = pkgs.stdenvNoCC.mkDerivation {
name = "mypkg";
src = ./.;
dontUnpack = true;
dontConfigure = true;
dontBuild = true;
installPhase = ''
mkdir -p $out/bin
echo "echo 'Hello, world!'" > $out/bin/hello
chmod +x $out/bin/hello
'';
};
mypkgShellHook =
pkgs.makeSetupHook
{
name = "mypkg";
propagatedBuildInputs = [
pkgs.bash
defaultPackage
];
substitutions = {
valueFromNix = "'value from nix!'";
shell = "${pkgs.bash}/bin/bash";
};
}
(
pkgs.writeScript "setup.sh" ''
#!@shell@
export GREETING="Hello, World!"
export VALUE_FROM_NIX=@valueFromNix@
''
);
}
);
}
これだけである、 makeSetupHook
を利用して自分の ShellHook
を定義してあげれば良い。
呼び出し方
flake.nix
{
description = "Flake shell";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
inputs.flake-utils.url = "github:numtide/flake-utils";
inputs.mypkg.url = "path:./mypkg";
outputs =
{
nixpkgs,
flake-utils,
mypkg,
...
}:
flake-utils.lib.eachDefaultSystem (
system: {
devShells.default = pkgs.mkShell { packages = [ mypkg.mypkgShellHook.${system} ]; };
}
);
}
呼び出す時は mypkgShellHook
を packages に指定してあげれば良い、
あとは nix develop
でお好みの環境に入ることができる。
おまけ
mkDerivation に setupHook
というものがあり、そこで完結させることも可能である。
{
description = "Flake shell";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
inputs.flake-utils.url = "github:numtide/flake-utils";
outputs =
{ nixpkgs, flake-utils, ... }:
flake-utils.lib.eachDefaultSystem (
system:
let
pkgs = nixpkgs.legacyPackages."${system}";
in
{
defaultPackage = pkgs.stdenvNoCC.mkDerivation {
name = "mypkg";
src = ./.;
dontUnpack = true;
dontConfigure = true;
dontBuild = true;
installPhase = ''
mkdir -p $out/bin
echo "echo 'Hello, world!'" > $out/bin/hello
chmod +x $out/bin/hello
'';
setupHook = (
pkgs.writeScript "setup.sh" ''
#!/bin/bash
export GREETING="Hello, World!"
''
);
};
}
);
}
Discussion