LoginSignup
9
6

More than 5 years have passed since last update.

Go 1.11 Modules

Posted at

お題

Go 1.11 における「Modules」は Go 1.12 での完成を目指す実験的なバージョン管理機能。
公式のwikiに従い、試してみよう。

開発環境

# OS

$ cat /etc/os-release 
NAME="Ubuntu"
VERSION="17.10 (Artful Aardvark)"

# Golang

$ go version
go version go1.11.2 linux/amd64

バージョンの切り替えはgoenvで行っている。

実践

■クイックスタートサンプルをトレース

1)GOPATH外にプロジェクトを作成

$ env | grep GOPATH
GOPATH=/work/src/golang
$
$ mkdir -p /tmp/scratchpad/hello
$ cd /tmp/scratchpad/hello

2)Modulesの初期化

$ go mod init github.com/you/hello
go: creating new go.mod: module github.com/you/hello

go.modが出来る。

$ ll
-rw-r--r-- 1 koge koge   28 11月 19 09:30 go.mod
$
$ cat go.mod 
module github.com/you/hello

3)外部パッケージのimportを含むソースを作成

$ cat <<EOF > hello.go
> package main
> 
> import (
>     "fmt"
>     "rsc.io/quote"
> )
> 
> func main() {
>     fmt.Println(quote.Hello())
> }
> EOF

4)ビルド

$ go build

すると、実行ファイル「hello」の他に、go.sumというファイルも作られる。

$ ll
-rw-r--r-- 1 koge koge   57 11月 19 09:35 go.mod
-rw-r--r-- 1 koge koge  499 11月 19 09:35 go.sum
-rwxr-xr-x 1 koge koge 2.2M 11月 19 09:35 hello
-rw-r--r-- 1 koge koge  102 11月 19 09:33 hello.go
$ cat go.sum 
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:qgOY6WgZOaTkIIMiVjBQcw93ERBE4m30iBm00nkL0i8=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
rsc.io/quote v1.5.2 h1:w5fcysjrx7yqtD/aO+QwRjYZOKnaM9Uh2b40tElTs3Y=
rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0=
rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=

そして、先ほどまではなかった「quote」パッケージに関する記述がgo.modに増えている。
go build時に勝手にソースから依存パッケージを抽出してくれる様子。

$ cat go.mod 
module github.com/you/hello

require rsc.io/quote v1.5.2

5)実行

$ ./hello 
こんにちは世界。

■コンセプト

モジュール

「Modules」は関連するGoパッケージの集合であり、それらを1つの単位としてバージョニングしたもの。
目的は、依存関係を正確に記録しておき、再現可能なビルドを作成できるようにすること。

「Modules」はセマンティックバージョニングする必要がある。
先頭は「v」であり、「【メジャーバージョン】.【マイナーバージョン】.【パッチバージョン】」の形式である。
(例:「v0.1.0」、「v1.2.3」)

go.mod

モジュールは、あるディレクトリに「go.mod」ファイルを持つGoソースのツリーとして定義される。
モジュールのソースコードは、GOPATHの外部に配置されている必要がある。

モジュールの例:

module github.com/my/thing

require (
    github.com/some/dependency v1.2.3
    github.com/another/dependency/v4 v4.0.0
)

go.modには、「module」、「require」、「exclude」、「replace」の4つのディレクティブがある。
「module」は、そのモジュールを定義するパス。
「require」は、そのモジュール内のソースがimportする外部パッケージ。
「exclude」と「replace」は、メインモジュールをビルドする時に無視されるパッケージ。
例えば、「https://github.com/sky0621/go-modules」をgit cloneしてモジュール化する場合、あらかじめ「【適当なパス】/github.com/sky0621」というディレクトリを掘っておき、その下にgit cloneする。
それからそのプロジェクト内に移動してモジュール初期化。

$ cd go-modules/
$
$ pwd
/work/src/gomodule/github.com/sky0621/go-modules
$
$ go mod init github.com/sky0621/go-modules
go: creating new go.mod: module github.com/sky0621/go-modules
$
$ cat go.mod 
module github.com/sky0621/go-modules

バージョンについて

Goのモジュールには従うべきルールがある。

  • セマンティックバージョニングであること
  • バージョン「v2」以上の場合はモジュールパスとimportパスに「v2」を含めること
  • バージョン「v0」ないし「v1」の場合はモジュールパス、importパスにバージョンを含めないこと

■モジュールの使い方

インストール

以下参照。

アクティベート

以下いずれか。

  • 環境変数「GO111MODULE」をアンセット後、GOPATH以外のパスにgo.modファイルを配置してgoコマンド実行
  • GO111MODULE=on」を環境変数にセットしてgoコマンド実行

まとめ

だいぶ端折ったけど、ひとまず必要最低限は書いたかな。

9
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
6