go のバージョンを go.mod から選ばせてみよう
ああ、go.mod
があるっていうのに、なんで我々は ${PATH}
で消耗しないといけないんでしょう?
goenv 入れるのもなあ... なんで .go-version
とかいうファイルを置かないといけないんでしょう [1] ?
もっと雑に管理したいですねえ。 go.mod
みていい感じにしてくれたら嬉しいですよねえ!! そうでしょう?
こんなことやってみた
というわけで、ざっくりこんなことやってみました。
ディレクトリを整理する
go の実行系のある場所といえば ~/sdk
ですね。
まずはその ~/sdk
にちょっと手を加えて、こんな感じにしました。
$ ls -la ~/sdk
total 0
$ ls -la
total 0
drwxr-xr-x 16 youta staff 512 2 14 22:00 .
drwxr-xr-x+ 91 youta staff 2912 2 14 21:29 ..
lrwxr-xr-x 1 youta staff 10 2 14 21:34 go -> ./go1.22.x
drwxr-xr-x 20 youta staff 640 2 14 21:58 go1.17.13
lrwxr-xr-x 1 youta staff 11 2 14 21:59 go1.17.x -> ./go1.17.13
drwxr-xr-x 19 youta staff 608 3 15 2022 go1.18
drwxr-xr-x 20 youta staff 640 2 14 21:59 go1.18.10
drwxr-xr-x 21 youta staff 672 9 26 2022 go1.18.6
lrwxr-xr-x 1 youta staff 11 2 14 21:59 go1.18.x -> ./go1.18.10
drwxr-xr-x 17 youta staff 544 1 5 08:48 go1.20.13
lrwxr-xr-x 1 youta staff 11 2 14 22:00 go1.20.x -> ./go1.20.13
drwxr-xr-x 20 youta staff 640 9 19 23:28 go1.21.1
lrwxr-xr-x 1 youta staff 10 2 14 22:00 go1.21.x -> ./go1.21.1
drwxr-xr-x 19 youta staff 608 2 14 21:19 go1.22.0
lrwxr-xr-x 1 youta staff 10 2 14 22:00 go1.22.x -> ./go1.22.0
drwxr-xr-x 18 youta staff 576 1 24 04:44 go1.22rc2
はい、 各 go1.${N}
ごとに、普段遣いしたいリリース番号のものに向けて go1.${N}.x
から symlink しました。
さらに、"go といえばコレ"というバージョンに向けて go
からリンクを貼りました。
これが第一段階です。
いいかんじのシェルスクリプトを書く。
あとは、このディレクトリ構成を前提にしたシェルスクリプトを書いて、go
って名前にして $PATH
の先頭側にくっつけるだけです。
こんなシェルスクリプトになりました[2]
#! /bin/bash
SDK=${GOSDK:-~/sdk}
function detectGomod() {
if [ -r "./go.mod" ] ; then
echo $(pwd)/go.mod
return 0
fi
if [ $(pwd) == / ] ; then
return 0
fi
cd ../
detectGomod
}
GOMOD=$(detectGomod)
if [ "${GOMOD}" == "" ] ; then
exec "${SDK}/go/bin/go" $@
exit
fi
GOVER=$(grep -Ee '^go ' ${GOMOD} | head -n 1 | awk '{ print $2 }')
exec ${SDK}/go${GOVER}.x/bin/go $@
起動した場所から上側にたどっていって go.mod
を探し、 その中の go ディレクティブをエイヤ!と解析して language version[3] を取り出しています。
リリース番号が書いてないことを前提に、 ~/sdk/go${GOVER}.x/bin/go
に exec
してやれば、 go.mod
準拠の go セレクタが一丁上がり!
go.mod
が見つからなければ、~/sdk/go
をデフォルトの go だと思うことにしています。
リリース番号には未対応ですが、対応する場合は、リリース番号を検出したら *.x
じゃないものから選ぶように拡張すればいいですね。
まとめ
いやあ、シェルスクリプトって気持ちいいですねえ!!!
追記
ゲェーッ、VSCode が ${PATH}
に go の実行環境のパスを差し込んでくる...
Discussion