Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
golangci-lint徹底入門 @sanposhiho
Slide 2
Slide 2 text
お前 is 誰 名前: Kensei Nakada / sanposhiho 所属: 京都大学 4回生 (卒業できれば)22年入社予定 期末レポートがやばい @sanposhiho @sanpo_shiho
Slide 3
Slide 3 text
No content
Slide 4
Slide 4 text
No content
Slide 5
Slide 5 text
目次 0. golangci-lint とは 1. golangci-lint の使用方法を学ぶ 2. golangci-lint に搭載されているlinterを学ぶ 3. golangci-lint の内部実装を学ぶ
Slide 6
Slide 6 text
目次 0. golangci-lint とは 1. golangci-lint の使用方法を学ぶ 2. golangci-lint に搭載されているlinterを(ちょっとだけ🙏)学ぶ 3. golangci-lint の内部実装を学ぶ
Slide 7
Slide 7 text
後でフルバージョンをZennで公開します
Slide 8
Slide 8 text
golangci-lint とは
Slide 9
Slide 9 text
golangci-lint とは > golangci-lint is a Go linters aggregator. 多くのlinterを搭載しており、同時に実行することができる便利ツール
Slide 10
Slide 10 text
No content
Slide 11
Slide 11 text
golangci-lint の使用方法を学ぶ
Slide 12
Slide 12 text
基本的な使い方 設定ファイルをもとに実行する auto fixに対応しているlinterに修正までやってもらう
Slide 13
Slide 13 text
基本的な使い方 特定のlinterを実行
Slide 14
Slide 14 text
設定ファイルを書く ・ファイル(.golangci.yml)を用いた設定に対応 → 設定をかけば golangci-lint run するだけ
Slide 15
Slide 15 text
基本的な設定内容(linters) 「linters」ではどのlinterを有効にするかを指定 ・disable-all →全てのlinterを無効にする ・enable-all →全てのlinterを有効にする ・disable → 指定したlinterを無効にする ・enable → 指定したlinterを有効にする
Slide 16
Slide 16 text
参考: デフォルトで有効なlinter達
Slide 17
Slide 17 text
基本的な設定内容(linters) - [方針1] enable-all/disable パターン - [方針2] disable-all/enable パターン
Slide 18
Slide 18 text
[方針1] enable-all/disable パターン ブラックリスト方式で指定できる メリット 新たなlinterが自動で追加される デメリット バージョンによって実行されるlinterが変化して しまう
Slide 19
Slide 19 text
[方針2] disable-all/enable パターン ホワイトリスト方式で指定できる disable-allはデフォルトで有効なlinterも無効 にします メリット 実行されるlinterを固定できる デメリット 新しいlinterに追従しにくい
Slide 20
Slide 20 text
基本的な設定内容(linters) - [方針1] enable-all/disable パターン - [方針2] disable-all/enable パターン どちらを使えばいいの? 多くのlinterを使いたい → 「1. enable-all/disable パターン」 新しいlinterを積極的に追加する必要がなく、バージョンアップには既存のバグの修正等のみを求める →「2. disable-all/enable パターン」
Slide 21
Slide 21 text
[余談] enable-allは一度非推奨になっていた話 2019年10月 こちらのPRでドキュメントに > please, do not use enable-all: it's deprecated and will be removed soon. という文言が追加されました
Slide 22
Slide 22 text
[余談] enable-allは一度非推奨になっていた話 理由 - 新しいlinterが自動で追加されるのはいいこと - だけどCIのビルドが落ちるようになったりとか、一つ一つ新しいlinterを無効に設定 しなきゃとかめんどくさいよね
Slide 23
Slide 23 text
[余談] enable-allは一度非推奨になりかけた話 時は流れ… 2021年6月に Un-deprecateに
Slide 24
Slide 24 text
[余談] enable-allは一度非推奨になりかけた話 - enable-allでしか実現できないメリットがある - 新しいlinterの追加など - 「CIで落ちる」というのはenable-allの問題ではなく、「enable-allを使う」という選択 の誤り
Slide 25
Slide 25 text
基本的な設定内容(run) linterの実行に関する設定です。 skip-dirsとskip-filesのみ紹介します。
Slide 26
Slide 26 text
skip-files 一致するファイルにはlinterを実行しません
Slide 27
Slide 27 text
skip-dirs 一致するパス以下にはlinterを実行しません
Slide 28
Slide 28 text
基本的な設定内容(issues) linterの報告に関する設定です。例えば特定の報告を無視するような設定ができたりし ます。 excludeとexclude-rulesのみ紹介します。
Slide 29
Slide 29 text
exclude 特定の文言を含む報告を全て無視する
Slide 30
Slide 30 text
exclude-rules ここで設定したルールに合致する報告は無視される - 特定のlinterを特定のファイルには実行しない(path) - 特定のlinterの特定の文言の報告を無視する(text) - 特定のlinterの特定の箇所の報告を無視する(source)
Slide 31
Slide 31 text
nolintによる報告の無視
Slide 32
Slide 32 text
nolintによる報告の無視
Slide 33
Slide 33 text
No content
Slide 34
Slide 34 text
nolintによる報告の無視 nolintの理由を記載する TIPS: nolintlintというlinterでnolintの理由が記載されているかどうかを確認できる
Slide 35
Slide 35 text
[余談] nolintのシンタックスはGoの慣習に即していない?
Slide 36
Slide 36 text
[余談] 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の間にスペースがある )と書くこともできるがこれもスペースがあるので フォーマットに即していないことになる
Slide 37
Slide 37 text
[余談] nolintのシンタックスはGoの慣習に即していない? またnolintは”// nolint” (ただのコメント)と書くこともできる → コメントディレクティブの形で統一した方が良いんじゃないかという議論もされている
Slide 38
Slide 38 text
golangci-lint に搭載されているlinterを学ぶ
Slide 39
Slide 39 text
golangci-lint に搭載されているlinterを学ぶ 全部紹介するのは時間的に厳しいので、sanposhihoが個人的に紹介したいlinterの みを取り上げます → 「後でZennに上げます」と言っていたものには全てのlinterとその一口解説が載って います。 ここで上げるlinterは勿論golangci-lint上以外からも実行できます。
Slide 40
Slide 40 text
[ちょっとその前に]非推奨のlinterって? golangci-lintにはgolangci-lint上での使用を非推奨とされているlinterが存在します これらのlinterは将来的にgolangci-lint上から削除される予定です 具体的にどのようにdeprecation cycleをデザインするかは現在議論中。
Slide 41
Slide 41 text
golint(非推奨)(archived) Goのorganization下でメンテナンスされていたlinterです。 今年の5月に非推奨となり、リポジトリもアーカイブされました 詳しくは→
Slide 42
Slide 42 text
golint(非推奨)(archived) - メンテがされていない - 2018年から実質的な変更が加わってない - Issueも放置されているものが多い - golang orgに存在するlinterなのでGoが公式として推奨しているlinterに見える - Go が実際には保守されていないプログラムを公式として推奨しているように見えてしまう - 開発者は合理的に異なるスタイルを採用したい場合がある - Golint単体で特定の警告を無視したりするなどの機能を持っていない
Slide 43
Slide 43 text
revive Golintの代替を目指して開発されたlinter 先のGolintの課題であるカスタマイズ機能を有しているなどする。 golangci-lint上ではreviveがgolintの代替として推奨されています。 https://github.com/mgechev/revive
Slide 44
Slide 44 text
errorlint, goerr113 errorの比較をerrors.Isを使用していない箇所等を検出します。 (それ以外もそれぞれ色々検出します) Go 1.13からerror型はfmt.Errorf()を使用してwrapすることができ、==などで比較すると wrapされているerrorをうまく比較できない場合があります、 詳しくは→ https://golang.org/pkg/errors/
Slide 45
Slide 45 text
paralleltest, tparallel, thelper 全てテストに関係するlinterです。 t.Parallel()やt.Helper()などが使用されているかどうかを確認してくれます。
Slide 46
Slide 46 text
wastedassign 不要な代入を検出するlinterです。 僕が作ったので宣伝のために紹介に入れました。(正直でよろしい) https://github.com/sanposhiho/wastedassign
Slide 47
Slide 47 text
golangci-lint の内部実装を学ぶ
Slide 48
Slide 48 text
golangci-lint の内部実装を学ぶ 一歩踏み込んで golangci-lint のlinterを実行する様子をコードベースで追ってみましょ う。 参考にしているのはv1.41.1時点でのコードです。
Slide 49
Slide 49 text
golangci-lint の内部実装を学ぶ 公式ドキュメントにもArchitectureの章が存在します https://golangci-lint.run/contributing/architecture/
Slide 50
Slide 50 text
golangci-lint の内部実装を学ぶ ではみてみましょう (→sanposhihoが頑張ってGoLandで読んでいきます)
Slide 51
Slide 51 text
終わりに 設定の話から始まり、搭載されているlinterの話、内部実装など、golangci-lintへの理解 が少し深まったのではないでしょうか Goにおけるlinterの作成/静的解析に興味が出た人は @tenntenn さんが公開している 「プログラミング言語Go完全入門」の14章がおすすめです ↓ https://engineering.mercari.com/blog/entry/goforbeginners/