pipenv を conda のように使う
pipenv
はディレクトリごとにPipfileおよびPipfile.lockを作成し、ディレクトリ単位で仮想環境を管理する。
この管理方法はプロジェクトなどにおいては非常に理にかなっている。
まっさらな状態から、プロジェクトに必要なパッケージだけを入れるだけで良いからだ。
しかし、普段からちょっとしたことでもPythonにやらせる場合にはこの管理方法は少し使いにくい。
そこで任意の場所で共通の環境を使えるように、Pipfileを管理するためのディレクトリを作成し、その場所にpipenv shell
する関数を作成する。
こうすることで、conda activate hoge
と同様のことが実現できる。
準備
まずはパスの設定やディレクトリの作成を行う。
また、ここではzsh
を対象とする。
Pipfileを保管するディレクトリを作成する。
ここでは、ホーム直下の.pipenvenv
に保管することにする。
$ mkdir ~/.pipenvenv
作成したディレクトリへのパスを作成しておく。
パスの設定は.zshenv
に記述しておく。
echo 'export $PIPENV_ENV_ROOT=$HONE/.pipenvenv' >> ~/.zshenv
次に自作関数のオプションなどを補完するための補完関数を置くディレクトリを用意する。
ここでは、~/.zsh-function
というディレクトリを作成し、そこに補完関数を置く。
mkdir ~/.zsh-function
zsh
の補完関数を場所を示す環境変数は$fpath
であるので、作成したディレクトリへのパスを追加する。
echo 'fpath=($HOME/.zsh-function $fpath)' >> ~/.zshenv
関数の作成
自作コマンドはシェルスクリプトとして作成した方がいい気もするが、ここでは.zshrc
に直接記述することにする。
function gpipenv() { ERROR_STATUS=1 if [ $# -lt 2 ]; then echo "Usage: gpipenv command env_name [package]" return $ERROR_STATUS fi ENV_PATH="$PIPENV_ENV_ROOT/$2" if [ $1 = "create" ]; then if [ -d $ENV_PATH ]; then echo "same environment name already exists!" return $ERROR_STATUS else (mkdir $ENV_PATH && cd $ENV_PATH && pipenv install) fi elif [ $1 = "install" ]; then if [ $# -eq 3 ]; then if [ -d $ENV_PATH ]; then (cd $ENV_PATH && pipenv install $3) else echo "env '$2' does not exists!" return $ERROR_STATUS fi else echo "Usage: gpipenv install env_name package_name" return $ERROR_STATUS fi elif [ $1 = "activate" ]; then if [ -d $ENV_PATH ]; then (cd $ENV_PATH && pipenv shell) else echo "the environment does not exists!" return $ERROR_STATUS fi else echo "illegal command!" return $ERROR_STATUS fi }
conda
でいうところのconda create
, conda install
およびconda activate
に相当する処理を行う関数gpipenv
を作成した。
conda deactivate
に相当する処理も書きたかったが、面倒なので煩雑になりそうだったのでCtrl-D
で行うことに。
余談
gpipenv shell
を行うとディレクトリ移動してしまうのが難点。
なんとかならないものか。
補完関数の作成
これで終わりでもいいのだが、コマンドの種類、構築した仮想環境の名前を忘れると、いちいち.zshrc
や仮想環境ディレクトリを確認しなければならない。
それは少し不便なのでzsh
の補完関数を作成する。
zsh
の補完関数は_関数名
という名前で作成する。
補完関数は先程準備した~/.zsh-function
に配置する。
今回は自作関数gpipenv
の補完関数ファイルを_gpipenv
として作成する。
#compdef gpipenv _gpipenv() { _arguments '1: :->command' '2: :->env' case "$state" in command) _values '' \ 'create[Create new virtual environment.]' \ 'install[Install new package to specified virtual environment.]' \ 'activate[Spawns a shell within the virtualenv.]' ;; env) _path_files -/ -W $PIPENV_ENV_ROOT ;; esac }
1行目の#compdef gpipenv
はgpipenv
に関する補完関数であることを明示するものなので必須である(多分)。
これで補完を行えば以下のように補完される。
$ gpipenv [ここでTAB] activate -- Spawns a shell within the virtualenv. create -- Create new virtual environment. install -- Install new package to specified virtual environment.
$ gpipenv activate [ここでTAB] base/ hoge/ fuga/