Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
golangci-lint徹底入門
Search
sanposhiho
July 19, 2021
0
1.6k
golangci-lint徹底入門
7/19 mercari.go #16
https://mercari.connpass.com/event/218434/
sanposhiho
July 19, 2021
Tweet
Share
More Decks by sanposhiho
See All by sanposhiho
kube-scheduler: from 101 to the frontier
sanposhiho
1
98
A Tale of Two Plugins: Safely Extending the Kubernetes Scheduler with WebAssembly
sanposhiho
0
94
人間によるKubernetesリソース最適化の”諦め” そこに見るリクガメの可能性
sanposhiho
2
1.9k
Don't try to tame your autoscalers, tame Tortoises!
sanposhiho
0
630
メルカリにおけるZone aware routing
sanposhiho
2
900
A tale of two plugins: safely extending the Kubernetes Scheduler with WebAssembly
sanposhiho
1
420
メルカリにおけるプラットフォーム主導のKubernetesリソース最適化とそこに生まれた🐢の可能性
sanposhiho
1
760
MercariにおけるKubernetesのリソース最適化のこれまでとこれから
sanposhiho
8
3.9k
The Kubernetes resource management and the behind systems in Mercari
sanposhiho
0
310
Featured
See All Featured
Teambox: Starting and Learning
jrom
132
8.7k
Imperfection Machines: The Place of Print at Facebook
scottboms
264
13k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
131
33k
Happy Clients
brianwarren
97
6.7k
GitHub's CSS Performance
jonrohan
1030
460k
Why Our Code Smells
bkeepers
PRO
334
57k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
126
18k
Code Review Best Practice
trishagee
64
17k
Practical Orchestrator
shlominoach
186
10k
Docker and Python
trallard
40
3.1k
Building Adaptive Systems
keathley
38
2.2k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
7
150
Transcript
golangci-lint徹底入門 @sanposhiho
お前 is 誰 名前: Kensei Nakada / sanposhiho 所属: 京都大学
4回生 (卒業できれば)22年入社予定 期末レポートがやばい @sanposhiho @sanpo_shiho
None
None
目次 0. golangci-lint とは 1. golangci-lint の使用方法を学ぶ 2. golangci-lint に搭載されているlinterを学ぶ
3. golangci-lint の内部実装を学ぶ
目次 0. golangci-lint とは 1. golangci-lint の使用方法を学ぶ 2. golangci-lint に搭載されているlinterを(ちょっとだけ🙏)学ぶ
3. golangci-lint の内部実装を学ぶ
後でフルバージョンをZennで公開します
golangci-lint とは
golangci-lint とは > golangci-lint is a Go linters aggregator. 多くのlinterを搭載しており、同時に実行することができる便利ツール
None
golangci-lint の使用方法を学ぶ
基本的な使い方 設定ファイルをもとに実行する auto fixに対応しているlinterに修正までやってもらう
基本的な使い方 特定のlinterを実行
設定ファイルを書く ・ファイル(.golangci.yml)を用いた設定に対応 → 設定をかけば golangci-lint run するだけ
基本的な設定内容(linters) 「linters」ではどのlinterを有効にするかを指定 ・disable-all →全てのlinterを無効にする ・enable-all →全てのlinterを有効にする ・disable → 指定したlinterを無効にする ・enable
→ 指定したlinterを有効にする
参考: デフォルトで有効なlinter達
基本的な設定内容(linters) - [方針1] enable-all/disable パターン - [方針2] disable-all/enable パターン
[方針1] enable-all/disable パターン ブラックリスト方式で指定できる メリット 新たなlinterが自動で追加される デメリット バージョンによって実行されるlinterが変化して しまう
[方針2] disable-all/enable パターン ホワイトリスト方式で指定できる disable-allはデフォルトで有効なlinterも無効 にします メリット 実行されるlinterを固定できる デメリット 新しいlinterに追従しにくい
基本的な設定内容(linters) - [方針1] enable-all/disable パターン - [方針2] disable-all/enable パターン どちらを使えばいいの?
多くのlinterを使いたい → 「1. enable-all/disable パターン」 新しいlinterを積極的に追加する必要がなく、バージョンアップには既存のバグの修正等のみを求める →「2. disable-all/enable パターン」
[余談] enable-allは一度非推奨になっていた話 2019年10月 こちらのPRでドキュメントに > please, do not use enable-all:
it's deprecated and will be removed soon. という文言が追加されました
[余談] enable-allは一度非推奨になっていた話 理由 - 新しいlinterが自動で追加されるのはいいこと - だけどCIのビルドが落ちるようになったりとか、一つ一つ新しいlinterを無効に設定 しなきゃとかめんどくさいよね
[余談] enable-allは一度非推奨になりかけた話 時は流れ… 2021年6月に Un-deprecateに
[余談] enable-allは一度非推奨になりかけた話 - enable-allでしか実現できないメリットがある - 新しいlinterの追加など - 「CIで落ちる」というのはenable-allの問題ではなく、「enable-allを使う」という選択 の誤り
基本的な設定内容(run) linterの実行に関する設定です。 skip-dirsとskip-filesのみ紹介します。
skip-files 一致するファイルにはlinterを実行しません
skip-dirs 一致するパス以下にはlinterを実行しません
基本的な設定内容(issues) linterの報告に関する設定です。例えば特定の報告を無視するような設定ができたりし ます。 excludeとexclude-rulesのみ紹介します。
exclude 特定の文言を含む報告を全て無視する
exclude-rules ここで設定したルールに合致する報告は無視される - 特定のlinterを特定のファイルには実行しない(path) - 特定のlinterの特定の文言の報告を無視する(text) - 特定のlinterの特定の箇所の報告を無視する(source)
nolintによる報告の無視
nolintによる報告の無視
None
nolintによる報告の無視 nolintの理由を記載する TIPS: nolintlintというlinterでnolintの理由が記載されているかどうかを確認できる
[余談] nolintのシンタックスはGoの慣習に即していない?
[余談] nolintのシンタックスはGoの慣習に即していない? - goのツールは//go:*というコメントディレクティブを使用することになっている - https://golang.org/cmd/compile/ - 他のツールも//^[a-z]+:[a-z]+.というフォーマットでコメントディレクティブを使用するの が一般的である -
ちゃんと公式にアナウンスするための以下の issueがたっている - https://github.com/golang/go/issues/43776 - //nolint: hoge (nolint:とhogeの間にスペースがある )と書くこともできるがこれもスペースがあるので フォーマットに即していないことになる
[余談] nolintのシンタックスはGoの慣習に即していない? またnolintは”// nolint” (ただのコメント)と書くこともできる → コメントディレクティブの形で統一した方が良いんじゃないかという議論もされている
golangci-lint に搭載されているlinterを学ぶ
golangci-lint に搭載されているlinterを学ぶ 全部紹介するのは時間的に厳しいので、sanposhihoが個人的に紹介したいlinterの みを取り上げます → 「後でZennに上げます」と言っていたものには全てのlinterとその一口解説が載って います。 ここで上げるlinterは勿論golangci-lint上以外からも実行できます。
[ちょっとその前に]非推奨のlinterって? golangci-lintにはgolangci-lint上での使用を非推奨とされているlinterが存在します これらのlinterは将来的にgolangci-lint上から削除される予定です 具体的にどのようにdeprecation cycleをデザインするかは現在議論中。
golint(非推奨)(archived) Goのorganization下でメンテナンスされていたlinterです。 今年の5月に非推奨となり、リポジトリもアーカイブされました 詳しくは→
golint(非推奨)(archived) - メンテがされていない - 2018年から実質的な変更が加わってない - Issueも放置されているものが多い - golang orgに存在するlinterなのでGoが公式として推奨しているlinterに見える
- Go が実際には保守されていないプログラムを公式として推奨しているように見えてしまう - 開発者は合理的に異なるスタイルを採用したい場合がある - Golint単体で特定の警告を無視したりするなどの機能を持っていない
revive Golintの代替を目指して開発されたlinter 先のGolintの課題であるカスタマイズ機能を有しているなどする。 golangci-lint上ではreviveがgolintの代替として推奨されています。 https://github.com/mgechev/revive
errorlint, goerr113 errorの比較をerrors.Isを使用していない箇所等を検出します。 (それ以外もそれぞれ色々検出します) Go 1.13からerror型はfmt.Errorf()を使用してwrapすることができ、==などで比較すると wrapされているerrorをうまく比較できない場合があります、 詳しくは→ https://golang.org/pkg/errors/
paralleltest, tparallel, thelper 全てテストに関係するlinterです。 t.Parallel()やt.Helper()などが使用されているかどうかを確認してくれます。
wastedassign 不要な代入を検出するlinterです。 僕が作ったので宣伝のために紹介に入れました。(正直でよろしい) https://github.com/sanposhiho/wastedassign
golangci-lint の内部実装を学ぶ
golangci-lint の内部実装を学ぶ 一歩踏み込んで golangci-lint のlinterを実行する様子をコードベースで追ってみましょ う。 参考にしているのはv1.41.1時点でのコードです。
golangci-lint の内部実装を学ぶ 公式ドキュメントにもArchitectureの章が存在します https://golangci-lint.run/contributing/architecture/
golangci-lint の内部実装を学ぶ ではみてみましょう (→sanposhihoが頑張ってGoLandで読んでいきます)
終わりに 設定の話から始まり、搭載されているlinterの話、内部実装など、golangci-lintへの理解 が少し深まったのではないでしょうか Goにおけるlinterの作成/静的解析に興味が出た人は @tenntenn さんが公開している 「プログラミング言語Go完全入門」の14章がおすすめです ↓ https://engineering.mercari.com/blog/entry/goforbeginners/