より良い `go run` を実現する goshim
https://github.com/Songmu/goshim
プロジェクトでちょっとしたスクリプトを書いてリポジトリで共有したいとなった時に、スクリプト言語なら楽ですが、Goで書くのはやや面倒です。リポジトリを分けるようなものでもないし、わざわざ go install
させるようなものでもないけど、ビルドしたバイナリをどこに置くのかなどが悩ましい問題です。macを使っている人もいればlinuxを使っている人もいるのでバイナリをリポジトリに配置するわけにもいきません。
go run
でも良いかと思われるかもしれませんが、本当にちょっとしたものならよいいのですが、以下の様な問題があります。
- 複数ファイルになった時に
go run main.go hoge.go
とかやるのがダルい- (
% go run $(go list -f '{{join .GoFiles " "}}') [args...]
とかやる手はある)
- (
- 子プロセスを呼びだすのでプロセス管理がめんどい
os.Exit(10)
とかしていても "exit status 10" とか出力に出るだけで、異常終了の場合、終了コードは常に1になってしまう- ※以前は終了コードが常に0だと書いてありましたが、mattnさんの指摘を受けて修正しました。またこの挙動は、Go1.7で修正予定 とのことです
そこで goshim
の出番です。 goshim
は指定したパッケージディレクトリのコードをビルドしてキャッシュし、それを exec
で実行してくれます。それにより、 go build
したバイナリを実行するのと同様にGoのソースを実行することができます。
以下のようにインストールします。
% go get github.com/Songmu/goshim/cmd/goshim
そして、以下のように呼び出します。
% goshim ./script/ore/pkg [args...]
これで、プロジェクトリポジトリに雑にGoのツールのソースコードを突っ込んでも、 goshim
で雑に動かしてもらうことができるようになりました。
make
のようにソースコードの mtime を見ているため、コードが更新されていない場合にはキャッシュが使いまわされ、高速に実行できる点もポイントです。
ビルドが必要であっても、ビルド自体に多少は時間はかかりますが、動き出してしまえばGoのバイナリを実行しているのと同じことになるので、ちょっとしたコードを雑にデプロイするのにも便利かもしれません。
go run main.go
とかやるよりも goshim .
の方が短いのも見逃せません。
実行にはgoの環境が必要であり、開発者のためのツールという感じなので、バイナリは提供しない予定です。普通に go get
してみてください。作ってみたら思いの外便利だったので、皆様も是非ご活用ください。
goshim
は syscall.Exec()
を使っているので windowsで動きません。またmattnさんに怒られてしまいそうです。