GolangCI-Lintとは
GolangCI-Lint とは、 Golang の Linter を一元管理するためのツールです。Goはliter一つとってもたくさんあってそれを組み合わせることでCIの信頼度を上げるという珍しい形を推奨しています。そのためこのような一元管理ツールが便利になってきます。
インストール方法
$ docker run --rm -v $(pwd):/app -w /app golangci/golangci-lint:v1.31.0 golangci-lint run -v
$ curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.31.0 # mac $ brew install golangci-lint
実行してみる
Usage
色々オプションはありますが取りあずrunだけ使えば良さそうです。CI組み込みの場合はcacheを使ったり。configとかlintersは基本的には全て後述するファイルで指定する方が良いと思うので言及しません。
golangci-lint -h Smart, fast linters runner. Run it in cloud for every GitHub pull request on https://golangci.com Usage: golangci-lint [flags] golangci-lint [command] Available Commands: cache Cache control and information completion Output completion script config Config help Help linters List current linters configuration run Run this tool in cloud on every github pull request in https://golangci.com for free (public repos) version Version Flags: --color string Use color when printing; can be 'always', 'auto', or 'never' (default "auto") -j, --concurrency int Concurrency (default NumCPU) (default 8) --cpu-profile-path string Path to CPU profile output file -h, --help help for golangci-lint --mem-profile-path string Path to memory profile output file --trace-path string Path to trace output file -v, --verbose verbose output --version Print version Use "golangci-lint [command] --help" for more information about a command.
実行
lintに引っかかるようなコードを書いておき以下を実行しました。linq.goの108行目のsignalのチャネルにバッファーがないという指摘が出てきました。括弧書きでエラーを発見した Linter の名前も出力されます。出力だけでは理解しづらい指摘もこれを元にぐぐることが可能です。
level=info msg="[config_reader] Config search paths: [./ /app / /root]" level=info msg="[lintersdb] Active 10 linters: [deadcode errcheck gosimple govet ineffassign staticcheck structcheck typecheck unused varcheck]" level=info msg="[loader] Go packages loading at mode 575 (types_sizes|compiled_files|deps|exports_file|files|imports|name) took 2.2593314s" level=info msg="[runner/filename_unadjuster] Pre-built 0 adjustments in 2.4586ms" level=info msg="[linters context/goanalysis] analyzers took 4.9483931s with top 10 stages: buildir: 3.9208345s, inspect: 310.9361ms, ctrlflow: 215.3187ms, fact_deprecated: 194.2855ms, printf: 145.8805ms, fact_purity: 138.1187ms, isgenerated: 2.8345ms, ineffassign: 2.6892ms, unmarshal: 376.9µs, SA4020: 375.1µs" level=info msg="[linters context/goanalysis] analyzers took 26.3209ms with top 10 stages: buildir: 24.6488ms, U1000: 1.6721ms" level=info msg="[runner] Processors filtering stat (out/in): autogenerated_exclude: 1/1, exclude-rules: 1/1, uniq_by_line: 1/1, diff: 1/1, max_per_file_from_linter: 1/1, path_shortener: 1/1, skip_dirs: 1/1, exclude: 1/1, max_same_issues: 1/1, max_from_linter: 1/1, severity-rules: 1/1, cgo: 1/1, filename_unadjuster: 1/1, path_prettifier: 1/1, identifier_marker: 1/1, skip_files: 1/1, nolint: 1/1, source_code: 1/1, path_prefixer: 1/1, sort_results: 1/1" level=info msg="[runner] processing took 4.9446ms with stages: nolint: 1.8015ms, autogenerated_exclude: 1.0542ms, source_code: 925.1µs, identifier_marker: 298.3µs, exclude: 276µs, cgo: 212.6µs, sort_results: 59.5µs, filename_unadjuster: 57.7µs, skip_dirs: 51.8µs, severity-rules: 51.1µs, path_prettifier: 25.8µs, skip_files: 16.9µs, max_per_file_from_linter: 16.9µs, max_same_issues: 15.8µs, uniq_by_line: 15.8µs, path_shortener: 14.1µs, max_from_linter: 13.9µs, exclude-rules: 12.7µs, diff: 12.5µs, path_prefixer: 12.4µs" linq.go:108:16: SA1017: the channel used with signal.Notify should be buffered (staticcheck) signal.Notify(sig, os.Interrupt, syscall.SIGTERM) ^ level=info msg="[runner] linters took 3.3437197s with stages: goanalysis_metalinter: 3.2339981s, unused: 103.3664ms" level=info msg="File cache stats: 1 entries of total size 3.5KiB" level=info msg="Memory: 58 samples, avg is 150.8MB, max is 274.3MB" level=info msg="Execution took 5.6239488s"
設定ファイル .golangci.yml
pythonとか他言語の開発ツール同様ドットファイルで構成を定義しておくことで使いたいlinterや無視したい無視したくないルールを書いておくことができます。実行に以下のようなファイルを置いておくことで反映されます。
.golangci.yml
.golangci.yaml
.golangci.toml
.golangci.json