GOPATH
問題
Gophers!
周知のようにgoはGOPATHで依存パッケージをどこにインストールするか決められます。
入門記事などでは、~/.bashrc
や~/.zshrc
の中で
export GOPATH=$HOME/gocode
または
export GOPATH=$HOME
とすることが多いようです。
しかし、GOPATHを各プロジェクトのパッケージが混ざるので、
- 同じパッケージの異なるバージョンを同時にインストールできない
- 変なことをすると、全プロジェクトが巻き添えになる
- どれが不要なパッケージか分からなくなる
という欠点があります。
そこでdirenv
direnvを使うと、プロジェクトごと(ディレクトリごと)にGOPATH
を分ける事ができます。
direnvのインスト―ルと基本的な設定
# HOMEにインストール
$ git clone http://github.com/zimbatm/direnv
$ cd direnv
$ make install DESTDIR=$HOME
# .bashrcに追加
$ echo 'eval "$(direnv hook bash)"' >> ~/.bashrc
例:
# fooプロジェクトの開発専用ディレクトリを作る
# src以下に、プロジェクトのレポジトリをインストール
$ git clone git://github.com/doloopwhile/foo ~/gocode-foo/src/github.com/doloopwhile/foo
# ディレクトリでdirenvの設定
$ cd ~/gocode-foo
$ echo 'layout go' > .envrc
.envrc
がdirenv用の設定ファイルです。
cd すると、自動でGOPATHがセットされます!
$ cd ~ && cd ~/gocode-foo/
direnv: loading ~/.direnvrc
direnv: loading .envrc
direnv: export +GOPATH ~PATH
$ echo $GOPATH
/home/taro/gocode-foo
# ~/gocode-foo/src/ 以下に依存パッケージがインストールされる。
$ go get -t ./...
楽になりましたね!
もっと楽にする
ところで、.envrc
にlayout go
を書いただけでは、
~/gocode-foo/src以下には、プロジェクト本体と依存パッケージが区別なく置かれてしまいます。
そこで direnv edit .
で .envrc
に設定を追加します。
$ cd ~/gocode-foo
$ direnv edit .
(エディタが起動するので以下を記入)
layout go
path_add GOPATH .direnv/gocode
すると、依存パッケージは~/gocode-foo/.direnv/gocode
にインストールされるようになります。
.envrc
には他にも専用コマンドがあり、普通のシェルコマンドも書けます。
たとえば、PATH
をいじって、使うgo
コマンドのバージョンを切り替えたりもできるでしょう。
https://github.com/zimbatm/direnv/blob/master/man/direnv-stdlib.1.md
ちなみに~/.bashrc
などでGOPATH
を指定していても、ディレクトリ固有のパスが優先されます。
なので、~/.bashrc
にはexport GOPATH=~/gocode
を書いておき、
- プロジェクト用のパッケージは
.envrc
に指定した~/gocode-foo/.direnv
にインストール - プロジェクトに無関係な日曜的なツール類は
~/gocode
にインストール
と、使い分ければいいと思います。
ちなみに
direnvはシンボリックリンクの問題があり、リンク経由だと、.envrc
が読み込まれません。
# 本来のパスを指定すると読み込まれる
$ cd ~/gocode-foo/src/github.com/doloopwhile/foo/
direnv: loading ~/.direnvrc
direnv: loading ../../../../.envrc
direnv: export ~GOPATH ~PATH
$ ln -s ~/gocode-foo/src/github.com/doloopwhile/foo/ ~/foo
# シンボリックリンクだと読み込まれない
$ cd ~/foo
direnv: loading ~/.direnvrc
direnv: loading ../../../../.envrc
/bin/bash: line 133: ./.envrc: No such file or directory
一応、forkしたレポジトリではシンボリックリンクに対応させており、本家にプルリクエスト中です。
ですので、forkを使うか(自己責任)、マージされるまで待ってください。
Gophers!