golang のアップデートを行いました!(1.10.3→1.12.1)

こんにちは。開発グループ・エンジニアの阿部です。
社内では abemotion って呼ばれたりもします。

前回の記事で紹介したのですが、

yomoyamablog.coconala.co.jp

apigateway で使われている golang のアップデートを行いました!

f:id:coconalainc:20190509144443j:plain
基本のGopherくん by Renée French | CC BY 3.0

今日はアップデート手順と、
1.11から標準機能として導入されたパッケージ管理 Go Modules についてご説明します。

アップデート手順

GOROOT="/usr/local/go"
GOPATH="$HOME/go"

インストーラーを使用すると、
上記標準で設定されている場所とは違う所にインストールされてしまうので、
コンパイル済みのバイナリパッケージ落としてきて設置しています。

まず設置済みのアップデート対象となる1.10.3を削除します。

$ rm -r /usr/local/go

削除できたら golang 1.12.1 を取得し置き換えます。

$ curl -O https://dl.google.com/go/go1.12.1.darwin-amd64.tar.gz
$ tar -C /usr/local -xzf go1.12.1.darwin-amd64.tar.gz

コンテナの設定変更等、インフラ側の対応はまだありましたが、
細かい変更を除けば、アプリケーション側の作業は基本的にはこれだけでした。

これでビルドが無事に通れば完了です。比較的簡単ですよね!
※ 上記手順はあくまで一例ですので、お試しになる場合はお手元の環境をよくご確認ください。

golang のアップデートが済んだら、今回導入した Go Modules 用に環境変数を設定します。

$ export GO111MODULE=on

Go Modules

1.11 から Go Modules と呼ばれるパッケージ管理の機能が、予備サポートとして標準で追加されました。

これまでパッケージ管理の仕組みは標準で搭載されておらず、
サードパーティツール等を入れて対応を行なっておりました。
(ココナラでは dep を使用)

1.11/1.12 ではまだ予備サポートですが、
1.13 以降ではモジュールモードがデフォルトでオンになるので、
(上記環境変数の設定が不要になる)
今回こちらの対応も合わせて行いました。

モジュールの作成

$ go mod init XXX

XXXにはモジュール名を入力します。
モジュール名は、モジュールを作成したいプロジェクトのパッケージパスと合わせておきます。

このコマンドで現在のディレクトリをモジュールのルートにしgo.modファイルが作成されます。
こちらのファイルに現在プロジェクトで使用しているパッケージ一覧が書かれます。

また dep ツールを使用している場合、Gopkg.lock ファイルを読み込んで、go.modに反映してくれます!

パッケージそのものはビルド時に取得され、~/go/pkg に格納されます。

バージョニング

Go Modulesでは、バージョニングはセマンティックバージョンタグで管理されています。 (v1.2.3の様な形式)

パッケージに特定のリリースタグが切られていない場合は、
特定のコミットに対応した擬似バージョンが作成されます。
(v0.0.0-YmdHis-XXX 形式)

Go Modules の特徴としては、依存関係解決の際に可能な限り古いバージョンが採用されます。
より古いバージョンが公開されることはないので、この仕組みでビルドを維持しています。
この規則は Minimal Version Selection と呼ばれています。

また異なるメジャーバージョンの共存も可能となっていて、それぞれ異なるモジュールパスを使用します。
後方互換性のないバージョン間のパッケージパスは、最後にメジャーバージョンが付きます。
(XXX/XXX/v3 の様な形式)
この規則は Semantic Import Versioning と呼ばれています。

最後に

言語やフレームワークのアップデートは、プロダクトの機能リリースと比べると一見地味ですが、細かく追随していきたいですね!
※ golang では直近2バージョンしかサポートされていないため、必須...笑

f:id:coconalainc:20190509142939j:plain