nixのコマンドを解説してみる

## 概要
nixはパッケージマネージャーである以前に各種言語のビルドラッパーでありDockefileのような環境構築ツールでもある。それゆえに使うコマンドも多い。
何のコマンドが何の目的で存在するか分からなかったので自分なりに理解して書いてみる。

## 備考
- [nixのマニュアル](https://nixos.org/manual/nix/stable/introduction.html)を日本語にした+メモ
    - 全部載せるには体力がなかったので本家参照のこと

- nix 2.4からnixコマンドに全ての機能を集約する変更が加えられた(まだ実験的)
    - より現代的で使いやすいものにする変更らしい
    - nix-*は淘汰される予定なので新しいコマンドも合わせて紹介する
    - 機能的に違う場合があるので注意
    
- manは従来が`man nix-<foo>`、新規が`man nix3-<foo>`

- 新しいコマンドは`configuration.nix`に明示的に書かないと使えない

```nix
# 以下をついき
{
  nix.extraOptions = ''
    experimental-features = nix-command flake
  '';
}
```


## コマンド解説

### パッケージマネージャーとしてのnix（pacmanと比較してみた）
- まとめはしたがNixOSの良さ(宣言的に書いて管理する)を殺している気がするのでそんなに出番ない
    - クエリの検索くらいしか使った事ない
- \-は該当が無いか見つけきれてない
- \|はor
- nix searchはnixpkgsだけでなくflakeを使ったリポジトリを指定すればその中のパッケージの検索も可能
    - nix-envと比べてかなり速いのでこっちを使おう

| コマンド | 新コマンド | pacmanとの対応 | 解説 |
| :- | :- | :- | :- |
| nix-env -iA nixpkgs.gcc | nix profile install nixpkgs#gcc | pacman -S gcc | インストールコマンド。-Aは最も優先度が高いnix式(おそらくバージョンのみ違う場合に最新のものだけを列挙する事と思われる)のみから検索してインストールされる。検索対象が絞られるため速い。 |
| nix-env -i gcc-3.3.3 | nix profile install nixpkgs/\<hash\|branch\>#gcc | pacman -U /path/to/cache | 特定のバージョンを入れたい時に。一応、nix-env -i gcc-3.3.3 gcc-4.0.2のように違うバージョンを同時に指定すると同時に入れることができる。(競合はする)。 |
| nix-env -f ~/foo.nix -i '.*' | - | makepkg -i foo/PKGBUILD | ローカルのnix式からのインストール |
| nix-env -f 'nixpkgs.hello' -A hello --dry-run | - | - | --dry-runを作ると/nix/storeのどこにインストールされるか分かる。|
| nix-env -uA | nix profile upgrade '.*' | pacman -Syu | 全てのパッケージのアップグレード |
| nix-env -u gcc-3.2.2 --always | - | pacman -U /path/to/lower-version | 特定のバージョンへのダウングレード。|
| nix-env -e gcc/nix-env -e | nix profile remove \<position\|attribute path\|store path\|'.*'(all remove)\> | pacman -D --asdeps $(pacman -Qqe) | 特定のパッケージ/全てのパッケージの削除(pacmanのやつは必須パッケージは残る) |
| nix-env --set-flag (true\|false) | - | pacman.confのNoUpgradeへの書き込み/削除 | 特定のパッケージのバージョンを固定/固定解除 |
| nix-env -q | nix profile list | pacman -Qem | インストール済みパッケージ一覧(nix-envで入れたやつのみ列挙 |
| nix-env -qa | nix search nixpkgs | pacman -Slq | 全てのインストール可能なパッケージの表示。-qasにするとパッケージの状態(インストール済みか否かなど)も表示。 |
| nix-env -qa '.*zip.*' | nix search nixpkgs#zip | pacman -Ss '*zip' | 特定のパッケージの検索(正規表現も使える) nix searchは#をつけないとその名前を含んだ全てのパッケージを提示する。|
| nix-env --list-generations | - | - | 世代のリスト |
| nix-env --delete-generations (3 4 5 \| +5 \| d \| 30d \|) | nix profile wipe-history --older-than 100d | paccache -r |  左から(特定の世代\|最新の５つを残して\|現在の世代より前全て\|30世代より前全て)削除 |
| nix-env -G 42 | nix profile rollback to 42 | - | 特定の世代へ切り替え |
| nix-env --rollback | nix profile rollback | - | ひとつ前の世代へ切り替え |

## キャッシュの削除

| コマンド | 新コマンド | pacman | 解説 |
| :-: | :-: | :-: | :-: |
| nix-collect-garbage -d | nix store gc | pacman -Sc | 現在の世代以外を削除 |
| nix-collect-garbage --max-freed $((100 * 1024 * 1024)) | nix store gc --max 1G |  paccache -ruk3 | 指定の容量に達するまで削除 |

## ビルドツールとしてのnix
- 生成物は./resultにシンボリックリンクで作成される
- 最終的にバイナリが生成される時に使う？ 
- nix-buildとnix buildの間にnix式の互換性は無い

| コマンド | 新コマンド | 解説 |
| :-: | :-: | :-: |
| nix-build '\<nixpkgs\>' -A (firefox\|openssl.all\|openssl.man | nix build nixpkgs#hello | nixpkgsの特定のパッケージをビルド。複数のoutputsがある場合、特定のoutputだけ得ることも可能 |
| nix-build| nix build | 単に実行するとディレクトリのdefault.nixをビルドする(nix buildはflake.nixでdefaultに設定されているパッケージ) |
| nix-build --dry-run | nix build --print-out-paths | store pathだけ得る |
| nix-build --no-out-link | nix build --no-link | ./resultへのリンクを作成しない |


## 環境構築ツールとしてのnix
- 変更の中で一番大きい??
- 以下にコマンドと用途を記載

| コマンド | 用途 |
| :-: | :-: |
| nix-shell | default.nixに書かれた依存関係を備えた隔離環境。 |
| nix develop | flakeにおけるnix-shell。\<nixpkgs\>.mkShell { buildInputs = [ any pkgs ]; }で書かれた依存関係が入った環境。ビルド手順の確認に。 |
| nix shell | こちらは、stdenv.mkDerivationに書かれた内容でビルドされたパッケージにパスが通っている環境に入る。生成物の確認、隔離環境の構築に。 |
| nix run | バイナリの実行。ビルドして実行するだけ。 |

| コマンド | 新コマンド | 解説 |
| :-: | :-: | :-: |
| nix-shell | nix develop | default.nix(nix developはflake.nix)に記載された依存にパスが通った対話型環境に入る。nix developは`configurePhase`など定義済みのコマンドを実行できる。(nix-shellも一応できる) |
| nix-shell '\<nixpkgs\>' -A bash --run "command" | nix shell nixpkgs#bash -c "command" | パッケージをビルドして非対話型環境でコマンドを実行する |
| - | nix develop (--unpack\|--configure\|...\|--(eachPhase) | 指定されたPhaseを実行する。 |


## プロジェクト管理のためのnix

| コマンド | 解説 |
| :-: | :-: | 
| nix flake check | ビルドチェック。nixpkgs#bashや.#fooで対象のパッケージのビルドのみをチェック可能。 |
| nix flake check --no-build | nix式だけの評価 |
| nix flake clone \<path\> | flakeを含んだリポジトリのクローン |
| nix flake info | リポジトリの説明 |
| nix flake init -t template#full | テンプレートに応じてflakeリポジトリを作製。テンプレートの指定はしなくてもいい |
| nix flake new -t template#full /path/to/output | 指定のディレクトリにflakeリポジトリを作製 |
| nix flake show | リポジトリ内のパッケージの出力 |
| nix flake update | flake.lockの更新 |

## NixOSのためのnix

| コマンド | 解説 |
| :-: | :-: | 
| nixos-rebuild switch -p profilename --flake .#target | targetのnix式を使ってビルドとパスを通した後、更新した環境に入る。リブートが必要なものの更新は反映されない。-pでプロファイルネームをつけられる(ブート時に表示される)。
| nixos-rebuild boot ... | targetのnix式を使ってビルドまでする。次回ブート時に選択することでその環境に入る。 |
| nixos-rebuild test ... | nix-rebuild switchのブートローダに登録されない版。|
| nixos-rebuild dry-build ... | ビルドだけする |
| nixos-rebuild build-vm ... | VMに環境を構築する。

## ユーザー環境のためのnix

| コマンド | 解説 |
| :-: | :-: | 
| home-manager build --flake .#target | ユーザー環境のビルド |
| home-manager switch ... | ユーザー環境のスイッチ |
| home-manager generations ... | ユーザー環境の世代一覧 |
| home-manager remove-generations ID | 特定の世代を削除