504
273

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

GoAdvent Calendar 2020

Day 16

Go1.16からは go get は使わず go install を使おう

Last updated at Posted at 2020-12-16

この記事はGo Advent Calendar 2020 16日目の代打記事です。奇しくも16日目にGo1.16の話をすることになりました。

【追記】タイトル改題しました

状況が落ち着いてだいぶ経ったのと、未だに多くの方にこの記事を見ていただけていることから、Go1.16での変更というより、今を生きる私達がどうすればいいか、という点にフォーカスしたタイトルに改題しました。本文に変更はありません。一応注記すると、go get が廃止になったわけではなく、普段の開発フローで使うことはまずなくなった、という意味です。(一通り読んでいただければお分かりいただけるかと。)

【追記】Go1.18について

ついに待望のGo1.18がリリースされましたね! https://go.dev/doc/go1.18#go-command
そして予告通り go get によるインストール機能は削除されました。どうしても従来のように go get でビルドとインストールを行いたい場合、GO111MODULE 環境変数を off にしてGOPATHモードにすることで可能です。

【追記】Go1.17について

Go1.17がリリースされました。 https://golang.org/doc/go1.17#go-get
Go1.17では、go get によるツールのインストールに警告が表示されるようになります。Go1.18 にて、go get によるツールのインストール機能が削除される予定です。(当初は1.17で削除される予定でしたが、変更されました。)

はじめに

Go1.16では、Modulesに関する様々なアップデートが入ります。cf. https://tip.golang.org/doc/go1.16#tools

  • ツールのグローバルインストールを簡単にするため、go install に新たな機能が追加されました。今後は「バイナリのビルドとインストールのための go install」、「go.mod 編集のための go get」と役割が整理されていくことになりました。(issueはこちら。)
  • GO111MODULE はデフォルトでon、つまり常にModuleモードが有効になりました。GOPATHモードにお別れを。
  • go buildgo test で自動的に go.mod が更新されることがなくなりました。go.mod の編集は go get , go mod tidy , あるいは手作業で行います。

この記事では、Go1.16以降のgo get / go install の使い方、抑えておきたいポイントを解説します。ちなみに、以下はすべてGOPATHモードではなくModuleモード前提で解説しています。(でないと複雑になりすぎるので)

抑えておきたいポイント

  • 基本的に、ツールのグローバルインストールには go install <package>@<version> を使用します。
    • 例: go install golang.org/x/tools/gopls@latest
    • スクリプトなどに書いていた方はごめんなさい、修正をお勧めします。
  • go get のバイナリインストールの機能は今後のバージョンで削除される予定です。
  • go getgo.mod に依存性を追記するためだけのコマンドとして整理されていきますが、go.mod の編集には go get 以外の方法も用意されているので、go get を使う機会は今後少なくなっていきそうです。

Go1.16で解決されるツールのインストール問題

今までGoでグローバル ($GOPATH/bin) にツールをインストールするにはお馴染みの go get コマンドが使われてきましたが、一つ問題を抱えていました。go getgo.mod を編集する役割も兼ねているため、go.mod を触らずにツールだけをインストールするには「go.mod のあるディレクトリを抜けて」「ツール側の go.mod を有効にし」go get する、という手順が必要でした。一つにまとめると以下のようになります。

$ cd $(mktemp -d); GO111MODULE=on go get golang.org/x/tools/gopls

流石にインストール一つにこんな手間は掛けたくないし、何よりModulesについてよく知らずに go get を行い不本意な go.mod の更新を行ってしまう事故が絶えませんでした。(ソースは筆者)

というわけで、Go1.16からは以下のようになります。

$ go install golang.org/x/tools/gopls@latest

とてもすっきりしましたね。

実はこの go install <package>@<version> という書式がGo1.16で新たに導入されたものです。この書式では、Module配下であろうとなかろうと、一貫して指定したversionを $GOPATH/bin にインストールします。

Go1.16では GO111MODULE はデフォルトでonになっているし、go installgo.mod を編集しなくなるため、もろもろの事故が起こることもなくなりました。

注意

  • @version つきでインストールできるのはmain packageのみです。非main packageはこの書式の対象ではありません。

補足: version指定なしの go install <package> について

  • Module外で @version なしの go install <package> は出来ません。
  • Module配下では、@version なしのインストールも可能(go.mod のバージョンが反映される)ですが、main packageを go.mod に記載しておくにはひと手間必要なので、Module配下であろうと go install <package>@<version> を行うのがシンプルでよいかと思います。
    • 非main packageのインストールについては、次の項目をご覧ください。

go install のその他の機能について

go install のその他の機能、つまり、

  • 作業ディレクトリをビルドして $GOPATH/bin に配置する機能
  • 非main packageをビルドしてキャッシュする機能(Module配下で、version指定せずに go install <package>

については、従来のまま変わりありません。これらは無くても生きていける代物ではありますが、たまに思い出すと便利かもしれません。

go get, go.mod について

一方の go get は、バイナリインストールの役割を go install に譲り、go.mod を編集するためだけのコマンドとして整理されていきます。Go1.16より後のリリース(Go1.17予定→Go1.18予定に変更)では、go get によるバイナリインストールの機能は削除され、go get はすべて go get -d 相当の、ソースをダウンロードし go.mod に追記するだけの挙動になる予定です。

go.mod を編集する方法

Go1.16では他にも、go buildgo test で自動的に go.mod が編集されないという挙動の変更がありました。これらを踏まえて、Go1.16で go.mod を扱う方法は以下の通りになります。

A) コードにimport文を書いてから go.mod に反映する方法

  • go get # 引数なし
    • 新規モジュール追加のみ
  • go mod tidy
    • 不要モジュールの削除と新規モジュールの追加を行ってくれる

B) importされていないモジュールを go.mod に追加する方法

  • go get <package>[@<version>]
  • 手作業で go.mod を編集

4つ挙げましたが、実際のところ go mod tidy がすべて賄っているので、go mod tidy 一本で行ってもよさそうです。

Go1.15からの変更点

先に述べている通り、go build などによる go.mod の自動編集の機能はGo1.16から無効になるため、Go1.15までのユーザーは、go.mod が変更されるのに期待して go build するとあれっ?となるかもしれません。go mod tidy しておきましょう。

また、Go1.18以降で go get のバイナリインストールの機能が削除されるため、それまでに各種手順書やスクリプトを修正する必要がありそうです。

goplsv0.6.0からGo1.16に追従して go.mod の自動編集を行わなくなる変更が入っています。順次開発フローに関しても、新しいModulesに寄せて整っていくのではないかと思われます。

まとめ

ツール周りで一部非互換な変更が入りますが、Go1.16からのModulesは大幅に簡潔かつハマりどころも少なくなっているため、より初心者には勧めやすくなったのではないでしょうか。Goを布教したい気持ちが強い筆者としては、ハマりどころが少なくなると非常にやりやすくなるし、布教のモチベも高まります。

他にも embed やら io/fs やら目玉機能が目白押しのGo1.16が待ち遠しいところです。リリース予定は来年の2月頃です。

504
273
2

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
504
273

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?