お題

表題について確認する。主に以下の人が対象。
★今まで「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

广告
将在 10 秒后关闭
bannerAds