「ほぼ何もしない」asdf向けGoプラグインasdf-go-sdk

2021/10/01に公開

概要

asdfを利用してGoのバージョンを切り替えるためのプラグイン、asdf-go-sdkの紹介です。

そもそもGo言語は後方互換性が高く、最新版を使用していれば大抵は問題ありません。
Goでは○○envが不要になった理由でも言及されているされている通り、基本的には最新版を使い、適宜公式の方法で複数バージョンをインストールすれば、良いでしょう。

では、このasdfプラグインは何をするかと言うと、公式の方法でインストールされたgo1.17.1のようなコマンドを、goとして実行出来るようにする、ただそれだけのプラグインです。

背景

開発に使用するツール・言語をasdfで管理するようになり、Goのみをgo1.17.1のように実行させる事に辛さを感じることがありました(例えばMakefileなど)。

asdfのGoプラグインは既に存在[1]していたものの、公式の方法とは異なる方法・場所にインストールされる物でした[2]。注意して使わないと、

  • GOPATHがインストールバージョン毎に別になってしまいgo getしたコマンドが使えなくなる
  • ディスク使用量が多くなる(GOPATH/srcなどが2重3重で保持される)
  • VSCodeやGoLandでSDKをインストールすると同じバージョンのSDKを2重管理することになる

などのトラブルにも遭遇しました。

GOPATHをGoのバージョン毎に分けたいと思った事はなく、あくまでgoコマンドを実行した際のバージョンがasdfで管理出来れば良かった為、思い切って 「ほぼ何もしない」 方針で作成したプラグインが、asdf-go-sdkです。

asdfについて

asdfは、大雑把に言えば○○envと同じように各種ツールのバージョンを管理する為のユーティリティです。
○○envとの大きな違いは、asdf自身はコマンドラインインターフェースのみを提供し、各種ツールのバージョン取得・インストールなどはプラグインとして実装されている点です。

以下の3つの機能を実装するだけで最小限のプラグインが実装できる為、既にプログラミング言語のみでなく多種多様なツールが提供されています(asdf-plugins)。

  • バージョンリスト取得
  • ダウンロード
  • インストール

使い方

このプラグインを利用する為には、システムに既にGoがインストールされている必要があります。

基本的な使い方は、asdfの他のプラグインと変わりません。

# プラグインの追加
asdf plugin add go-sdk

# インストール可能なバージョンリストの表示
asdf list-all go-sdk

# 指定したバージョンのインストール
asdf install go-sdk 1.17.1

# インストール済みリストの表示
asdf list go-sdk

# 利用するバージョンの設定
asdf local go-sdk 1.17.1

# デフォルトで利用するバージョンの設定
# [system]でシステムにインストールされた物を利用。おすすめ!
asdf global go-sdk system

asdfを使用せずに公式の方法でインストールした場合や、VSCode・GoLandなどの開発環境でSDKを追加した場合、次のコマンドで同期することでasdfから利用できるようになります。

asdf go-sdk sync

プラグインの動作

ここから先はプラグインを利用するだけなら読む必要はありません。

インストール

公式の方法の方法に従い、次のコマンドが内部で実行されます。
アークテクチャの判定やSDKのダウンロードはほぼ全てGoに委ねています。

downloadを実行した際のSDKインストール先判定処理がgoroothomedirと非公開にされており、利用することができませんでした。
長期間変わっていない様子だったので同等のコードをプラグイン内で実行して取得していますが、できれば提供されている方法で取得したかった所です。

# 利用可能なgoが1.16以下の場合
go get golang.org/dl/go1.17.1

# 利用可能なgoが1.17以上の場合
go install golang.org/dl/go1.17.1@latest

# go get・installでGOBIN以下にインストールされたコマンドでSDK本体のインストール
go1.17.1 download

# asdfが定めたディレクトリ以下にインストールしないと認識されないため、シンボリックリンクを作成
ln -s $(go1.17.1 env GOROOT) ASDFの管理ディレクトリ

コマンド(go)実行時の環境変数

環境変数GOROOTだけ設定・上書きします。

通常はGOROOTを設定する必要はありません。しかし、GoLandなどの一部の開発環境で開かれたターミナルはGOROOTが設定されていることがあり、ビルド時に「does not match go tool version」のようなエラーが出ることがあります。
これを避ける為、指定されているバージョンに合わせたGOROOTを明示的に指定して起動するようにしています。

GOPATHGOBINに対して何も変更を加えないため、asdfを使用しない場合と動作は何ら変わりません。

その他

asdfはプラグインでasdf go-sdk syncのようなコマンドを追加することができ、追加したコマンドがasdf helpに表示されます。
このプラグインの開発中、プラグイン名にハイフン(-)を含んでいるとこのヘルプが正しく表示されない事が分かり、asdf本体の修正を行いました。

現時点でこの修正が入ったバージョンはリリースされていないため、asdf helpに表示されるコマンドは誤った物が表示されます。ご注意下さい。

脚注
  1. https://github.com/kennyp/asdf-golang ↩︎

  2. asdfのプラグインの動作として誤っている訳ではありません。むしろ私の作成したプラグインの方が、asdfの本流からは外れる動作をします。 ↩︎

Discussion