direnvを使ってGo開発をいい感じにする
GOPATH以下が汚くなってません?
以下のような感じで、GOPATH
を設定して開発をしていると・・・
export GOPATH=$HOME/go export PATH=$PATH::$GOPATH/bin
ghqでリポジトリを一括で管理しているので、探すのに困ることはありませんが
352個もソースがありました。こういうことをずっとしていると、自分の環境だけで動くみたいなソースになっていることに気づけなかったりします。あと、Goglandのindexing終わらない事案とか・・・w
また、仕様としてimport
が以下のなるのですが、リポジトリ名やユーザーが変わると全滅するソースになったりします。一応GOPATH
をプロジェクトごとに設定すれば解決出来ますが、それは正直面倒ですよね?それを解決してくれるのが、direnv
です
package main import "github.com/pei0804/direnv-example/sample" func main() { sample.Sample() }
やりたいこと
import
を必要最低限だけ記述したい- 必要なパッケージだけを
GOPATH
以下に入れたい GOPATH
を動的にいい感じに設定したい
package main import "app/sample" func main() { sample.Sample() }
package sample import "fmt" func Sample() { fmt.Println("Hello World") }
最終的に上記のようなコードで動作させます。
direnvを使ってGOPATHをいい感じにする
direnv is an environment switcher for the shell. It knows how to hook into bash, zsh, tcsh and fish shell to load or unload environment variables depending on the current directory. This allows project-specific environment variables without cluttering the ~/.profile file.
つまり、シェルの環境変数いい感じ適用するぜ!
では、READMEにあるように、シェルそれぞれに合った設定をしてください。
自分はzsh
なので、以下の記述を追加しました。
# ~/.zshrc eval "$(direnv hook zshrc)"
とりあえず動かす
$ git clone https://github.com/pei0804/direnv-example.git <--- あえてgit cloneで適当に配置する $ cd direnv-example $ make direnv direnv allow direnv: loading .envrc direnv: export ~GOPATH $ make run go run main.go Hello World
上記の手順で動いたと思います。 これでどこでも動かせる+必要なパッケージのみのクリーンな環境が出来ました。 ちなみにファイル構成は以下のような感じです。
. ├── LICENSE ├── Makefile ├── README.md └── go └── src └── app ├── Makefile ├── main.go └── sample └── sample.go
シェルに設定していないGOPATHが正しく動作した理由は、.envrv
の記述にあります。
内容は簡単なもので、今いる場所/go
で新たなGOPATH
を追加しているだけです。
export GOPATH=$(pwd)/go:$GOPATH
この操作で、さっき追加したソースはGoのルールに乗っ取り正しく構成されたソースになります。自分は最近この手法で開発するケースが増えています。特にDockerベースの開発をする時は、この手法がとてもマッチしてていい感じです。(また後日記事にします) ちなみに、最近いい感じになってきているgolang/depは、こういう構成で開発することを想定しているっぽいです。