nix-flake-organization について
Nix flake リポジトリのレビューとリファクタリング向けスキルです。`flake/`を公開出力層、`src/`を機能実装層に分け、移行と検証の手順を示します。
主な機能
- 01公開出力と実装の分離
- 02薄い出力アダプターの維持
- 03機能単位のコード整理
- 04移動時の出力名維持
- 05flake 出力とビルドの検証
活用シーン
- 01肥大化した`flake.nix`の整理
- 02出力配線からモジュール実装を分離
- 03flake の公開 API の明確化
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ darkmatter/ skills --skill nix-flake-organizationインストール後、Claude Code で/nix-flake-organizationを入力して読み込まれたか確認します。
詳細
Nix フレークの構成
flake/ は公開出力レイヤー、src/ は実装レイヤーとして維持します。フレークツリーでは名前とルートを定義し、出力を再エクスポートします。機能の動作、モジュール本体、パッケージの導出式、アプリのスクリプト、ヘルパーロジックは src/<name>/... に配置します。
この境界内で codebase-design を適用します。
各機能の実装をまとめ、複雑さを隠す場合や有用な再利用を可能にする場合に限って切り出します。Nix の出力アダプターは、意味のある公開エントリーポイントです。内部転送専用のファイルを追加する場合は、独自の目的が必要です。TypeScript の models/ や services/ ディレクトリを押し付けるのではなく、Nix の役割を維持してください。
使用する場合
- ユーザーが Nix フレークの構成を整理またはリファクタリングするよう求めている。
- フレークの出力が
flake.nixに詰め込まれている、または実装コードと混在している。 - NixOS、nix-darwin、Home Manager、または flake-parts のモジュールに、出力の配線ファイル内のビジネスロジックが含まれている。
- リポジトリで、公開フレーク API と実装内部を明確に分ける必要がある。
使用しない場合
- リポジトリの構成を変えずに、パッケージ、アプリ、またはモジュールを1つ追加するだけのタスク。
- リポジトリが Nix フレークではない。
- ユーザーが、確立済みの別のプロジェクト構成を維持するよう明示的に求めている。
基本プロンプト
リクエストを実装計画に変換する際は、次の改善済みプロンプトを使用します。
このリポジトリを再構成し、トップレベルの
flake/ディレクトリに公開フレークのインターフェースを配置してください。該当する場合は、flake/apps、flake/packages、flake/lib、flake/modules/{flake-parts,home-manager,darwin,nixos}を用意します。flake.nixは最小限のエントリーポイントとして維持し、flake/内のすべてのファイルを薄く保ってください。ファイルで行えるのは、出力名の宣言、実装ファイルのインポート、flake-parts モジュールの構成、公開呼び出し規約への適合です。導出式のロジック、アプリのスクリプト、オプションや設定の本体、サービスの動作、ヘルパーの実装を含めてはいけません。こうした実装の詳細は、機能を中心としたsrc/<name>/...のパスにまとめてください。構成を移動しても既存の出力属性名は維持し、公開インターフェースを変更する場合は、リポジトリの互換性ポリシーに従ってください。nix flake show、nix flake check、および代表的なパッケージやモジュールの評価またはビルドで検証してください。
目標の構成
既存のリポジトリに合わせて名前を調整しながら、次の構成を優先してください。
flake.nix
flake/default.nix
flake/apps/default.nix
flake/packages/default.nix
flake/lib/default.nix
flake/checks/default.nix # if checks exist
flake/devShells/default.nix # if devShells exist
flake/overlays/default.nix # if overlays exist
flake/modules/flake-parts/default.nix
flake/modules/home-manager/default.nix
flake/modules/darwin/default.nix
flake/modules/nixos/default.nix
src/<name>/app.nix
src/<name>/package.nix
src/<name>/lib.nix
src/<name>/modules/flake-parts.nix
src/<name>/modules/home-manager.nix
src/<name>/modules/darwin.nix
src/<name>/modules/nixos.nix
flake-parts モジュールがある場合は、ユーザーの簡略な例に含まれていなくても、flake/modules/flake-parts をプラットフォーム別のモジュール群と並べて配置します。
機能中心の構成とは、出力の種類ごとではなく、ドメインの概念ごとにまとめることです。たとえば vpn という概念にパッケージ、アプリ、NixOS モジュールがある場合は、それらを src/vpn/ にまとめます。パッケージに関連するモジュールがない場合は、src/<pkg-name>/package.nix に配置しても構いません。リポジトリがすでにプラットフォーム別に整理されている場合は、その構成を src/ の下でも維持できます。ただし、flake/ のツリー全体を機械的に src/ の下に再現してはいけません。
薄いレイヤーのルール
| 場所 | 許可される内容 | 許可されない内容 |
|---|---|---|
flake.nix | 入力、最小限の outputs、./flake のインポート | パッケージ/モジュールの実装 |
flake/apps | アプリの出力名とインポート | シェルスクリプト、ラッパー、実行時の動作 |
flake/packages | パッケージの出力名とインポート | mkDerivation、オーバーレイ、ビルドロジック |
flake/lib | 公開ヘルパーの再エクスポート | ヘルパーの実装 |
flake/checks | チェックの出力名とインポート | テストハーネスの実装 |
flake/devShells | 開発シェルの出力名とインポート | ツールのセットアップロジック、シェルフック |
flake/overlays | オーバーレイの出力名とインポート | パッケージのオーバーライドとビルドロジック |
flake/modules/flake-parts | flake-parts のインポートとモジュールの構成 | perSystem のビルドロジック、派生物、アプリスクリプト |
flake/modules/* | 公開モジュールのエクスポートとインポート | オプション、config、アサーション、サービス |
src/<name>/... | すべての実装詳細 | 公開出力スキーマの決定 |
薄いことは、空であることを意味しません。薄いファイルでは、呼び出し規約を調整したり、inputs、self、pkgs を渡したり、公開属性名を維持したりできます。実装の詳細を読まなくても理解できる状態にしてください。
設定済みのファイルサイズ制限を守ってください。まとまりのあるモジュールが制限を超える場合は、まず独立した責務を切り分けられないか検討してください。それができない場合は、範囲を限定した制限の引き上げ、または例外について記録してください。1つの機能を説明するオプション、デフォルト値、アサーション、設定は、モジュールが長くなったとしても、まとめて配置してください。
モジュール出力において、薄いとは flake/modules/<platform>/default.nix ファイルが再エクスポートポイントであることを意味します。完全なモジュールを src/ からインポートし、それを公開出力属性に接続します。単一のモジュール内でオプションと設定を分割することではありません。オプションと設定は src/<name>/modules/<platform>.nix にまとめて配置してください。
# flake/modules/nixos/default.nix
{ ... }:
{
flake.nixosModules.vpn = import ../../../src/vpn/modules/nixos.nix;
}
# src/vpn/modules/nixos.nix
{ config, lib, pkgs, ... }:
{
options.services.vpn = { ... };
config = lib.mkIf config.services.vpn.enable { ... };
}
flake-parts リポジトリでは、perSystem が packages、apps、checks、devShells を担うことがよくあります。flake/modules/flake-parts では perSystem の構成を薄く保ってください。パッケージの派生物は引き続き src/<name>/package.nix に、アプリの動作は src/<name>/app.nix に、開発シェルやチェックの実装は src/<name>/... に配置します。同じ出力を、flake/packages の直接配線と flake-parts の perSystem 配線の両方で定義しないでください。
移行ワークフロー
- 現在の公開出力を一覧にします:
packages、apps、lib、checks、devShells、overlays、nixosModules、darwinModules、homeManagerModules、および flake-parts のインポート。 - まず公開出力のスキーマを維持します。ユーザーから破壊的変更の依頼がない限り、出力属性の名前を変更せずにファイルを移動します。
- 現在の出力が1つのファイルに混在している場合は、まず出力ファミリーごとに切り分け、それぞれ独立して移動できるようにします。一度に全面的に書き換えることは避けます。
flake/ディレクトリを出力の薄いシムとして作成し、出力ファミリーを1つずつ移動します。- 実装は機能ごとに整理した
src/<name>/...に移します。リポジトリがすでにプラットフォーム中心の構成でない限り、flake/のツリーをsrc/の下に再現することは避けます。 - 共有実装は
flake/libではなく、src/<name>/lib.nixまたはsrc/shared/<name>.nixに置きます。 - 名前を変更した出力については、リポジトリの互換性ポリシーに従います。そのポリシーで必要な場合にのみエイリアスを残し、それ以外の場合は利用側を更新して古いパスを削除します。
formatterのように対応するサブディレクトリがない出力には、それ専用の薄いflake/<output>/シムを用意するか、最も近い既存の構成ファイルに残します。無関係なディレクトリにまとめないでください。- 各ファミリーの移動後に、
nix flake show、nix flake check、対象を絞ったビルドと評価で検証します。
よくある間違い
flake.nixをflake/に移動すること。Nix はリポジトリのルートにflake.nixがあることを想定しています。flake/を薄い公開レイヤーではなく、新たな実装の置き場所として扱うこと。- 共有コードの置き場所として便利に感じるため、実装を
flake/libに隠すこと。 - オプション宣言、
config、アサーション、サービスをflake/modules/*に置くこと。 packages.${system}とapps.${system}はシステム固有である一方、モジュール出力は通常そうではないことを忘れること。src/<name>/...から実装をインポートするのではなく、flake/modules/flake-partsにperSystemのビルドロジックを置くこと。- 明確な互換性上の理由がないのに、同じ derivation に対して直接の出力配線と flake-parts の
perSystem配線の両方を作ること。 flake/lib、flake/modules、srcの間で循環インポートを作ること。- 移動のみのリファクタリングで公開出力名を変更すること。
- パスの移動だけに見えるという理由で、検証を省略すること。
テンプレート化されたスクリプト
シェルスクリプトをパッケージ化するときは、長いスクリプトを Nix 文字列に埋め込まず、再利用可能なスクリプトロジックを独立したソースファイルに置きます。Nix はパッケージ固有のデフォルト値の置換にのみ使用します。
nixpkgs 形式の @name@ プレースホルダーと replaceVars を優先します:
writeTextFile {
name = "tool";
destination = "/bin/tool";
executable = true;
text = builtins.readFile (replaceVars ./tool.sh {
default_config = builtins.toJSON config;
});
}
スクリプトでは、Nix による置換をすべて先頭にまとめ、実行時の値を引数または環境変数で上書きできるようにします:
default_config() {
cat <<'JSON'
@default_config@
JSON
}
: "${TOOL_JQ:=jq}"
tool_config() {
if [ -n "${TOOL_CONFIG_JSON:-}" ]; then
printf '%s\n' "$TOOL_CONFIG_JSON"
else
default_config
fi
}
これにより、Nix の外部でもスクリプトを利用でき、Nix との結合を簡単に監査でき、引用符の多いインラインシェル文字列を避けられます。また、substituteAll が replaceVars に置き換えられた現在の nixpkgs の規約にも沿います。
レビューチェックリスト
flake/のファイルは、ほとんどがインポート、属性名、再エクスポート、公開呼び出し規約のアダプターです。src/<name>/...には derivation、スクリプト、オプション、設定、サービス、アサーション、ヘルパーが含まれています。- 既存の公開出力名が引き続き機能するか、意図的な移行についての注記が用意されています。
- モジュールファミリーは分離されています:
home-manager、darwin、nixos、flake-partsの間で、プラットフォーム固有のロジックが漏れ出していません。 - 検証コマンドは、システム固有の出力とモジュールの評価パスの両方を対象にしています。
- テンプレート化されたスクリプトは独立したファイルに置かれ、
replaceVarsを使った@name@プレースホルダーを使用しています。再利用可能な動作のために環境変数や引数による上書きを可能にしつつ、Nix 固有のデフォルト値は先頭にまとめられています。
ツール
ありません。これはプロンプトとレビューに特化したスキルです。検証には、リポジトリで既に使用されている Nix コマンドを使ってください。
参考資料
個別の参考ファイルはありません。上記の正規プロンプト、薄いレイヤーのルール、移行ワークフロー、レビューチェックリストを使用してください。