ghqによるGoのプロジェクト管理 & プロジェクト毎で外部モジュール管理

# GOPATH問題
```
$ cd ~/Documents/go/hoge
$ tree .
.
├── main.go
└── redis
    ├── redis.go
    └── redis_test.go
$ cat main.go
package main

import (
	"./redis"
)

func main() {
...
}
```
上記のようなmain.goのimport文はGoのお作法的にアウト。ただ、コンパイルも実行も可能。

お作法的には、import文にはgithub.com以下から記述するべき。

```
$ cat main.go
package main

import (
	"github.com/kosuda/hoge/redis"
)

func main() {
...
}
```

上記のようなディレクトリ構成にするためには$GOPATH/src/github.com/kosuda/hogeにしなくてはいけない。

**つまり、好きな場所にディレクトリ作って開発的なことは避けるべき**

**外部モジュールも含めてすべてGOPATH以下に含めるべき**

そこで、なんかプロジェクトを管理する上でうまいやりかたないかなーと思い、以下調査結果。ついでに、依存関係の管理手法も。

# ghq + direnv + godep

+ [ghq](https://github.com/motemen/ghq)    : go製のgit module管理
+ [godep](https://github.com/tools/godep)  : dependency management tool
+ [direnv](https://github.com/zimbatm/direnv) : go製のディレクトリ毎で環境変数を管理するやつ

## 1. ghq
#### - インストールあんど設定
```
$ go get github.com/motemen/ghq
$ cat ~/.gitconfig
[ghq]
    root = ~/.go/src
...
```
ghqをgo getしたらgitconfigにghq.rootを追加すればおｋ

#### - 使い方
```
$ ghq list
… <= ghq.root以下に含まれているリポジトリの一覧表示
$ ghq look ghq
        cd /Users/a13486/.go/src/github.com/motemen/ghq
↑　ghq.root以下にあるディレクトリにcdできる。
```

ただ、ここで注意しなくてはいけないのが、ghq lookで移動するとシェルを再度実行するのでプロセスが増えるお。まぁそこまで気にすることはないんですが、僕は結構exitとかしてウィンドウ閉じることが多いのであれ？って感じになった。

理由は簡単。

```
#!/usr/bin/env bash
cd ~/test
ls
```

上記のようなスクリプトを実行しても~/testに移動しないのと一緒で~/testに移動するにはシェルを実行する必要があるのと一緒。

```
#!/usr/bin/env bash
cd ~/test
ls
/usr/bin/env bash
```

## 2.godep
#### - インストール
```
$ go get github.com/tools/godep
```

使ってみた。

```
$ tree .
.
├── README.md
├── main.go
└── redis
    ├── redis.go
    └── redis_test.go

$ godep save
$ ls
Godeps/    README.md  main.go    redis/
$ ls Godeps/
Godeps.json  Readme       _workspace/
$ cat Godeps/Godeps.json
{
	"ImportPath": "github.com/kosuda/benchmark",
	"GoVersion": "go1.3",
	"Deps": [
		{
			"ImportPath": "github.com/garyburd/redigo/redis",
			"Rev": "6628c86d6a89ce7983c7c9b5e98c1df795fbd256"
		}
	]
}
```
おー、これで依存関係の管理がスッキリする。

ただし、これも注意しなくてはいけないのが必ず、以下の条件を満たすこと


**+ VCSによって管理されていること**

**+ $GOPATH/src/{hosting service name}/{user name}/hogehogeという構成であること**

## 3. 何がうれしい？
これで、ghq.rootにGOPATHを含めることで、ghq getで開発リポジトリを＄GOPATHにもってきて開発みたいなことが可能。さらにgodepsがあるので、godeps getをそのリポジトリですれば自動で外部モジュールをインストできる。gpm (npmみたいな名前)　というのもあったんだけど、godep saveみたいな自動で依存関係を抽出してファイルを作るというのが貧弱だったのでやめた。

## 4. うれしくないこと
どうしてもパッケージをすべてグローバルにインストするというのが気持ちわるい。それぞれのパッケージ内で管理してほしい。node_modules的なやつ。

## 5. direnv

```
brew install direnv
```

使い方とかは以下の記事が参考になった。

http://qiita.com/kompiro/items/5fc46089247a56243a62

では、早速使ってみる

```
$ ghq look hoge

$ direnv edit .
direnv: loading .envrc
direnv: export ~GOPATH
$ cat .envrc
export GOPATH=$(pwd)/vendor/:$GOPATH
$ echo $GOPATH
vendor/が入っていることを確認

$ go get github.com/garyburd/redigo/redis
$ tree .
.
├── Godeps
├── README.md
├── main.go
├── redis
│   ├── redis.go
│   └── redis_test.go
└── vendor
    ├── pkg
    └── src
        └── github.com
            └── garyburd

```

これでいい感じ。

以下、色々と確認作業。

```
$ rm -rf Godeps
$ godep save <= ちゃんとredigo/redisのやつがはいってる
$ rm -rf vendor
$ godep get <= vendorの中に入ってくれる
$ cd ..
$ echo $GOPATH
vendor/が外れて.zshrcに設定したGOPATHのみになっている
```

ということで、これでパッケージをそれぞれのプロジェクトで管理できるようになりました。ちなみに、direnvでgopathが変わってるときにghq getをしてもvendorには入らないのでgo getする。開発者が新たに追加するときに注意が必要。

# ちなみに、Docker projectの場合

hack/make.shでvendor/:.gopath/src:$GOPATH的な感じで作って、srcのリンクを.gopath以下のとこに作り、hack/vendor.shで外部モジュールをvendorディレクトリにcloneしてくるみたいな作りで依存関係の管理をしてる模様。詳細はhack/packager.mdとかhack/vendor.shとかhack/make.shとか読めば分かる。まださらっと読んだだけなので間違ってるかも。

**↑↑これは全然センスが感じられませんでした＼(^o^)／**