Try Golang! “go get”でツールを配布する際に気を付けるべきこと

How to release Golang tools with “go get”

Takuo
VELTRA Engineering
5 min readAug 16, 2018

--

これまで、Goで書いたツールを配布する際は、バイナリをGitHubのリリースページから落としてもらっていたのですが、実はGoの標準コマンドであるgo getを使えば、ダウンロードだけでなくインストールまでしてくれるということを今更ながら知りました。

もちろんこのことはgo getドキュメントに記載されているのですが、じゃぁgo getを使ってツールを配布する時には、何に気をつけたらいいの?って話は、意外に記事になっていない気がしたので、今回はそれについてさらりと書いてみたいと思います。

“go get”のおさらい

おなじみのgo getはGitHubなどのリポジトリにあるGo言語で書かれたライブラリやツール類をローカル環境にgetしてくるコマンドです。上述したとおり、特にオプション指定しなければ、ダウンロード後にインストール処理が走ります。

まずは一番シンプルな形について見てみましょう。ルート直下にmain.goがあるリポジトリをgo getで取得してみます。

go getコマンドはこんな感じ。

すると、ファイルのダウンロード後、$GOPATH/bin以下にリポジトリ名のバイナリファイルが作成されます。$GOPATH/binをちゃんとPATHに設定していれば、すぐにコマンドを利用することができます。

続いて、cmdの下にmain.goを配置しているタイプのリポジトリ。ライブラリとしての用途がメインで、コマンドとしての機能も提供しているリポジトリはこの形式を取ることが多いですね。

この形式のリポジトリの場合は、下記のようにgo getしてもらうことになります。

これで、先ほどと同様に$GOPATH/binの下にリポジトリ名のバイナリファイルが作成されます。なお、この時のバイナリファイル名はmain.goが格納されているディレクトリ名になるので、必ずしもリポジトリ名と一致させなくても構いません。

“go get”でのツール配布時に気を付けるべきこと

さて、上の例では、依存パッケージの有無については触れませんでしたが、依存パッケージがある場合はどうなるでしょうか。

実は、go getは依存パッケージがある場合でも、自動でそれらを落としてインストールを進めてくれます。しかし、特に何も考慮しないと、いずれも各パッケージの最新バージョンがダウンロードされてしまいます。

依存パッケージのバージョンを指定したい場合、Go標準の依存パッケージ管理手法であるvendoring機能を使用します。

ここまでは当たり前の話なのですが、気を付けないといけないのは、ちゃんとvendorをリポジトリにコミットすることです(gitignoreしない)。depなどで管理している場合、Gopkg.lockGopkg.tomlだけリポジトリに入れてvendor自体はリポに入れないケースをたまに見かけますが、go getでインストールさせたい場合は原則入れてあげましょう。

それこそdep本体もvendorをコミットしていますし、クロスコンパイルツールであるgoxや、パスワード管理ツールのgopassなんかも同様の手法をとっています。

なお、depのドキュメントでは、vendorをコミットするかしないかは、利用者の考え次第だと記載されています。ライブラリとしての用途しかない場合や、go get以外で配布するようなケースでは、メリット・デメリットを考えて判断してもらえばよいのかなと思います。

気を付ける点はあるものの、さらりとgo getと書いてもらうだけでツールを配布できるのはとてもお手軽です。もちろん利用者側の環境にGoがインストールされている必要がありますが、開発者向けのツール配布はこれで十分な気がします。

ちなみに、depの代わりに標準になろうとしているvgoは、Goの標準として入るらしいので、vendorがリポジトリになくてもgo getの際に考慮されたりするのかもしれませんね。

--

--

Takuo
VELTRA Engineering

Engineer who likes travel, simple code, and something new