Go言語のパッケージ管理ツールのDepとModulesの違いについて調べた内容をここにまとめました。
少しでもご参考になれば幸いです。
まず始めにGOPATHについて
Goを初めて触った頃に、困ったことがありました。それはパッケージの管理でした。
プライベートでの開発時のGOPATHの設定は$HOME/go
して、参画していた案件に関しては$HOME/hogehoge-project/go/
みたいな感じでGOPATHを分けていました。
分けていた理由としてはやはり依存しているパッケージのバージョンに違いなどがあったからです。
例えば
$HOME/go/src/github.com
go
└── src
├── github.com
│ ├── my-github-repos
│ │ ├── csv_sample
│ │ ├── image_example
│ │ └── test_code
│ ├── codegangsta
│ │ ├── envy
│ │ └── gin
│ ├── davidrjenni
│ │ └── reftools
│ ├── derekparker
│ │ └── delve
│ ├── fatih
│ │ ├── gomodifytags
│ │ └── motion
│ ├── go-delve
│ │ └── delve
│ ├── golang
│ │ └── dep
│ ├── golangci
│ │ └── golangci-lint
│ ├── josharian
│ │ └── impl
│ ├── json_sample
│ ├── jstemmer
│ │ └── gotags
│ ├── kisielk
│ │ └── errcheck
│ ├── klauspost
│ │ └── asmfmt
│ ├── mattn
│ │ └── go-shellwords
│ ├── mdempsky
│ │ └── gocode
│ ├── rogpeppe
│ │ └── godef
│ ├── stamblerre
│ │ └── gocode
│ └── zmb3
│ └── gogetdoc
go/src/github
配下に依存パッケージがインストールされます。
ここで問題なのが、my-github-repos/csv_sample
とother-github-repos/image_sample
でginというGoフレームワーク使っている場合、~/go/src/github.com/codegangsta
を共通で利用するので、各々で異なるバージョンを指定できないのが問題でした。
こういった問題があるので、私はそのプロジェクト用にGOPATHを新たに作成していました。
# fish
set -x GOPATH "$HOME/go:$HOME/hogehoge-project/go"
Goを使用したプロジェクトが増えていくたびに、GOPATHも追加していくという悪循環に陥る。(個人的に好きじゃなかった)
しかもgo get
を使用すると、デフォルトでGOPATHを最初に指定したディレクトリにインストールされたりと、いろいろ面倒だったり。
dep
当時(たしかGOのバージョンが1.10ぐらいの時)、パッケージのバージョン管理をどうしようかなっと思って、ググって調べました。そうするとGOのパッケージ管理ツールでDepというものに出会いました。
vendor配下にパッケージがインストールされて・・・・うんにゃらかんにゃら。
どの言語でもよくみるやつですね。「これは便利そう」というが率直な感想でした。
$ cd ~/go/src/github.com/hogehoge-project/gorm_sample/vendor
$ tree -d -L 2
.
├── github.com
│ ├── go-sql-driver
│ └── jinzhu
└── google.golang.org
└── appengine
Go Modules
Go 1.11から外部パッケージとしてGo Modulesが使えるようになりました。
Go Modulesが出てくるまでの依存パーケージ管理と言えば、dep一択だったかなと個人的には思ってましたが、depを使わずにこちらを使用されることが増えている印象を受けました。
実際にGo言語で開発していた案件に参画した時もDepを利用されていました。Goのバージョンも当時は1.10とかでしたね。
$ cd ~/go/src/github.com/hogehoge-project
$ go mod init
$ go get github.com/labstack/echo@v2
$ cd ~/go/pkg/mod/github.com/labstack
$ tree -d L 1
.
├── echo@v2.2.0+incompatible
└── gommon@v0.3.0
$ cd ~/go/src/github.com/fugafuga-project
$ go mod init
$ go get github.com/labstack/echo/v4
$ cd ~/go/pkg/mod/github.com/labstack
$ tree -d -L 1
.
├── echo
├── echo@v1.4.4
├── echo@v2.2.0+incompatible
├── echo@v3.3.10+incompatible
└── gommon@v0.3.0
上記のようにバージョン毎のリポジトリがインスールされる
そして各々のプロジェクトにあるgo.mod
というファイルがモジュールを管理しており、
importする際はこの ~/go/pkg/mod/
配下にあるモジュールを使うようになります。
最後に
最近よく、depからGo Modulesに移行されている記事が目立つようになってきました。
私自身もGo Modulesについて知ったばかりなので深く掘り下げた内容ではなく、ざっと簡単な説明にはなりましたが参考になれば幸いです。