🦔
go installしたものを一括で更新する方法
結論
zsh ですが、簡単なスクリプトで実現できそうです。
pushd ~
local gobin="$(go env GOBIN)"
local gobin="${gobin:-$(go env GOPATH)/bin}"
print -rl ${gobin}/*(*) | while read file; do
local pkg="$(go version -m "${file}" | head -n2 | tail -n1 | awk '{print $2}')"
go install "${pkg}@latest"
done
popd
解説
実行ファイルから出自を知る
忘れがちですが、 go version -m
は、ビルドした実行ファイルを取れるんですね。
多謝、 @skanehira !
$ go version -m ~/go/bin/goimports
/home/kyoh86/go/bin/goimports: go1.17.7
path golang.org/x/tools/cmd/goimports
mod golang.org/x/tools v0.1.9 h1:j9KsMiaP1c3B0OTQGth0/k+miLGTgLsAFUCrF2vLcF8=
dep golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
dep golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 h1:id054HUawV2/6IGm2IV8KZQjqtwAOo2CYlOToYqa0d0=
dep golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
zshをちょっと頑張る
まずはglobalなgo installでインストールされる先を特定します。
local gobin="$(go env GOBIN)"
local gobin="${gobin:-$(go env GOPATH)/bin}"
GOBIN
を設定している場合はその場所を指すべきだし、指定されていないならGOPATH/bin
でしょう。
次に特定ディレクトリ(今回はgo/bin
)配下の実行ファイルをリストアップします。
これには、zshのextended globが大変便利ですね。
まともにやるなら find
とか使うんでしょうが…
print -rl ${gobin}/*(*) | while read file; do
# ...
done
あとはgo version -m
の出力から2行目2列目だけ引っ張り出せば、Package Pathが抽出できます。
(より厳密には、1列目==pathをちゃんと抽出するべきですが、面倒なので簡略化しています)
go version -m "${file}" | head -n2 | tail -n1 | awk '{print $2}'
これを変数pkg
に放り込んで、 go install
に渡してやれば良い。
go install "${pkg}@latest"
direnvとか、go.modとかに影響されると面倒くさいので、前後にhomedirへの移動と復帰をはさみます。
pushd ~
# ...
popd
ということで全体構造を再掲します。
pushd ~
local gobin="$(go env GOBIN)"
local gobin="${gobin:-$(go env GOPATH)/bin}"
print -rl ${gobin}/*(*) | while read file; do
local pkg="$(go version -m "${file}" | head -n2 | tail -n1 | awk '{print $2}')"
go install "${pkg}@latest"
done
popd
終わりに
この記事はQiitaの拙著記事 $GOPATH/binにいるバイナリ群の出自を探る方法 を元に、大幅に書き直したものです。
goはmodule awareのサポート前後で大きく環境が異なるので、情報を選ぶ時は投稿日などには十分注意したいですね。
Discussion