Goのパッケージ管理
【2022/11】Go1.19について追記
go get
はGo1.18から削除されました。どうしても従来のように go get
でビルドとインストールを行いたい場合、GO111MODULE 環境変数を off にしてGOPATHモードにすることで可能です。
go get
削除された経緯はgo mod tidy
で代用できるからです。Go1.16以降であればgo install
使いましょう。
本編
GOMODULEが誕生される前に GOPATH
と GOVENDOR
を使用してパッケージの管理をするのが一般的でした。
GOPATH
: Go言語一度でも使用したことがあれば、お馴染みがあると思います、GOROOT
と一緒に、Go言語の環境構築時にセットしてると思います。また、配下に src
フォルダが存在することが必須とされています
GOVENDOR
: パッケージ管理を専門フォルダーvendor
に一任する、 glide, dep,go dep...
などの管理ツールもあります
でも、どっちを使用しても、便利とは言えない
-
GOPATH
- 全てのプロジェクトは
src
フォルダに置かなければならない、すぐフォルダがパンパンになります
- 全てのプロジェクトは
-
GOVENDOR
- ディレクトリに対しての依存性が厳しい、場合によって
vendor
の配下にまたvendor
が存在します
- ディレクトリに対しての依存性が厳しい、場合によって
GOMODULE goモジュール
Go1.11バージョン以降追加された機能です。またバージョン上げてない方はバージョンアップしてください
公式の説明は以下になります リンク
Go 1.13には、Goモジュールのサポートが含まれています。モジュール対応モードは、現在のディレクトリまたはその親にgo.modファイルが見つかった場合にデフォルトでアクティブになります。
モジュールサポートを利用する最も簡単な方法は、リポジトリをチェックアウトし、そこにgo.modファイル(次のセクションで説明)を作成し、そのファイルツリー内からgoコマンドを実行することです。
より細かく制御するために、Go 1.13は一時的な環境変数GO111MODULEを引き続き尊重します。これは、off、on、またはauto(デフォルト)の3つの文字列値のいずれかに設定できます。GO111MODULE = onの場合、goコマンドではモジュールを使用する必要があり、GOPATHを参照することはありません。これを、モジュール対応または「モジュール対応モード」で実行されるコマンドと呼びます。GO111MODULE = offの場合、goコマンドはモジュールサポートを使用しません。代わりに、ベンダーのディレクトリとGOPATHを調べて依存関係を見つけます。これを「GOPATHモード」と呼びます。GO111MODULE = autoまたは未設定の場合、goコマンドは現在のディレクトリに基づいてモジュールサポートを有効または無効にします。モジュールのサポートは、現在のディレクトリにgo.modファイルが含まれる場合、またはgo.modファイルが含まれるディレクトリの下にある場合にのみ有効になります。
モジュール対応モードでは、GOPATHはビルド中のインポートの意味を定義しなくなりましたが、ダウンロードされた依存関係(GOPATH / pkg / mod)とインストールされたコマンド(GOBINが設定されていない場合はGOPATH / bin)を保存します。
では、早速使ってみます、まずgoの環境変数を確認します
$ go env
set GO111MODULE=
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\user\AppData\Local\go-build
set GOENV=C:\Users\user\AppData\Roaming\go\env
set GOEXE=.exe
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=C:\Users\user\go
set GOPRIVATE=
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=C:\Go
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLDIR=C:\Go\pkg\tool\windows_amd64
set GCCGO=gccgo
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
下記のようにgomoduleの値は空になってます
それはどういう意味かというとと
goのプロジェクトがGOPATHの配下に存在すれば=off,でなければ=on
set GO111MODULE=
でもそのまましておくと、一部エラーを引き起こす可能性があります。
下記のコマンドを実行して修正しましょう
$ go env -w GO111MODULE=on
実行後、再度env情報確認すれば、下記のようにonになってるはずです
set GO111MODULE=on
GOMODULE実際使ってみます
任意のディレクトリでフォルダを新規に作ってください
$ mkdir gomodtest && cd gomodtest
gomodをセット、名前を何にするのかは任意
$ go mod init gomodtest
実行後、 go.mod
ファイルが作られたと思います、中身を見てみますと
module gomodtest
go 1.13
- プロジェクト名
- 使用してるgoのバージョン
が確認できるはずです、早速パッケージを get
しましょう
$ go get -u go.uber.org/zap
終了後、またgo.mod
の中身をみてみましょう、先ほどgetしたパッケージ内容が記録されてることが確認できます。
module gomodtest
go 1.13
require (
go.uber.org/atomic v1.5.1 // indirect
go.uber.org/multierr v1.4.0 // indirect
go.uber.org/zap v1.13.0 // indirect
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f // indirect
golang.org/x/tools v0.0.0-20191127201027-ecd32218bd7f // indirect
)
また、同じディレクトリにgo.sum
ファイルが増えてると思います、中身を確認すると
省略
...
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
...
省略
パッケージのバージョンとそのhash値が入ってます、それは、パッケージが不正なカイゼンされないことが確保しますとの用途です
下記のコマンド実行すればgo.sum
の内容をgo.mod
に同期できます
$ go mod tidy
goモジュール使用する場合、パッケージは下記のディレクトリに存在します
/gopath/pkg/mod/go.uber.org/zap@v1.13.0/field.go
最後
インストールしたパッケージを使ってみましょう、Uber
さんがオープンソースしたlog出力用のパッケージです
gomodtestディレクトリの配下でgoファイルを新規に作ります
$ vim main.go
package main
import "go.uber.org/zap"
func main(){
logger, _ := zap.NewProduction()
logger.Warn("warning test")
}
実行すれば、以下の出力が確認できます
{"level":"warn","ts":1574911209.375762,"caller":"gomodtest/main.go:7","msg":"warning test"}
既存プロダクトのGOMODULE使用
$ cd [とあるgomod使用していないgoプロジェクト] && go mod init [プロジェクト名]
その後、ディレクトリ内の全てのファイルをbuildします
$ go build ./...
以上、完了です
追記
githubなどからソースをcloneして使用する場合、
GOMODULE使用してるプロダクトであれば、下記のコマンドでパッケージのインストール出来ます。
$ go mod tidy