Nix Flakesとそれに対応するGuixの機能
(coopi.neocities.org)- Nix Flakesは、プロジェクト依存関係、ロック、出力スキーマ、開発環境を
flake.nixとflake.lockを中心にまとめるもので、Guixはchannels、manifests、guix describe、guix shell、operating-systemのような直交的なツールの組み合わせによって同種の機能を提供する - Flakesは、プロジェクトごとの
inputsと自動生成されるflake.lockで依存関係を固定し、Guixはユーザーごとのguix describe、プロジェクト内でコミットを記したchannels.scm、guix time-machineによって再現可能な環境を構成する - 純粋性はFlakesではrestricted evaluationによって強制され、GuixではSchemeモジュール構造、明示的な入力、隔離されたビルドコンテナを通じて設計上実現される
- 出力構造は、Flakesが
packages、devShells、nixosConfigurationsのような標準attrsetを提供する一方、Guixは<package>、manifest、operating-system、serviceのような透過的なSchemeレコードとファイルを各コマンドが直接利用する - 選択基準は、単一のエントリーポイントと標準スキーマを好むならFlakesが向いており、小さく独立したツールを組み合わせる方式を好むならGuixのほうが適している
主要な比較
- Nix flakeに相当する単一のGuix機能は存在せず、Nix Flakesが複数の問題を1つの大きな機能で解決するのに対し、Guixはより小さく直交的なツール群の組み合わせで対応する
- GuixはNix daemonを再利用しており、build isolationとstore managementを担うC++コンポーネントを共有している
- GuixはNix daemonの上にある言語、パッケージ定義、サービスシステムなどの大部分をGuile Schemeで新たに実装している
- GuixとNixは、derivation formatであるATermとdaemonの系譜を共有しているが、daemon上位の構造はGuix独自の方式で構成されている
- GuixはFlakesが提供するcapabilitiesを備えているが、それを異なる形で提供している
Nix Flakeの基本構造
- Nix flakeは、ルートに
flake.nixファイルを持つsource treeであり、通常はGit repositoryの形を取る flake.nixの存在によってsource treeはflakeとなり、このファイルはdescription、inputs、outputsのような構造を持つdescriptionは人間が読める文字列で、flakeが提供する内容を示すinputsは、他のflakes、Git repos、tarballsのようなdependenciesを宣言し、Nixがそれらをfetchしてevaluateしたうえでoutputs関数に渡すoutputsは、解決済みのinputsと特別なselfinputを受け取り、packages、dev shells、NixOS configurations、overlaysなどを含むstructured attrsetを返す関数である-
例の構造と実行対象
- 例の
inputsにあるnixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";は、GitHub上のNixOS/nixpkgsリポジトリからnixos-unstableブランチを取得することを意味する - 例のflakeは、
supportedSystems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" ];とnixpkgs.lib.genAttrsを使って、複数のCPU architectureごとのoutputsを生成する - Flakesは
packages.<system>レベルを要求し、例ではpackages配下のdefaultpackageをpkgs.buildGoModuleで定義している src = ./.;は、Git repository全体をsourceとして使うdevShellsはnix developが参照する開発shell定義であり、例ではpkgs.mkShellとbuildInputs = with pkgs; [ go gopls gotools ];を使う
- 例の
-
flake.lockと純粋評価- flakeに対してNixコマンドを実行すると、Nixはすべてのinputと推移的inputを正確なrevisionに固定するJSONファイル
flake.lockを生成する flake.lockは、マシンや時間をまたいだbuild reproducibilityを可能にするlock fileである- Flakesはpure evaluationを強制し、
$NIX_PATH、builtins.currentSystem、environment variablesが暗黙的に入り込めず、すべてがexplicitでなければならない - Flakesが果たす機能は、dependenciesの宣言、dependenciesのpinning、純粋性の強制、標準出力スキーマの提供、reproducible sharing、development environmentsの定義として整理できる
- flakeに対してNixコマンドを実行すると、Nixはすべてのinputと推移的inputを正確なrevisionに固定するJSONファイル
Guixの対応方法
- Guixは、Nix 2.4でFlakesが2021年11月1日に導入される前から、Flakesの機能のかなりの部分に対する解決策をすでに備えていた
- Guixのchannels mechanismは2018〜2019年ごろに導入された
- Guixの解決策はorthogonalであり、単一のmonolithic abstractionを採用せず、各ツールを独立して利用できる
-
Channelsと依存関係の宣言
- Flakeでは
flake.nix内にdependenciesを直接宣言し、例ではnixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";とhome-manager.url = "github:nix-community/home-manager";を使う - Flake inputの
inputs.nixpkgs.follows = "nixpkgs";は、home-manager自身のnixpkgsinputを取得せず、現在のflakeのnixpkgsを使うようにして、異なるnixpkgsのコピーが2つ生じる状況を避ける - GuixのchannelsはGuile modulesを含むGit repositoryで、通常はpackage definitionsを含むが、services、system configurations、任意のScheme codeも含められる
- Guix channelsは
~/.config/guix/channels.scmで宣言し、このScheme fileはchannel recordsのlistを返す guix pullはすべてのchannelsをfetchしてcompileし、それらのmodulesをすべてのguixcommandで利用可能にする- Channelsはrepository rootの
.guix-channelfileを使って、ほかのchannelsへのdependenciesを宣言できる - Guix channelsのchannel dependencyはflakeの
inputsにおおむね似ており、guix pull実行時にtransitive channel dependenciesも一緒にfetchされる
- Flakeでは
-
プロジェクトごとの依存関係とユーザーごとの依存関係
- Flakesはper-project方式で、各repositoryが独自の
flake.nixとinputsを持つ一方、channelsはsystem-wideまたはper-user方式で、channels.scmがすべてのguixinvocationsに適用される - Flakesは、異なるプロジェクトがそれぞれ異なるdependency setを自然に持てるよう支援し、Guixでは同じ効果を得るために通常
guix time-machineまたはseparate profilesを使う - Flakesは
github:NixOS/nixpkgs、git+https://...のようなURL-like syntaxを使い、channelsはplain Git URLsを使う - Flake syntaxはquick referencesではよりergonomicで、channelsはより単純でexplicitである
- Flakesは
flake = false;によって、flake.nixのないrepositoriesをnon-flake inputsとしてサポートする - GuixではchannelはScheme filesが入ったGit repositoryなので、特別なopt-inは不要で、Guile modulesがあるrepositoryならどれでもchannelになれる
- Flakesはper-project方式で、各repositoryが独自の
固定、再現性、タイムマシン
-
flake.lockflake.lockはJSON graphで、すべてのinputは正確なcommit hashにpinningされ、Nixはfetchしたsource tree全体のhashであるnarHashを検証するflake.lockはrepositoryにcommitされるため、cloneした人は同一のdependency versionsを受け取るflake.lockのoriginalは要求した対象で、lockedは実際に得られた対象であるflake.lockのtwo-layer systemは、nix flake lock --update-input nixpkgsのように特定のinputだけを更新し、残りは維持するselective updateを可能にする
-
guix describeとguix time-machine- Guixは
guix pull実行時にすべてのchannelsの正確なcommitsを記録し、guix describeがこの情報を表示する guix describeの出力にはgeneration番号、日付、current表示、channel名、repository URL、branch、commitが含まれる- Guixの記録されたchannel commitsはlock fileに相当するが、project directory内のfileではなく、
~/.config/guix/currentにあるGuile profileとして存在する - 再現可能な環境を共有するには、Guixでは**
guix time-machine**を使える guix time-machine --commit=8a1ab328 -- shell -m manifest.scmは、まずGuix自体を特定のrevisionにpinningし、そのrevisionのpackage definitionsを使ってguix shellを実行するguix time-machineは必要に応じてそのrevisionをdownloadしてcompileし、package definitionsが正確にそのcommit時点の状態であるisolated environmentを作成する- pinned commitsを持つ
channels.scmをproject repositoryにcheck inするGuixのパターンもある guix time-machine -C channels.scm -- shell -m manifest.scmは、repositoryに含まれるchannels.scmを使ってexact environmentを再現する
- Guixは
-
両方式の違い
flake.lockはper-projectかつautomaticで、guix describeはper-userかつautomaticである- pinned commits入りの
channels.scmはGuixでper-project pinningを提供するが、manual方式である - Guixはper-project pinningのergonomics改善を進めているが、現時点のworkflowではよりexplicitなセットアップが必要である
flake.lockはmachine-readableなJSON graphで、Guixにおける対応物はcommit hashesを持つchannelsを列挙したScheme fileである- どちらの方式もdependency pinningという目標を達成するが、flake lockはすべてのtransitive inputについて
originalとlockedentriesを持つfull dependency graphなので、よりstructuredである guix time-machineは直接的なflake equivalentがない機能で、pinned dependency versionsだけでなく、package collectionの完全に異なるhistorical stateへ移動できる
純粋性モデル
- Flakes は restricted evaluation context で実行され、
builtins.currentSystem、builtins.getEnv、$NIX_PATHの使用は禁止されるか無視される - Flakes ではすべてが declared inputs から来る必要があり、implicit state への accidental dependency が生じにくいようになっている
- Flakes の pure evaluation のトレードオフは、system detection のために明示的な
systemパラメータが各所で必要になることと、environment variables を読み取れないことにある - Flakes で impure escape hatch が必要な場合は、
--impureを明示的に渡さなければならない - Guix では別個の pure evaluation mode は不要で、evaluation は慣習上すでに pure である
- Guile modules は、environment variables として明示的に渡さない限り、それらにアクセスしない
- Guix には
$NIX_PATHに相当するものがなく、packages は search path ではなく module system を通じて解決される - Guix には
builtins.currentSystemに相当する概念がなく、systems は package metadata と--systemフラグで明示される - Guix の build も pure であり、builds は explicitly declared inputs だけが見える isolated containers で実行される
- Guix builds では
/usr/bin、/etc、network access はなく、network access の例外は fixed-output derivations に限られる - Build sandboxing の方式は、Nix と Guix が本質的に同じアプローチを共有している
- Guix は Scheme modules 構造を通じてアーキテクチャレベルで purity を達成し、Flakes はもともと impure な system の上に restricted evaluation mode を重ねて purity を強制する
出力スキーマとデータモデル
-
Flake output schema
- Flakes は outputs に対する standard schema を定義しており、
packages.<system>.<name>はnix build、devShells.<system>.<name>はnix develop、apps.<system>.<name>はnix runで使われる - Flake output schema には
nixosConfigurations.<name>、overlays.<name>、nixosModules.<name>、formatter.<system>、templates.<name>、checks.<system>.<name>もある - Flake output schema の standardization により、
nix build .、nix run、nix flake showが一貫した場所を参照するため、discoverability が高まる - Flake output schema の欠点は rigid である点で、任意の output types を追加するには Nix 自体の修正が必要だが、小規模な extension mechanism は存在する
- Flake の
<system>パラメータのため、multi-platform support は明示的に処理する必要があり、forAllSystems、flake-utils、flake-partsのような helper functions や libraries が使われる
- Flakes は outputs に対する standard schema を定義しており、
-
Guix の first-class data types
- Guix には Flakes のような単一の output schema はなく、複数の command が利用できる first-class data types がある
- Guix で packages は
<package>records として定義され、guix install、guix buildが利用する - Guix で manifests は Scheme files として定義され、
guix shell -m、guix packageが利用する - Guix で system configs は
operating-systemとして定義され、guix system reconfigureが利用する - Guix で home configs は
home-environmentとして定義され、guix home reconfigureが利用する - Guix で services は
<service>records として定義され、operating-systemのservicesfield が利用される - Guix で channels は Git repos であり、
guix pullが利用される - Guix で package variants は Scheme procedures であり、
--with-input、--transformが利用される
-
ファイルとパッケージ定義
- Guix project は、package definitions を含む channel、開発用の
manifest.scm、デプロイ用のsystem.scm、operating-systemまたはhome-environmentdeclaration などを組み合わせて提供できる - Guix ではこれらのファイルは special entry point file を必要とせず、Scheme values を定義する Scheme files にすぎない
- Guix では関連する
guixsubcommand にファイルを指定すれば command が処理し、別途 ceremony や schema validation は不要である - 例の
manifest.scmは、specifications->manifestに"guile"、"guile-git"、"guile-json"の package names list を渡して development environment を宣言する - 例の
mylib.scmは、Guix における Nix derivation の対応物である<package>record を定義し、package fields を programmatically query できる - 例の package definition は
(name "mylib")、(version "0.1.0")、(source (local-file "."))、(build-system gnu-build-system)、(inputs (list guile guile-git))、(home-page "https://example.com")、(license gpl3+)を持つ - Guix の
local-fileは build time に current directory の files を取り込み、Nix のsrc = ./.;に似ている - Guix の
gnu-build-systemは./configure && make && make install方式で、Guix にはcmake-build-system、python-build-systemなど他の build systems もある - Guix は、Nix で
stdenvがgccとcoreutilsを implicit に提供するのとは異なり、dependencies をすべて explicit にしている
- Guix project は、package definitions を含む channel、開発用の
開発環境
- Flakes の
devShellsの例では、devShells.x86_64-linux.default = pkgs.mkShell { buildInputs = with pkgs; [ go gopls gotools ]; shellHook = '' echo "Welcome to the devShell!" ''; };を使用する mkShellはビルド時にシェル環境を作成する derivation を生成し、buildInputsはシェル内のPATHに入り、shellHookはシェルに入る際に任意の bash を実行する- Flake の dev shell には
nix develop、または名前付きシェル用のnix develop .#my-shellで入る - Guix の開発環境は、
manifest.scmでspecifications->manifestにパッケージ仕様文字列のリストを渡して定義できる - 例の Guix manifest では
"go"、"gopls"、"go-tools"を宣言する - Guix manifest ベースのシェルには
guix shell -m manifest.scmで入る - Guix では ad-hoc な環境において、ファイルなしで
guix shell go gopls go-toolsのようにコマンドラインのパッケージ名だけを渡せる guix shellは完全な分離のための--container、標準的な Linux filesystem layout を期待するプログラム実行用の--emulate-fhs、Guix コンテナ内で Guix を実行する--nestingをサポートする- Guix manifests は、より大きな
flake.nix構造に埋め込まれていない、独立した Scheme ファイルである guix shellはファイルなしでも動作できるが、nix developには flake またはレガシーインターフェースのshell.nixが必要である- Flakes は
devShells.x86_64-linux.test、devShells.x86_64-linux.defaultのような名前付き dev shell を提供する - Guix manifests では、名前付き dev shell の代わりに
manifest.scm、test-manifest.scmのような別ファイルを並べて置く方式を取る - Nix Flakes と Guix はどちらもコンテナ化された開発をサポートする
システム構成
-
NixOS と Flakes
- Flakes の
nixosConfigurationsの例では、nixpkgs.lib.nixosSystemが NixOS modules のリストを受け取り、kernel、services、config files などを含む完全な system derivation を生成する - Flake ベースの NixOS デプロイの例のコマンドは
nixos-rebuild switch --flake .#myhostである - 例の
nixosConfigurations.myhostにはsystem = "x86_64-linux";とmodules = [ ./configuration.nix home-manager.nixosModules.home-manager ];が含まれる - NixOS modules は、
options、config、mkIf、mkDefault、mkForceを通じた優先順位ベースのマージを使う module system である - NixOS のモジュールシステムでは、複数のモジュールが同じオプションを設定しても、システムが優先順位を解決するため、数十個のモジュールが同じ構成に貢献しても衝突を避けやすい
- Flakes の
-
Guix
operating-system- Guix の
operating-systemは関数ではなく Scheme record であり、各 field は名前付きの型付き値として Guix が検証する - Guix system デプロイの例のコマンドは
guix system reconfigure config.scmである - 例の
operating-systemrecord には(host-name "myhost")、(timezone "Etc/UTC")、bootloader configuration、file systems、services が含まれる - Guix bootloader configuration の例では
grub-efi-bootloaderと target"/boot/efi"を使い、Guix は GRUB、U-Boot などをサポートする - Guix file systems はリストで宣言され、
%base-file-systemsは/dev、/proc、/sysなどのデフォルトを提供する - Guix services は directed acyclic graph(DAG) を構成し、各 service はほかの services を extend できる
%base-servicesは Shepherd init system、syslog、networking などの必須 services を提供する- Guix system configuration には特別な output type は不要で、
operating-systemrecord を返すファイルをguix systemに指定すればよい - Guix の service の組み合わせは、既存システムに任意の方法で接続される新しい service を書きやすくする
- Guix の
探索性とレジストリ
- Flakes には、プロジェクト依存関係、出力、発見可能なスキーマを 1 つのファイルで宣言する標準エントリポイント
flake.nixがある - Guix プロジェクトでは、
manifest.scm、channels.scm、guix.scm、package.scmなどの慣例ベースのファイルを使うことがある guix shellが自動認識するプロジェクトファイルとしてguix.scmを標準化しようとする動きはあるが、flake.nixほど確立されてはいない- Flakes には、短い名前を URL にマッピングするグローバルレジストリ flake-registry があり、例として
nix run nixpkgs#hello、nix build github:NixOS/nixpkgs#firefoxがある - Guix は似た利便性のためにパッケージ指定を使い、例として
guix shell hello、guix install firefoxがある - Guix には、任意の Git リポジトリを短い名前で指すレジストリ相当のものはなく、URL を直接使う
- Nix のレジストリは、
nixpkgsがレジストリエントリなのか、ローカルパスなのか、別の対象なのかが常に明確ではなく、混乱の原因になることがあった nix flake showは、flake が提供するすべての項目をツリービューで表示するコマンドである- Guix にはパッケージ用の
guix searchとサービス用のguix system searchはあるが、特定のプロジェクトやリポジトリが提供するすべての項目を表示する対応コマンドはなく、Scheme ファイルを直接確認する必要がある - Flakes は、
nix flake showが project の提供物を一貫したビューで示す点で discoverability が高い - Guix projects はより ad-hoc で、どのファイルを見るべきかを知っている必要があり、標準の単一エントリポイントファイルがない
- Guix はすべてが Scheme であるため、schema なしで好きなものを定義して組み合わせられ、flexibility が高い
パッケージモデルとグラフ書き換え
- Nix では、パッケージは
stdenv.mkDerivation { ... }呼び出しによって derivation を返す関数であり、その結果は不透明な attribute set である - Guix では、パッケージは
<package>レコードであり、名前付きフィールドを持つ透明なデータ構造なので、標準の Scheme 手続きで検査、変換、結合できる - Guix の package definition は opaque functions ではなく transparent records なので、特別なツールなしで inspect と transform をプログラム的に実行できる
- Guix では packages が data であるため、graph rewrites を容易に行える
- Guix では
package-input-rewritingによって依存関係グラフ全体を走査し、perlをperl-minimalに置き換える処理を表現できる - Guix の
inheritキーワードは、coreutilsのすべてのフィールドを継承し、指定したフィールドだけを上書きする形でパッケージを再定義する - Nix には似た目的の overlays があるが、不透明な関数インターフェースのため検査や変換がより難しく、使い勝手が劣る
セキュリティ更新、ブートストラップ、認証
- Guix の grafting は、すべての依存パッケージを再ビルドすることなく、依存関係ツリーにセキュリティ更新を適用できるようにする
- glibc のような低レベルライブラリに脆弱性がある場合、Guix はストアパスを書き換えて修正版に置き換えられる
- Nix はセキュリティ更新時にすべてを再ビルドし、依存関係ツリーが大きい場合はビルド時間に数時間の差が出ることがある
- Guix は ソースベースのブートストラップ に強く注力しており、小さな信頼基盤からシステム全体をビルドできる
- Guix のブートストラップチェーンは、約 500 バイトの hex assembler から始まり、Scheme で書かれた
mesC コンパイラ、tcc、完全な GNU toolchain へと続く - bootstrappable builds プロジェクトは、完全なソースブートストラップの詳細を扱っている
- Nix は Guix よりも多くのバイナリシードに依存している
- ブートストラップチェーンを監査できなければ、システムが本当に意図したソースからビルドされたかを完全には検証できないため、完全なソースブートストラップは信頼性と検証可能性にとって重要である
- Guix channels は 暗号学的認証 を標準でサポートしている
- Guix channel は、特定のコミットとその Ed25519 署名から成る「introduction」を指定し、Guix はその introduction から現在のコミットまでの署名チェーン全体を検証する
- Flakes は信頼モデルとして HTTPS と GitHub インフラを用いており、これは Guix の Ed25519 channel authentication とは異なるセキュリティモデルである
要約表の主要な対応関係
- 依存関係の宣言では、Flakes は
flake.nixのinputs、Guix はchannels.scmと.guix-channelを使う - 依存関係の固定では、Flakes は自動・プロジェクト単位の
flake.lockを使い、Guix はユーザー単位の自動guix describeと、プロジェクト単位の手動コミット指定channels.scmを使う - 純粋評価は flake mode で強制され、Guix では設計上の内在的特性である
- 出力スキーマは、Flakes が
outputsの構造化された attrset を使い、Guix は ad-hoc な Scheme records を使う - 開発環境は、Flakes が
devShellsとnix develop、Guix がmanifest.scmとguix shellを使う - システム構成は、Flakes が
nixosConfigurationsとモジュールシステム、Guix がoperating-systemとサービス DAG を使う - 1 コマンドでの再現性は、Flakes が
nix build github:foo/bar、Guix がguix time-machine -C channels.scm -- buildの形である - プロジェクト単位の固定は、Flakes が
flake.lockで自動処理し、Guix がコミットを含むchannels.scmで手動処理する - 探索性は、Flakes が
nix flake show、Guix が Scheme モジュールの検査に依存する - パッケージモデルは、Flakes/Nix が不透明な関数、Guix が透明なレコードである
- init system は、Nix が systemd、Guix が GNU Shepherd を使う
- セキュリティ更新は、Nix が全面再ビルド、Guix が高速な grafting を使う
- ブートストラップの信頼性は、Nix がバイナリシード、Guix が完全なソースブートストラップに基づく
- 認証済み更新は、Flakes が HTTPS/GitHub への信頼、Guix が Ed25519 channel authentication を使う
- FHS サポートは、Nix が
buildFHSUserEnv、Guix が--emulate-fhsを提供する - 非 Linux サポートは、Nix が macOS 向けの nix-darwin、Guix が GNU Hurd に整理される
- 自由ソフトウェア専用かどうかでは、Nix は専用ではなく構成可能であり、Guix は FSDG に準拠する
結論
- Flakes と Guix は、再現性、依存関係管理、システム宣言という同種の問題を、異なるアーキテクチャ哲学で解決している
- Flakes は、1 つのファイル、1 つのスキーマ、1 つのロックファイル、1 つの慣習の集合を備えた、単一機能に近い
- Guix は、配布のための channels、環境のための manifests、構成のための
operating-system、再現性のためのguix time-machine、その他の構造のための Scheme records といった、直交するツール群の組み合わせである - 1 つの標準的なやり方、1 つのエントリーポイントファイル、1 つの出力スキーマ、1 つのロック形式を好むなら、Flakes が自然に合う
- 小さく独立したツールを組み合わせ、それぞれのツールに 1 つのことをうまくやらせる Unix 哲学をパッケージ管理に適用するやり方を好むなら、Guix がよく合う
- 両エコシステムは、パッケージ管理は関数型・宣言的・再現可能であるべきだという考えを中心に発展しており、異なる実装で同じアイデアを押し進めている
1件のコメント
Lobste.rs の意見
このサイトはモバイルだと読みにくすぎる。文字が少し小さいし、スクロールするたびにずっと邪魔してくる
最初の比較以降は読めなかった。ずっと目次まで跳ね戻されるからだ
記事を読んでも、プロジェクトの依存関係をどう指定して固定すべきなのかまだよく分からない。配布して共有するには、
channels.scmに各推移的依存関係のコミットハッシュを手動で調べて入れなければならないように見えるtime-machineは Guix パッケージ集合にしか動かず、ツリー外依存関係には効かないようだnix run github:nixos/nixpkgs/<commit hash>#<package>のように、nixpkgs の過去時点のコードもかなり簡単に実行できるGuix が独特なのは、パッケージ集合のバージョンとパッケージマネージャのバージョンを分離しない点だ。古いパッケージを動かそうとすると古い Guix リリースも一緒に動かすことになるが、なぜそれを望むのかよく分からない
記事では flakes はコミットを手動で探して指定しなければならないと言いながら、その直後にコミットを指定しなければならない Guix コマンドを例に出している。Nix flake でも
--override-inputで nixpkgs バージョンを上書きできるが、これは雑で、だから unflake で改善しようとしている点の一つでもある普通は専用の
guix shell環境で開発して、共有する段階になったらguix describe -f channels > channels.scmで全コミットハッシュをchannels.scmに記録する流れだdeclaring channel dependencies の文書を見ると依存関係のコミットは指定できるが、その依存先がさらに依存を持つ場合にそちらも特定コミットへ固定されているか検証するオプションはないようだ
time-machineの--commit=表記は Guix チャネル向けだが、-Cでファイルから追加のチャネルを読み込めるパッケージマネージャとパッケージレコードに後方互換性を壊す変更が入っても、履歴と再現性を失わずに済む利点がある
ただし各コミットごとに nixpkgs のチェックアウトが必要なので、最初の構築コストは非常に大きい。一度作れば、その後のインデックス維持コストは低いはずだ
サイトの問題とこのスレッドは coopi に伝えておいたので、すぐ直ることを願う
完全に Guix 寄りの立場から言うと、coopi が言うように Guix にも Nix の
flake.nixやnixディレクトリのような、すべてを収める標準ファイル/ディレクトリがあればいいと思う。ただ、Scheme モジュールを読み込むには正しいパスを指定しなければならないので、不可能かもしれないこの Lobsters の記事には著者が言いたいことが入っているので、タグは
nixとlispだけでも十分に思えるlinuxを外そうというのは説得力がない。両者に共通する唯一のカーネルなのだから :P ただ、言うとおりunixは合わないかもしれない例えばこんな感じだ: そして新しいチャネルの作成や扱いを助ける
guix channelコマンドもあるとよいGuix にも Nix flake の
.inputs.nixpkgs.followsのように、推移的依存関係の固定値を上書きする機能があるのか気になるまた、著者の Guix 説明のかなりの部分は flakes 以前の Nix を思い起こさせる。標準エントリポイントがなく、チャネルを使う構造などだ。ただ、Guix には型システムと本物の言語があるので、同じパターンでも痛みは少ないように思える。Nix がもっと良かったか、別の言語だったら生まれていたかもしれないもう一つの歴史のように感じる
他のコメントで指摘されている使い勝手の問題のせいで、おすすめするのをためらう。私はデフォルトで JavaScript を無効化する NoScript を使っているので気づかなかった
それでもこの記事はちょうど必要なタイミングで来た。会社で Nix をかなり使う方向に進んでいて、flakes のせいで少し苦労しているのだが、この記事の説明は以前読んだものよりずっと明快だった
Coopi の回答: 今朝変更を入れたが仕事のためテストできておらず、調べてみるとJavaScript に問題があったとのこと
このサイトは iOS モバイルでは使えない。ページが下の方で読み込まれたあと即座に上へスクロールされるようで、1画面以上下へスクロールすると何かがトリガーされてまた上へ戻される
リーダーモードなら動くが、ハイライトと元々かなり良かった細かなスタイリングが失われる
flakes のやっていることは Guix の複数のツールでもできると言うのは妥当だが、Nix にも同じ問題を解く小さく直交したツール群が以前からあり、今でもあることは押さえておくべきだ
flakes が提供するのは標準プロジェクトエントリポイントと、それによって可能になるエコシステム、たとえばレジストリだ。記事でも Guix にはこの部分がないと言っている
Guix ユーザーは標準エントリポイントは不要だと判断するかもしれないし、多くの Nix ユーザーもそう判断してきた
しかし、直交的なツールセットで flakes はできると言うのは、FreeBSD は jail で必要なことは全部できるのだから OCI サポートは不要だ、という主張に似て聞こえる。標準化がエコシステムを可能にするという点を見落としている
Guix に強い関心があり、多少の貢献もしてきたが、
channels.scmとguix time-machineを使ったビルドが、flake の固定値を変えて Nix 評価を行うよりなぜそんなに遅いのか比較してみたい。3倍程度遅い、たとえば 5〜10 秒が 15〜30 秒になるくらいなら受け入れられるが、私が試したときはそんなレベルではなかった