既存のプロジェクトをNix化する方法（devenvとflake templates）

:::note info
この記事は[Nix Advent Calendar 2024](https://adventar.org/calendars/10086)の4日目の記事です。
:::

プログラミング言語やライブラリの使い方を学習するときに有効な方法の一つは、既存のリポジトリのソースコードを参考にすることです。ソースコードはウェブブラウザで閲覧することもできますが、使い慣れているテキストエディタ・IDEを使ってローカルで閲覧すると、開発時と同一の機能を利用できるので快適です。

現在、日本の人々の間では、[ghq](https://github.com/x-motemen/ghq)というソフトウェアを使ってソースリポジトリを git-clone するのが人気のようです。 日本はかつて、連合国軍最高司令官総司令部(GHQ)の占領下にありました。 太平洋戦争終戦直後の日本でアメリカ兵はチョコレートをばらまいていましたが、もはや戦争体験も日本国民共通の記憶ではなくなって久しいです。 最近のインフレで値上がりしているとはいえ、チョコレートは日本のドラッグストアで買うことができます。 GHQが人気である背景については私の知る由もありません。

https://x.com/BruceIkeGold/status/1866737768350757193

https://x.com/BruceIkeGold/status/1868723751627714775

もう一つ日本で最近流行しているものの一つとして、Nixがあるそうです。 私は2020年からNixOSを使っているので、Nixは日本国民と私の共通体験だといえるでしょう。 私の観測範囲でも、最近はGHQよりNixが気になっている人のほうが多いようです。

人々がNixを使う目的の一つは、開発環境の再現性です。 Nixを使う場合は、原則としてコンパイラやLSP等のツールチェーンをグローバルにインストールせず、プロジェクトごとに管理してself-containedなリポジトリとすることが望ましいです。

https://x.com/takeokunn/status/1862037993164587096

しかし、自チームの管理下にないリポジトリをGitHub等からgit-cloneして（ghqは使っても使わなくてもよいです）閲覧しようとする場合、そのリポジトリにはflake.nixやshell.nix等のNix環境が入っていない場合が多いでしょう。 LSPを利用してソースコードを快適に閲覧したり、OSSにPRを送る前にローカルでビルドして動作確認したりするためには、Nixの開発環境をすぐにセットアップする方法を習得しておくことが重要です。

今回の記事では、既存のプロジェクトにNix環境を追加する方法として、 (1) Nix初心者にも敷居の低いeasyな方法と、 (2) 私が使っているsimpleで依存が少ない方法を紹介します。




## Easyな方法: devenv

[devenv](https://devenv.sh/)を使うと、Nixベースの開発環境を簡単に用意することができます。 devenvには主要なプログラミング言語やサービスの設定が組み込まれており、わずかなセットアップ手順で、すぐに開発を始めることができます。 devenvを開発しているのは、Nixのバイナリキャッシュのサービスを提供するCachixであり、品質面でも信頼できるでしょう。 devenvの使い方については、公式の[Getting started](https://devenv.sh/getting-started/)がありますので、ここでは説明しません。




## Simpleな方法: Flakeテンプレート

私は現在devenvを使っていません。 devenvのバージョンが0.3-0.4だったときに試用していましたが、flakeとdevenvを併用すると仕組みが複雑で、学習コストも二重にかかってしまうので、使うのをやめました（私は[twist.nix](https://github.com/emacs-twist/twist.nix)のようなプロジェクトのためにflakeを学習する必要がありました）。 

devenvはパッケージだけでなくサービスも管理できる等様々な機能があるので、プロダクションレベルの本格的な環境を構築するには便利かもしれません。 練習程度のプロジェクトではそれほど本格的な環境は必要ない場合がほとんどですし、[flake-parts](https://flake.parts/)を使えばprocess-composeやdevenvさえも後から組み込めるようなので、私はflakeに必要なライブラリだけを組み込んでいく方式で環境構築しています。


flake.nixを書く手順を省くために、現在は、[flake-templates](https://github.com/akirak/flake-templates)というテンプレートリポジトリを整備して、Nixの `nix flake init` コマンドで各リポジトリに追加しています。対応言語は、OCamlやElixir、Gleam等、私が使っているまたは学習中の言語のみです。

使い方は以下のウェブサイトで説明しています（言語は英語のみです）。

https://akirak.github.io/flake-templates-doc/

Emacsを使っている人は、[nix3.el](https://github.com/emacs-twist/nix3.el)の​`nix3-flake-init`​コマンドを使うと、[flake registry](https://nix.dev/manual/nix/2.24/command-ref/new-cli/nix3-registry.html)に登録したリポジトリからテンプレートを選んで初期化できるので便利です。 nix3.elは私が書いたパッケージですが、Nix環境を含めたEmacsのE2Eテストという技術的課題が未解決のためWIPになっており、MELPA等のパッケージリポジトリに登録されていません。 ただし、 `nix3-flake-init` は問題なく動きます。




### 躍進を続けるflake-templates

この flake-templates リポジトリですが、私のリポジトリの中では比較的速いペースでスターが増えています。 今年は私のGitHubリポジトリの中でflake-templatesのスター数が最多になりました（下図）。

![star-history-2024123.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151145/ae86e0fd-3c41-497f-3025-e8f173836a11.png)


GitHubのtrafficを見ても訪問者は定常的にそこそこ多いです（当社比、下図）。検索エンジンからの流入が多く、内容を見られている言語としてはいつもTypeScriptが最多、続いてだいたいRustかGoが2位になっています。TypeScriptのテンプレートは正直にいって中身がほとんどないんですが、それだけ環境構築に悩んでいる人が多いエコシステムであるのかもしれません。

![wayshot-20241203-000833.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151145/61b6b0d5-6898-a7c3-6e77-45406e669aea.png)


自分が書いたパッケージよりもテンプレートのほうが人気になってしまうとは、皮肉なことです。 [Joel Spolskyが00年代に言った](https://web.archive.org/web/20120527092607/http://local.joelonsoftware.com/wiki/%E8%BA%8D%E9%80%B2%E3%82%92%E7%B6%9A%E3%81%91%E3%82%8B%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3%E5%AE%87%E5%AE%99%E9%A3%9B%E8%A1%8C%E5%A3%AB%E3%81%9F%E3%81%A1)、次の言葉が刺さります。

> アーキテクチャ宇宙飛行士に見られる顕著な特徴は、彼らが実際の問題を解かないということだ&#x2026; 代わりに、彼らは多くの問題のテンプレートに見えるものを解決する。少なくとも、解決しようとはする。

寄付金等は今のところ募っていないので、スターが増えても直接的な実益はありませんが、自分で調べなくてもIssues等から情報が入ってくるようになるのがOSSに取り組む利点だと思います。