GOPATHの運用を見なおしてみたら意外と便利だった

f:id:dojineko:20160909000527j:plain

go-get と ghq (+ fzf/peco) の連携 はとても便利

社内でGoの機運が高まっているようなので、
整理を兼ねてこれまでかじって適当に作った環境をみなおしてみました。

Goの環境を設定するというとやっぱり気になるのは $GOPATH の設定。(そうでもない?)
「GOPATHはどこでもええんやで」という解説でサラリとさきに進んでいるけども、
これがどうにもしっくり来ませんでした。

普段Gitリポジトリの管理には motemen 氏作の ghq を活用しています。
fzf や peco と組み合わせるとこれがとても便利です。

最初環境を作った時、GOPATH と ghq管理のディレクトリをあえて下記のように分けていました。

- ~/Documents/
    - ghq/ # ghq管理のディレクトリ
        - github.com
        - bitbucket.org
    - go/ # GOPATHで指定したディレクトリ
        - src/
            - github.com
        - pkg/
        - bin/ # 実行ファイルが入るのでPATHを通す

このディレクトリ構成の問題は、 ghq管理下で Goのライブラリを書いて、
作ったライブラリを実際に使おうとした時、すでにghq配下にソース一式があるのに、
別途 go get しないといけないということです。

もしくは ghq 管理下のリポジトリへのシンボリックリンク$GOPATH/src/ 配下に設定してあげる必要があります。
多重管理感が否めない運用になってしまっていました。どうしよう。

「きっと先人がいい解決策を見出しているに違いない」ということで下記のエントリにたどり着きました

blog.kentarok.org

なるほど幸いなことに $GOPATH/src 配下と ghq 管理下のディレクトリ構成が同じということだそうな。
なので、ghqの管理下とするディレクトリを $GOPATH/src にしてあげると都合が良いみたい。

最初見た時「え〜・・・ghq配下に gitリポジトリ以外が入るのやだなぁ」と思っていたのですが、
まさかと思ってみてみたら、$GOPATH/src 配下のディレクトリはすでに git clone された状態でそこにいたのでした。

なるほど、それなら混ぜてしまってもそんなに問題にならなそうかなとはおもいつつ、
go get している時に何が起こっているのかを調べてみました。

ためしにGoのクロスコンパイルお助けツール gox を例に go get してなおしてみました。
go の標準コマンド系は大体 -x をつけると何をするか表示してくれるみたいです。

# go get すると・・・ (-x で実行するコマンドを確認できる)
go get -x github.com/mitchellh/gox

# リモートリポジトリをCloneしてSubmoduleも持ってくる
cd .
git clone https://github.com/mitchellh/gox /Users/Dojineko/Documents/Works/src/github.com/mitchellh/gox
cd /Users/Dojineko/Documents/Works/src/github.com/mitchellh/gox
git submodule update --init --recursive
cd /Users/Dojineko/Documents/Works/src/github.com/mitchellh/gox
git show-ref
cd /Users/Dojineko/Documents/Works/src/github.com/mitchellh/gox
git submodule update --init --recursive

# go build する
WORK=/var/folders/c7/0gmg4zcx4w94q_164qrqd_s40000gp/T/go-build617552209
mkdir -p $WORK/github.com/mitchellh/gox/_obj/
mkdir -p $WORK/github.com/mitchellh/gox/_obj/exe/
cd /Users/Dojineko/Documents/Works/src/github.com/mitchellh/gox
/usr/local/Cellar/go/1.7/libexec/pkg/tool/darwin_amd64/compile -o $WORK/github.com/mitchellh/gox.a -trimpath $WORK -p main -complete -buildid 080a157dd1f358e3a4b8d51aad521493bb2a7fb4 -D _/Users/Dojineko/Documents/Works/src/github.com/mitchellh/gox -I $WORK -I /Users/Dojineko/Documents/Works/pkg/darwin_amd64 -pack ./env_override.go ./go.go ./main.go ./main_osarch.go ./platform.go ./platform_flag.go ./toolchain.go
cd .
/usr/local/Cellar/go/1.7/libexec/pkg/tool/darwin_amd64/link -o $WORK/github.com/mitchellh/gox/_obj/exe/a.out -L $WORK -L /Users/Dojineko/Documents/Works/pkg/darwin_amd64 -extld=clang -buildmode=exe -buildid=080a157dd1f358e3a4b8d51aad521493bb2a7fb4 $WORK/github.com/mitchellh/gox.a
mkdir -p /Users/Dojineko/Documents/Works/bin/

# 実行ファイルなら成果物を $GOPATH/bin に移動する
mv $WORK/github.com/mitchellh/gox/_obj/exe/a.out /Users/Dojineko/Documents/Works/bin/gox

もう一度書き出すと、

  1. go get を実行
  2. リモートリポジトリをCloneしてSubmoduleも持ってくる
  3. go build する
  4. 実行ファイルなら成果物を $GOPATH/bin に移動する

という流れ。

動きとしてはリポジトリをCloneして、後でghq管理下に入れるのと全く同じ。 そのため $GOPATH/srcghq 管理のディレクトリにしても問題になりにくいということですね。

ということでさっくりと ghq 配下のディレクトリを $GOPATH/src に移動して、所々設定を適宜変更。
シャッキリポン(?)と多重管理を解消するに至りました。

# 下記のようにディレクトリを再構成
- ~/Documents/
    - Works/ # GOPATHで指定したディレクトリ
        - src/ # ghq管理のディレクトリ
            - github.com
            - bitbucket.org
        - pkg/
        - bin/ # 実行ファイルが入るのでPATHを通す
# .zshrc .bashrc などで設定しているはずの GOPATHを変更する
GOPATH=~/Documents/Works 
# .gitcofig の ghqの設定を $GOPATH/src なディレクトリに変更する
[ghq]
    root = ~/Documents/Works/src

あとはいつもどおり、

  • Goパッケージなら go get で取得
  • 自作のGo パッケージを build したいなら go buildコンパイル
  • go get したコードの中身を見てみたいなら他のリポジトリと同じくghq + fzf / peco

というシンプルな流れを作るに至りました (∩´∀`)∩ワーイ


関連リンク

www.pakutaso.com

blog.kentarok.org

motemen.hatenablog.com