はじめに
この記事は フューチャーAdvent Calendar 2020 の20日目の記事です。
環境構築に便利な〇〇env系ツールを、もっと便利に扱える anyenv
に感動したので、ブログ化しました。
開発言語のバージョン管理
複数プロジェクトに関わる場合、開発言語のバージョン管理は必須スキルです。
他の開発メンバーと利用バージョンを一致させなければ、フォーマッタ適用 → PRでの差分爆発が生じてレビュアーに袋叩きにされます。
なので、各エンジニアはそれぞれの創意工夫により、開発言語のバージョン管理問題を解決しています。
私の場合、環境構築ポリシーとして
- ローカル環境への直ダウンロードは厳禁
- 環境構築は基本的にDockerを使う
という方針を、ずっと貫いています。
...
スミマセン。強がりです。
貫けていませんでした。
〇〇env の多用
コロナ影響で在宅勤務へ移行した結果、NWの問題によりDockerがうまく使えない状況が増え、仕方なく〇〇env系ツールの利用を開始しました。
インストールした〇〇env系ツールは
- PJ開発はメインでgoを使う → goenv
- 環境Aはpythonのみ動く → pyenv
- 環境Bはrubyのみ動く → rbenv
- AWSのMFA(多要素認証)でet-otpを使う → jenv
というもので、開発作業で新しい言語が必要になるたびに、対応するツール1つ1つ追加していました。
これらは同じコマンド操作で設定可能なため、ストレスになるのはパッケージのダウンロード時間くらいだと思っていましたが、知らぬ間に開発環境汚染が進んでいました。
bash_profileが汚れていた
担当業務で Vue.js のコードに触れる機会があり、新たに nodenv
をインストールしようとしたところ
- 〇〇env系ツールの環境構築って、いっつも同じような環境変数を追加しているな
- bash_profileのメンテしてたっけ?
ということに気づき、cat ~/.bash_profile すると、↓こんな感じになっていました
...
# goenv
export GOENV_ROOT=$HOME/.goenv
export PATH=$GOENV_ROOT/bin:$PATH
eval "$(goenv init -)"
# pyenv
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
# jenv
export JENV_ROOT=$HOME/.jenv
export PATH="$HOME/.jenv/bin:$PATH"
eval "$(jenv init -)"
(rbenv, nodenv などの設定が続く...)
...
あれ?
開発環境が汚れないよう注意していたはずなのに
所々で微妙な違いがあり、綺麗な状態とは言い難い...
〇〇env系ツールが増えるごとに
bash_profileに追記し続けるのを止めたい
...
anyenv が便利そう!
anyenvを使って綺麗にする
anyenv自体の説明前に、このツールを使うと何が綺麗になるか?から説明します。
すでにインストール済みのgoenv, pyenvなどはanyenv経由での再設定が必要になりますが、それを乗り越えれば、bash_profile に必要な 〇〇env系ツールの記述
は、以下のみで十分となります。将来的に新しい 〇〇env が必要になった場合でも、bash_profile への追記は不要です。
...
# anyenv
eval "$(anyenv init -)"
...
goenv, jenvごとにPATHを設定 & initする煩わしい記述から解放され、かつ、操作方法は従来の〇〇env系コマンドを利用可能なので、開発環境汚染を少しでも減らしたいエンジニアであれば、このツールを使わない理由は無いと思います。
anyenvとは?
anyenv - All in one for **env
This is a simple wrapper for rbenv style environment managers. You don't have to git clone or modify your shell profile for each **env anymore if you install anyenv.
端的に言うと、複数の〇〇envを一括管理できる便利ツールです。
執筆時点(2020.12.10)では、以下〇〇envパッケージがanyenvでは利用可能です。
有名どころは網羅しているので、多くの開発プロジェクトで導入可能だと思います。
$ anyenv install -l
Renv #R
crenv #Crystal
denv #D
erlenv #Erlang
exenv #Elixir
goenv #Go
hsenv #Haskell
jenv #Java
jlenv #Julia
luaenv #Lua
nodenv #Node.js
phpenv #PHP
plenv #Perl
pyenv #Python
rbenv #Ruby
sbtenv #Sbt
scalaenv #Scala
swiftenv #Swift
tfenv #terraform
上記から欲しい言語をインストールすれば、あとはいつも通りの〇〇env操作コマンドで環境構築可能です。
anyenvのインストール手順
macの場合
Homebrewを利用します。
$ brew install anyenv
$ echo 'eval "$(anyenv init -)"' >> ~/.bash_profile
$ exec $SHELL -l
$ anyenv install --init # enter "y"
Linux環境の場合
GitHubから直接引っ張ってきます。
$ git clone https://github.com/anyenv/anyenv ~/.anyenv
$ echo 'export PATH="$HOME/.anyenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(anyenv init -)"' >> ~/.bash_profile
$ exec $SHELL -l
$ anyenv install --init # enter "y"
最後に $ anyenv install 〇〇env
で欲しいパッケージを取得すれば、これまで通りの〇〇envコマンドが利用できます。
ex) node.jsのv15.0.1が欲しい場合
anyenvを利用し、nodenvを取得します。
$ anyenv install nodenv
$ exec $SHELL -l
$ anyenv versions
nodenv:
Warning: no Node detected on the system
次は、nodenvでv15.0.1を取得します。
$ nodenv install 15.0.1
$ nodenv global(local) 15.0.1
$ node -v
v15.0.1
以上により、Node.js:v15.0.1 が利用可能となりました。
私の開発では goenv, pyenv, jenv, nodenv が必須なので、以下の設定を入れています。
$ anyenv versions
により、各envの設定状況が一覧できます。
$ anyenv versions
goenv:
system
1.XX.0
* 1.YY.0 (set by /Users/<username>/.anyenv/envs/goenv/version)
jenv:
system
* XX.0 (set by /Users/<username>/.anyenv/envs/jenv/version)
nodenv:
system
* XX.0 (set by /Users/<username>/.anyenv/envs/nodenv/version)
pyenv:
system
XX.0
* YY.0 (set by /Users/<username>/.anyenv/envs/pyenv/version)
anyenvインストール以前に設定したgoenvやpyenvの環境変数が残っている場合は、bash_profileから削除することも忘れないようご注意ください。
まとめ
- 環境変数、
echo 'export hogehoge"' >> ~/.bash_profile
で追加したまま放置していませんか - 複数の〇〇env系ツールを使っているなら、anyenvの利用がオススメ
- anyenvでbash_profileがスッキリ