追記
scopelintを廃止しました。
注意
某Let's encryptの騒ぎで、まさにこの問題が根幹にあったみたいですね。
Scopelintがもうちょっとちゃんとしていれば…
現在、False positiveが取り除けていません
(ゆえに主要なlinter suiteでdefault offになっています)
contribution、お待ちしています。
動機
golangでforループを回すと、中でうっかりクロージャやリファレンスを取れません。
example/readme.go
package example
import "fmt"
func readme() {
values := []string{"a", "b", "c"}
var funcs []func()
for _, val := range values {
funcs = append(funcs, func() {
fmt.Println(val)
})
}
for _, f := range funcs {
f()
}
/*output:
c
c
c
*/
var copies []*string
for _, val := range values {
copies = append(copies, &val)
}
/*(in copies)
&"c"
&"c"
&"c"
*/
}
意外と気づきにくいバグの元になってプログラマは容易に死にます。
一応一部のケースは go vet
でも検出できますが、万能ではありません。(なぜか go func(){ }()
だけは気をつけてくれる)
ならチェックしようぜ!ということでlinter作りました。
使い方
golint とほぼ同じです。
go get -u github.com/kyoh86/scopelint
でインストールして、雑にパッケージとかディレクトリとかファイルを渡してください。
scopelint github.com/kyoh86/scopelint/example
scopelint ./...
幾つかオプションも用意しました。
-
--set-exit-status
: golintに同じ。エラーがあれば終了コードを1
に設定する。毎回指定するのアホらしいので、デフォルトtrue
。 -
--vendor
:vendor
ディレクトリの下は見ない。これもデフォルトtrue
。 -
--test
:*_test.go
なファイルは見ない。これもデフォry
終わりに
あちこち golint のソースをコピペして作っています。ライセンス書かなきゃ…
とまれ、良きgopherライフを!