Closed kachick closed 1 year ago
子(ChatGPT)曰く
Q,
I'm using Nix package manager in these days. However it is not fit for switching multiple latest versions of Programming Language interpreter and compilers. Which resource resolve it?
A,
Nix is a powerful package manager that allows you to easily install and manage software packages, including programming language interpreters and compilers. However, it can be challenging to switch between multiple versions of a programming language interpreter or compiler using Nix, as it has its own way to manage dependencies and versions.
One way to manage multiple versions of a programming language interpreter or compiler is to use the NixOS module system. NixOS allows you to define system configurations in a declarative way, and you can use this to create different profiles for different versions of a programming language interpreter or compiler.
Alternatively, you can use tools like nix-env or nix-shell to manage your environment. nix-env allows you to install, remove and switch between different versions of a package, and nix-shell allows you to enter a shell environment that has a specific version of a package installed.
Another popular tool is direnv, it allows you to automatically configure your environment based on the contents of a .envrc file in the current directory. This can be very useful for managing different versions of programming languages and their dependencies on a per-project basis.
You could also use asdf a language version manager it supports many languages and it allows you to switch between different versions with ease.
It's important to note that, each tool has its own benefits and drawbacks, and the best one for you will depend on your specific needs and use cases. You can try them and pick the one that better fits your needs.
便利すぎて、全然使用法わかってないのに nix-shell のためだけに使いまくってる。かなりのツール群が用意されてて、そのコマンド名で pkgs.theName で指定すると大体ある。 default.nix とshell.nix の使い分けがピンとこなかったんだけど、https://stackoverflow.com/a/44118856/1212807 を読んでからは default.nix に倒してる
このファイルを一々いじらなくても、ちょっと追加するだけなら nix-shell --packages theName
で済むのも快適。 asdf と conflict すると asdf が勝ってしまう(単にPATHの指定順次第かなと思ったんだけど、.asdf/shims がnixの個別指定より後に来たりする・・・)ので、面倒だから asdf の plugin をどんどん削り出している
https://github.com/kachick/times_kachick/issues/184#issuecomment-1396670990 常に bash で上げられてしまう事については、もう毎回 nix-shell --command 'zsh'
にしててそんなに困ってない。上げる時にちょっとひっかかるレベルのタイムラグがあるのは事実なんだけど、依存性管理の楽さが圧倒的に上回る。 POSIX に限定して~とか考えず、jq とか ripgrep とか imagemagic とか cargo-make とか普段使ってるツール群もサクッとリポジトリ単位で追加できるのが楽オブ楽
しかしそのままのノリで GitHub Actions で使おうと思えば使えるんだけど、公式のアクション使ってツール群入れるまでがまぁ時間かかる。ワンバイナリ系とか個別に使えば数秒のところが、全体とは言え2分以上とかかかるようになるとちょっと抵抗があって、元々コンパイルに時間がかかるような物でなければ CI では個別のアクションを使ったりしてる。正しくは無さそうだけど、今んとこ把握できてるのでこれが楽。。。
なんだかんだNix使いだして1年以上経過しているのに驚いた。特段大きな進歩はなくて、未だに読み書きすら覚束ない。 とはいえ流石に依存度が高いから必要に応じて都度調べるみたいなのの繰り返しである程度は使えるようになってきたんだけど、副作用というかで最近自分でも面白いのが「シェルスクリプトで済ませたくなる頻度が増えた」
ここ10年とかシェルスクリプトって基本敵視されているというか、構文のクセもそうだけど書きづらいしGNUとBSDスタイルどちらでも動くようにコマンドのオプションを調整して・・・みたいなのが厄介なのでなるべく書かない方が良いし、新規のものはシングルバイナリで配布し易いGoとかRustで書こうという流れだったと思うんだけど、Nixを使うとこの「どの外部コマンドが実行時に見えているかを厳密に指定出来る」のがガツンと効く。それはGoとかのワンバイナリな物からRubyみたいにコンパイルで引っかかりやすい物、それらを組み合わせて自分で書いた他のシェルスクリプトとかなんでもかんでも厳密に指定できる。 こうなってくると今度はグルー言語としての便利さに純粋に集中出来るようになってきて、1つの小さなシェルスクリプトで結構な事が済ませられるようになる。 Nixもそれは重々承知しているのかWriteShell~みたいな関数がいっぱい用意されていて、デフォルトで実行されるshellcheckやらベタ書きしなくてすむPATHのinject(Nix以外でも使い回ししやすくなる)、忘れないように setopt等含めて用意してくれるので便利
ということでなんか書く時に「あー、これNixとシェルスクリプトで1行だな」みたいな事を思う瞬間が増えた
尚 GitHub Actions 内で長めのシェルスクリプト書く度 🤮 になるので別に常にシェルスクリプトを書きたいみたいな欲求は無い(ここでベタ書きしないで Nix installer action 使って nix run 出来ると楽なのにー みたいな事は思うけど Nix のセットアップにかかるオーバーヘッドが微妙で避けがち)
言語系は気軽に最新版使いたいとか思ってると厳しい?
中央集権リポジトリに無くても自分で適当にフォークしたりして使える。しかしこれだとバイナリキャッシュを効かせるのが面倒なのと、複数の nixpkgs を取り回す面倒さが出てくる nixpkgs は普通にPR受け入れてくれるというか、規模が大きすぎて独裁なんか出来んわとコミュニティ主導感が強い。でも自分がそんなに詳しいわけでもない処理系とかツールのビルドに対するレシピを書いて僕これのメンテナになります(推奨されている)というのはちょっと度胸がいる 後マージされた後にメジャーなチャンネルへ更にバックポートされてバイナリキャッシュが効く状態になるまでのタイムラグは長め
慣れればアドホックなコードも書きやすくなってきて気軽に使えるけど、結局幸せになるためにはアップストリームへマージしてもらっていったほうが良いというのはどこでも同じっちゃ同じな気はする
どの外部コマンドが実行時に見えているかを厳密に指定出来る
Linux でも macOS でも大体はいける。 今のところ大きくハマったのは ps コマンドで、これが全然違うというかGNUの procps を BSD に持ってけない?っぽいのははーそうなんだという感じだった。オプションだけの話ではなく取れるものにも差があった。ゆとりなっくす世代なので意識せず生きてこれた しかし pkgs.procps と書いてエラー出ないのに内部で振り分けられてて実質 GNU に固定できないのは罠感強かった
https://github.com/NixOS/nixpkgs/blob/8dab54e2b3c4d0c946e1a24cad6bf23e552b2b36/pkgs/top-level/all-packages.nix#L28067-L28069 https://github.com/NixOS/nixpkgs/blob/8dab54e2b3c4d0c946e1a24cad6bf23e552b2b36/pkgs/os-specific/linux/procps-ng/default.nix#L13-L16 https://github.com/NixOS/nixpkgs/blob/8dab54e2b3c4d0c946e1a24cad6bf23e552b2b36/pkgs/top-level/unixtools.nix#L170-L176
devbox https://github.com/jetpack-io/devbox が流行りだした頃、まだ asdf とか *env とかでのバージョン管理に疲弊してるの・・・? と自分で自分に思った。 ということで、https://github.com/digitallyinduced/ihp でもガッツリ使われているらしいことから気になってた Nix https://github.com/NixOS/nix を使いだしてみた。devbox はラッパーっぽい雰囲気なのと必要性がまだあんま良くわかってないので保留
なるほど、サックリ固定バージョン同士の組み合わせを自分の環境に導入出来てめっちゃ便利! asdf だと先に chezscheme を導入しないといけない面倒さだった idris2 をサックリ入れられたのも嬉しい ( https://github.com/kachick/times_kachick/issues/201 はそこで引っかかった) CIの構築も楽なだけでなく、一定以上構成準備に時間がかかる場合は https://github.com/cachix/cachix 使うと速度向上も期待できそうだし
とは思ったんだけど、ガチガチに固めてるのと広範囲にカバーしてくれてる反面なのか最新版がなかなか中央集権リポジトリ?に無かったりする。 登場からほぼ一ヶ月経った Ruby も まだ 3.1 が最新だし、Crystal に至っては まだ 1年前の 1.2 で止まってる。PRを出してくれている方は居るんだけど、なかなかマージに至るまでが大変そう https://github.com/NixOS/nixpkgs/pull/195606 そもそも4500以上のPRが滞留してるし・・・ crystal 自身もビルドに Nix 使ってるみたい https://github.com/crystal-lang/crystal/blob/62b0adecc4cdfb4c84632a8f329d48983da97c6c/shell.nix だし、便利なのは間違いないと思うんだけど用途次第なんだろうなぁ 自分で定義すれば良いとは言え、気軽に出来るかというとちと大変そう