お題
表題について確認する。主に以下の人が対象。
★今まで「glide」や「dep」を使ってて、Go1.11でModulesを使い始めたものの違いに戸惑っている人。
これまでの「glide」や「dep」といったVendoring方式のツールがどんなだったかは下記参照。
Goとvendoring
Go 1.11 における Modules の概念については以下に載っている。
https://github.com/golang/go/wiki/Modules#go-111-modules
上記の冒頭文によると、
Go 1.11 において Modules は、あくまで実験的に導入したものである。
フィードバックを踏まえ、Go 1.13 で完成する。
下位互換は持たせるので Go1.11 及び Go 1.12 で作られた Module が Go 1.13 で使えなくなるということは無い。
とのこと。
プロダクションレベルで導入すべきかどうかは、判断の分かれるところだろう。
ちなみに上記のWikiから、主にチュートリアル部分を抜粋して試した記事が下記。
Go 1.11 Modules
今回は、表題についての確認。
開発環境
# OS
$ cat /etc/os-release
NAME="Ubuntu"
VERSION="18.04.2 LTS (Bionic Beaver)"
# Docker
$ sudo docker version
Client:
Version: 18.09.2
API version: 1.39
Go version: go1.10.4
Git commit: 6247962
Built: Tue Feb 26 23:52:23 2019
OS/Arch: linux/amd64
Experimental: false
Server:
Engine:
Version: 18.09.2
API version: 1.39 (minimum version 1.12)
Go version: go1.10.4
Git commit: 6247962
Built: Wed Feb 13 00:24:14 2019
OS/Arch: linux/amd64
Experimental: false
# Golang
$ go version
go version go1.11.4 linux/amd64
実践
自前端末の環境に依存しないよう、dockerhubの公式イメージを使う。
■ Go 1.11 の公式イメージを取得
docker login
docker loginする。
【参考】
http://docs.docker.jp/docker-hub/accounts.html
$ sudo docker login
〜〜〜
Login Succeeded
docker search
【参考】
https://hub.docker.com/_/golang
$ sudo docker search golang
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
golang Go (golang) is a general purpose, higher-lev… 2614 [OK]
〜〜〜
docker pull
$ sudo docker pull golang:1.11
1.11: Pulling from library/golang
〜〜〜
Status: Downloaded newer image for golang:1.11
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
golang 1.11 28daaf3edbdb 2 weeks ago 756MB
docker exec
$ sudo docker run -it golang:1.11
root@3c5e824d4a2d:/go#
■ 適当なWebAPIを実装
前段で docker exec
した状態からの作業。
GOPATH
外にソース置き場を作成
root@3c5e824d4a2d:/go# pwd
/go
root@3c5e824d4a2d:
root@3c5e824d4a2d:/go# env | grep GOPATH
GOPATH=/go
root@3c5e824d4a2d:
root@3c5e824d4a2d:/go# mkdir /usr/local/src/gowork
root@3c5e824d4a2d:/go# cd /usr/local/src/gowork/
GOPATH
外のソース置き場に自前以外のモジュールを使うWebAPIを実装
root@3c5e824d4a2d:/usr/local/src/gowork# cat <<EOF > main.go
> package main
>
> import (
> "net/http"
>
> "github.com/labstack/echo"
> )
>
> func main() {
> e := echo.New()
> e.GET("/item", func(c echo.Context) error {
> return c.JSON(http.StatusOK, "OK")
> })
> e.Logger.Fatal(e.Start(":8080"))
> }
>
> EOF
root@3c5e824d4a2d:/usr/local/src/gowork#
root@3c5e824d4a2d:/usr/local/src/gowork# cat main.go
package main
import (
"net/http"
"github.com/labstack/echo"
)
func main() {
e := echo.New()
e.GET("/item", func(c echo.Context) error {
return c.JSON(http.StatusOK, "OK")
})
e.Logger.Fatal(e.Start(":8080"))
}
root@3c5e824d4a2d:/usr/local/src/gowork#
Go Module初期化
root@3c5e824d4a2d:/usr/local/src/gowork# go mod init gowork
go: creating new go.mod: module gowork
root@3c5e824d4a2d:/usr/local/src/gowork#
root@3c5e824d4a2d:/usr/local/src/gowork# cat go.mod
module gowork
Webアプリの起動確認
起動時にソースの内容を元に、必要なモジュールをダウンロードする。
root@3c5e824d4a2d:/usr/local/src/gowork# go run main.go
go: finding github.com/labstack/echo v3.3.10+incompatible
go: downloading github.com/labstack/echo v3.3.10+incompatible
go: finding github.com/labstack/gommon/color latest
〜〜〜 省略 〜〜〜
go: finding github.com/valyala/bytebufferpool v1.0.0
go: downloading golang.org/x/sys v0.0.0-20190412213103-97732733099d
go: downloading github.com/valyala/bytebufferpool v1.0.0
____ __
/ __/___/ / ___
/ _// __/ _ \/ _ \
/___/\__/_//_/\___/ v3.3.10-dev
High performance, minimalist Go web framework
https://echo.labstack.com
____________________________________O/_______
O\
⇨ http server started on [::]:8080
Webアプリ起動後のgo.mod
確認
Webアプリ起動時にダウンロードしたモジュールをバージョンとともにrequire
として管理。
root@3c5e824d4a2d:/usr/local/src/gowork# cat go.mod
module gowork
require (
github.com/labstack/echo v3.3.10+incompatible // indirect
github.com/labstack/gommon v0.2.8 // indirect
github.com/mattn/go-colorable v0.1.1 // indirect
github.com/mattn/go-isatty v0.0.7 // indirect
github.com/valyala/fasttemplate v1.0.1 // indirect
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734 // indirect
)
■ Go 1.11 Modulesの機能で取得した自前以外のモジュール
WebAPI実装ソース及びgo.mod
置き場には、自前以外のモジュールは存在しない。
「glide」や「dep」であれば vendor
ディレクトリがあって、その下に自前以外のモジュールのソースが置かれていたのだけど。
root@3c5e824d4a2d:/usr/local/src/gowork# ls -l
total 12
-rw-r--r-- 1 root staff 350 Apr 28 05:00 go.mod
-rw-r--r-- 1 root staff 2273 Apr 28 05:00 go.sum
-rw-r--r-- 1 root staff 213 Apr 28 04:59 main.go
となると、あとは、GOPATH
の配下だろうね。
root@3c5e824d4a2d:/usr/local/src/gowork# env | grep GOPATH
GOPATH=/go
root@3c5e824d4a2d:/usr/local/src/gowork#
root@3c5e824d4a2d:/usr/local/src/gowork# ls -l /go/
total 12
drwxrwxrwx 2 root root 4096 Apr 12 22:23 bin
drwxr-xr-x 3 root root 4096 Apr 28 05:00 pkg
drwxrwxrwx 2 root root 4096 Apr 12 22:23 src
root@3c5e824d4a2d:/usr/local/src/gowork#
root@3c5e824d4a2d:/usr/local/src/gowork# ls -l /go/bin/
total 0
root@3c5e824d4a2d:/usr/local/src/gowork#
root@3c5e824d4a2d:/usr/local/src/gowork# ls -l /go/src/
total 0
GOPATH/bin
とGOPATH/src
は空。
root@3c5e824d4a2d:/usr/local/src/gowork# ls -l /go/pkg/
total 4
drwxr-xr-x 5 root root 4096 Apr 28 05:00 mod
root@3c5e824d4a2d:/usr/local/src/gowork#
root@3c5e824d4a2d:/usr/local/src/gowork# ls -l /go/pkg/mod/
total 12
drwxr-xr-x 4 root root 4096 Apr 28 05:00 cache
drwxr-xr-x 5 root root 4096 Apr 28 05:00 github.com
drwxr-xr-x 3 root root 4096 Apr 28 05:00 golang.org
root@3c5e824d4a2d:/usr/local/src/gowork#
root@3c5e824d4a2d:/usr/local/src/gowork# ls -l /go/pkg/mod/github.com/
total 12
drwxr-xr-x 4 root root 4096 Apr 28 05:00 labstack
drwxr-xr-x 4 root root 4096 Apr 28 05:00 mattn
drwxr-xr-x 4 root root 4096 Apr 28 05:00 valyala
うん。ここっぽいね。GOPATH/pkg
今回のGoソースで使っている labstack/echo
を確認してみる。
root@3c5e824d4a2d:/usr/local/src/gowork# ls -l /go/pkg/mod/github.com/labstack/
total 8
dr-xr-xr-x 5 root root 4096 Apr 28 05:00 echo@v3.3.10+incompatible
dr-xr-xr-x 7 root root 4096 Apr 28 05:00 gommon@v0.2.8
root@3c5e824d4a2d:/usr/local/src/gowork#
root@3c5e824d4a2d:/usr/local/src/gowork# ls -l /go/pkg/mod/github.com/labstack/echo\@v3.3.10+incompatible/
total 180
-r--r--r-- 1 root root 1075 Apr 28 05:00 LICENSE
〜〜〜 省略 〜〜〜
-r--r--r-- 1 root root 8265 Apr 28 05:00 bind.go
-r--r--r-- 1 root root 10848 Apr 28 05:00 bind_test.go
〜〜〜 省略 〜〜〜
-r--r--r-- 1 root root 8831 Apr 28 05:00 router.go
-r--r--r-- 1 root root 29962 Apr 28 05:00 router_test.go
バージョン指定付きでディレクトリが出来ていて、その中にはソースが展開されている。
ここであらためて、go.mod
の中身を確認。
root@3c5e824d4a2d:/usr/local/src/gowork# cat go.mod
module gowork
require (
github.com/labstack/echo v3.3.10+incompatible // indirect
〜〜〜 省略 〜〜〜
)
このへんの記載とディレクトリに付与されたバージョンが連動している。
GOPATH/pkg
の下にソースが展開されるとなると、複数のアプリが同じモジュールを使う時にそれぞれのアプリで使うバージョンが違ったりしておかしなことになるのではと思ったけど、こうしてバージョン付きのディレクトリ名にすることで複数バージョンを共存できるようにしているのだね。
備忘録
今回はgo run
を実行した時にgo.mod
に依存モジュールがrequire
として追加されたけど、go build
やgo test
実行時も同じらしい。
https://github.com/golang/go/wiki/Modules#daily-workflow