この記事はWanoグループ Advent Calendar 2020 の3日目の記事になります。🎅🎁
何をするのか
Golandでは、 gofmt
や goimport
のような静的解析のコマンドは少しの設定でファイル保存時に実行することができます。
今回は自作の静的解析ツールを上と同じように保存時にフックさせてみようと思います。
プロジェクト特有のコマンドをCIで実行しているような場合、それをローカルでも通してからpushしたい! みたいなケースで使えそうです
使うライブラリ
今回は、 TODO
コメントが一つでもあったら怒られるというスパルタコマンドを checom という名前で作成 -> Golandに設定 してみます。
ちなみにTODOコメントに他意はありません
静的解析
コメントを抜き出すだけなら標準のライブラリで十分です。
CLIツール
cobra というCLIツール作成用のライブラリを使っていますが、必須ではないです。
- github.com/spf13/cobra
静的解析ツールの作成
静的解析は標準の go
パッケージを使えば非常に簡単
package main
import (
"fmt"
"go/parser"
"go/token"
"os"
"strings"
"github.com/spf13/cobra"
)
func main() {
if err := rootCmd.Execute(); err != nil {
fmt.Fprintf(os.Stderr, "%s: %v\n", os.Args[0], err)
os.Exit(-1)
}
}
func init() {
cobra.OnInitialize()
}
var rootCmd = &cobra.Command{
Use: "checom",
Run: CommentChecker,
}
const ngWord = "TODO"
func CommentChecker(cmd *cobra.Command, args []string) {
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, args[0], nil, parser.ParseComments)
if err != nil {
fmt.Println(err)
return
}
var cnt int
for _, cg := range f.Comments {
t := cg.Text()
if strings.Contains(strings.ToUpper(t), ngWord) {
cnt++
fmt.Printf("😡 \n%s\n", t)
}
}
if cnt != 0 {
fmt.Println("😡 DO NOW 😡")
return
}
fmt.Println("You're hard worker 😆")
}
f, err := parser.ParseFile(fset, args[0], nil, parser.ParseComments)
arg[0]
にファイルのパスが入ってくる想定で、ファイルをパースしてコメントを引っこ抜いてます。
CLIツールはこれだけで、非常にシンプル
go install
コマンドで $GOPATH/bin/
にバイナリを設置します。
$ cd project/checom
$ go install
$ ll $GOPATH/bin/ | grep checom
-rwxr-xr-x 1 user staff 4922168 11 4 17:03 checom
これで $GOPATH/bin
にパスが通っていれば checom /path/to/file
で実行できるようになりました。
Golandの設定
Golandでは File watcher
というファイル監視機構が用意されているのでそれを使います。
Preference > Tools > File watcher > + > custom
から以下の設定します。
https://pleiades.io/help/go/new-watcher-dialog.html
File type
- どのファイル形式の保存・変更時にフックさせるかの設定です。今回は
Go
ですね。
Program
- ↑のバイナリの置き場所の指定です。
-
$GOPATH$
はGoland側に設定してあるマクロというかエイリアスなので、もし設定していなければ普通にバイナリまでのパスを書いても動きます。
Argument
- コマンドの引数を指定できます。
- 同様に
$FilePath$
はGoland側の設定で、保存・変更したファイルのパスになります。
Show console
- コマンドの実行結果をコンソールに出力する際の設定です。
- デフォルトでは
On error
ですが、今回は全て標準出力に出力するようにしてしまっていたので、Always
にしないと何も表示されません。
ということで、上記を設定することで、Goland上で /path/to/project/hoge.go
を保存・変更した場合に
$GOPATH/bin/checom /path/to/project/hoge.go
が走るようになりました。
動作
小文字でも見逃してくれません。
無事動きました
まとめ
静的解析ツールを作るハードルがかなり低いので、プロジェクト内でもCIなどで必要なニーズが出てきたら簡単に導入できそう。
Golandは全体の2%くらいしか機能を使えてない気がするので、もっと活用していこうという気になりました。
Wanoでは積極的にエンジニア採用を行なっています!
まずはオンラインでVPoEとのカジュアル面談から。お好きな入り口からお気軽にお声がけください!
Wano Recruitページ https://group.wano.co.jp/recruit/
QiitaJobs https://jobs.qiita.com/employers/wano-inc/postings/1297
Wantedly https://www.wantedly.com/companies/wano/projects
Findy https://findy-code.io/companies/522