Golang v1.12 から dep ではなく Go Modules を使う

Go Modules とは

バージョン管理ツール。

Swift だと CocoaPods、
PHP だと Composer、
フロント全般だと npm みたいな感じのやつ。

ここら辺すごい変化があって、

golide等 → dep → go modules

という流れになってる。
go modules は便利。

go mod init

go.mod をファイル作成する。

$ cd /path/to/your/project
$ go mod init

エラーが出たら

既存のプロジェクトの移行作業ではなく、
新規にプロジェクトを作成し、
モジュール名を指定していない場合に起きる。

モジュール名を指定して init する。

$ go mod init

go: cannot determine module path for source directory /var/www/html/psychedelicnekopunch/xxxxxx (outside GOPATH, module path must be specified)

Example usage:
	'go mod init example.com/m' to initialize a v0 or v1 module
	'go mod init example.com/m/v2' to initialize a v2 module
  • モジュール名は github でソースを管理してたら「github.com/ユーザー名/プロジェクト名」にしておくのが良さそう。
$ go mod init github.com/psychedelicnekopunch/xxxxxx

go mod tidy

使ってないモジュールや使用しているけどダウンロードしていないモジュールなどを調べて良い感じにしてくれる。
全プロジェクト共通のディレクトリ(ex. /var/www/go 以下)にダウンロードされていく。
プロジェクト毎に使用しているモジュールのバージョンが違っていても良い感じにしてくれる。

$ go mod tidy

go mod tidy する前に

プロジェクトの作業を進める。
go ファイルを作成し、使いたいモジュールを import 記述で指定していく。

ある程度書き終わってから、
go mod tidy すると必要なモジュールをダウンロードしたりして、
良い感じに整理してくれる。

うまくいく例

次々とダウンロードされていく。

$ go mod tidy

go: downloading ...
go: downloading ...
go: downloading ...
go: downloading ...

エラーが出たら

以下のようなエラーが出たら、
go.mod を書き換える。

あくまで例なので、
自分の状況に置き換えて書き換える。

  • ブランチ名とリポジトリ先の名前が一致しない感じのエラー。
$ go mod tidy

go: github.com/360EntSecGroup-Skylar/excelize@v0.0.0-00000-xxxxx: go.mod has post-v0 module path "github.com/360EntSecGroup-Skylar/excelize/v2" at revision xxxxx
go: github.com/robfig/cron@v0.0.0-00000-xxxxx: go.mod has post-v0 module path "github.com/robfig/cron/v3" at revision xxxxx
go: error loading module requirements
$ vi go.mod

# 最終行に追加
# 下記バージョンは調べた日での最新バージョン
replace github.com/360EntSecGroup-Skylar/excelize => github.com/360EntSecGroup-Skylar/excelize/v2 v2.1.0
replace github.com/robfig/cron => github.com/robfig/cron/v3 v3.0.1
  • そもそもモジュール名とダウンロード先が違う
$ go mod tidy

module declares its path as: github.com/russross/blackfriday/v2
but was required as: gopkg.in/russross/blackfriday.v2
$ vi go.mod

# 最終行に追加
# 下記バージョンは調べた日での最新バージョン
replace gopkg.in/russross/blackfriday.v2 => github.com/russross/blackfriday/v2 v2.0.1

help

よく使うのは tidy

$ go mod help

Usage:

	go mod <command> [arguments]

The commands are:

	download    download modules to local cache
	edit        edit go.mod from tools or scripts
	graph       print module requirement graph
	init        initialize new module in current directory
	tidy        add missing and remove unused modules
	vendor      make vendored copy of dependencies
	verify      verify dependencies have expected content
	why         explain why packages or modules are needed

自分が作ったファイルを import したい時

モジュール名を確認する

go.mod に書いてある。
「module xxxxx」がモジュール名。

$ cat go.mod

module github.com/psychedelicnekopunch/xxxxxx

go 1.12

require (
	github.com/xxxxxx/xxxxx v0.0.1
)

import する

  • 例えば main.go に import する。
  • app/infrastructure/DB.go があったとする。
    • DB.go に NewDB() が定義されているとする。
package main

import (
	"fmt"
	"github.com/psychedelicnekopunch/xxxxxx/app/infrastructure"
)

func main() {
	db := infrastructure.NewDB()
	fmt.Print(db)
}

関連投稿