Go言語のパッケージ管理の課題
Go言語は基本的に「go get ~」でインストールしたパッケージはすべて環境変数$GOPATH配下にインストールされます。
また、Go1.8からは環境変数$GOPATHを設定していない場合は、$HOME/goを利用するようになっています。
そして、Goをビルドするときには、常に環境変数$GOPATHまたはこのディレクトリを見るので、同じモジュールでもビルドするプログラムによってバージョンを変える、といった事は標準の機能では実現出来ません。
これは結構深刻な問題で同一言語で複数システムを開発しているとバージョンが異なるモジュールを使うことはほぼ確実にありえます。
Go言語のパッケージ管理システム
その問題を解決してくれるのが「glide」と呼ばれるパッケージ管理ツールです。
glideはvendoringという管理方式を持っています。
これは自分が依存している外部モジュールも自分自身が管理する、という方式の事を指します。
NodejsのnpmやPHPのComposerを例に挙げると、あちらは自分自身が依存している外部モジュールについては参照情報のみを管理し、実態は外部から取得を行います。なので、結局は外部に依存しているという状態になります。
ここの境目がvendoringか否かになってきます。
glideについてもHomebrewでインストール可能ですので早速使えるようにしてみましょう。
手順
インストール
以下のコマンドを実行します。
brew install glide
インストールはこれだけで完了です。
確認
以下のコマンドを実行してみましょう。
glide --version
正常にインストールが完了しています。
バージョン定義ファイルの作成
Go言語で開発する上で意識する必要のあるディレクトリ構成が2つあります。
- ワークスペース → GOPATHに指定するGo言語共通のディレクトリ
- プロジェクト → Go言語で実際に開発するディレクトリ
今回は以下のディレクトリ構成で説明をします。
- ワークスペース →
/Users/{ユーザー名}/tmp/work/go - プロジェクト →
/Users/{ユーザー名}/tmp/work/go/src/sample
まずはプロジェクト内で以下のコマンドを実行し、バージョン定義ファイルを作成してみましょう。
glide init
そうすると、glide.ymlというファイルが作成されます。
中身は最低限の記述しかされていません。
依存パッケージの追加
次に依存するパッケージを追加してみましょう
今回はコチラ のモジュールを利用してみましょう。
プロジェクト内で以下のコマンドを実行してください。
glide get github.com/sirupsen/logrusエラー:Could not find any of /Users/{ユーザー名}/go/src.
実行時に、以下のようなエラーが出る人がいるかもしれません。
これは環境変数$GOPATHの指定がないのでデフォルトの/Users/{ユーザー}/go/srcにインストールしようとするのですが、そんなディレクトリは存在しないよ!というエラーです。
そのディレクトリを作れば解決なのですが、利用するモジュールはプロジェクト単位で管理したいので、以下の記事で導入したdirenvを使って環境変数$GOPATHを指定しましょう。
関連記事
【ローカル開発に便利】ディレクトリ毎に環境変数を設定することが出来る「direnv」のインストール方法と使い方【.envrc】
プロジェクト内で以下のコマンドを実行し、direnv edit .
以下の記述を追記します。
基本的にはワークスペースを指定してください。export GOPATH="/Users/{ユーザー名}/tmp/work/go/"
ここで以下のエラーが出た場合はエラーメッセージの通りに以下のコマンドを実行します。
direnv allow
そうすると.envrcが正常に読み込まれると思います。
Without src, cannot continue.
こちらのエラーが出る場合はディレクトリ階層に問題があります。
先ほどdirenvにて環境変数$GOPATHに指定したワークスペースの階層に「src」ディレクトリが存在していないのが原因です。
なので、srcディレクトリを作成する必要があります。
確認
もう一度実行してみましょう。
正常にインストールされるとglide.ymlに記述が加わり、glide.lockというファイルが作成されます。
また、vendorディレクトリが自動で生成されその中にモジュールがインストールされている事がわかります。
ソースからの利用
あとはコーディング時にimportして利用するだけです。
今回はsample.goという簡単なファイルを作成しドキュメント通り以下のコードを記述します。
package main
import (
log "github.com/sirupsen/logrus"
)
func main() {
log.WithFields(log.Fields{
"animal": "walrus",
}).Info("A walrus appears")
}
そして、以下のコマンドで実行します。
go run sample.go
正常にimportされていそうですね。出力されました。
最終的なディレクトリ
ワークスペース配下のディレクトリ構成はこんな感じです。
あとがき
少しディレクトリ構成に癖がありますが、ルールさえ分かってしまえば他の言語と大差なく作業を進める事が可能になります。
ぜひ、glideを使いこなしてGo言語を実装してみてください。
