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のルールを強くする / Kyoto.go #56
Search
utagawa kiki
December 15, 2024
Programming
2
2.4k
ゆるやかにgolangci-lintのルールを強くする / Kyoto.go #56
Kyoto.go #56
https://kyotogo.connpass.com/event/335437/
utagawa kiki
December 15, 2024
Tweet
Share
More Decks by utagawa kiki
See All by utagawa kiki
go test -json そして testing.T.Attr / Kyoto.go #63
utgwkk
3
310
自動で //nolint を挿入する取り組み / Gopher's Gathering
utgwkk
1
1.1k
君たちはどうコードをレビューする (される) か / 大吉祥寺.pm
utgwkk
21
16k
Dive into gomock / Go Conference 2024
utgwkk
14
7.7k
Goでリフレクションする、その前に / Kansai.go #1
utgwkk
4
3.6k
Go製Webアプリケーションのエラーとの向き合い方大全、あるいはやっぱりスタックトレース欲しいやん / Kyoto.go #50
utgwkk
7
4.2k
ありがとう、create-react-app
utgwkk
4
11k
mockgenによるモック生成を高速化するツール bulkmockgenのご紹介 / Kyoto.go #43
utgwkk
2
2.4k
SPAでもデータをURLでシェアしたい / Kyoto.js 19
utgwkk
2
1.9k
Other Decks in Programming
See All in Programming
スケールする組織の実現に向けた インナーソース育成術 - ISGT2025
teamlab
PRO
1
120
機能追加とリーダー業務の類似性
rinchoku
2
1.3k
AI Coding Agentのセキュリティリスク:PRの自己承認とメルカリの対策
s3h
0
230
Navigation 2 を 3 に移行する(予定)ためにやったこと
yokomii
0
320
AIと私たちの学習の変化を考える - Claude Codeの学習モードを例に
azukiazusa1
10
4.3k
より安全で効率的な Go コードへ: Protocol Buffers Opaque API の導入
shwatanap
1
180
チームのテスト力を鍛える
goyoki
3
460
私の後悔をAWS DMSで解決した話
hiramax
4
210
Kiroで始めるAI-DLC
kaonash
2
610
Namespace and Its Future
tagomoris
6
700
Amazon RDS 向けに提供されている MCP Server と仕組みを調べてみた/jawsug-okayama-2025-aurora-mcp
takahashiikki
1
110
今から始めるClaude Code入門〜AIコーディングエージェントの歴史と導入〜
nokomoro3
0
200
Featured
See All Featured
Understanding Cognitive Biases in Performance Measurement
bluesmoon
29
1.9k
Learning to Love Humans: Emotional Interface Design
aarron
273
40k
Building a Scalable Design System with Sketch
lauravandoore
462
33k
How to Think Like a Performance Engineer
csswizardry
26
1.9k
The Art of Programming - Codeland 2020
erikaheidi
56
13k
Unsuck your backbone
ammeep
671
58k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
50k
Large-scale JavaScript Application Architecture
addyosmani
513
110k
The Invisible Side of Design
smashingmag
301
51k
Building Better People: How to give real-time feedback that sticks.
wjessup
368
19k
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.1k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
580
Transcript
ゆるやかにgolangci-lint のルールを強くする id:utgwkk / @utgwkk (うたがわきき) 2024/12/15 Kyoto.go #56 オフライン忘年LT会@マネフォ京都
1
自己紹介 • うたがわきき (@utgwkk) • 株式会社はてな ◦ Webアプリケーションエンジニア • 好きなパッケージはreflect
2
アジェンダ • golangci-lintについて • lintルールを強くするためにまずやったこと • あとからlintルールを強くするコツ 3
アジェンダ • golangci-lintについて • lintルールを強くするためにまずやったこと • あとからlintルールを強くするコツ 4
golangci-lintについて • https://golangci-lint.run/ • Goのlinterをまとめて実行するrunner • アンケート: golangci-lintを使っている? 5
アジェンダ • golangci-lintについて • lintルールを強くするためにまずやったこと • あとからlintルールを強くするコツ 6
golangci-lintは使っていたが • 最小構成でスタート • 検査しないファイルだけ設定する • デフォルトで有効のlinterのみ • CIで走らせる 7
設定をよくする機運が高まる • 実装ミスがlinterで検知されると嬉しい • どこまで検査してくれるのか知らなかった • 底力を引き出せていないのでは 8
9 よっしゃやっていくぞ
10 まずは何をするか • 全てのlinterを有効にする?
11 全てのlinterを有効にする? • エラーが大量に出てしまう • 既存のコードベースに合わせた調整が困難 • 設定項目が無限にある!!
まずはgolangci-lintを知る (1) • golangci-lint自体の設定項目を知る • どこまで柔軟にできるか・できないか知る • https://golangci-lint.run/usage/configur ation/ 12
まずはgolangci-lintを知る (2) • 搭載されているlinter一覧がある • 上から順番に見ていく • 1つずつ有効にして検査してみる • https://golangci-lint.run/usage/linters/
13
14 golangci-lintを知った • どんなlinterが搭載されているのか知る • 無理なく導入できるlinter・設定が分かる • 既存のコードベースに合わない設定を知る
15 完全に理解した
アジェンダ • golangci-lintについて • lintルールを強くするためにまずやったこと • あとからlintルールを強くするコツ 16
17 あとからlintルールを強くするコツ • linterの象限を考えて導入する • 部分的にlinterを有効化・無効化する
linterの象限 • コーディング規約に合う・合わない • 簡単に導入できる・できない • (他にもあると思うけど簡略化した) 18
コーディング規約に合う • コーディング規約に合う・簡単に導入できる ◦ linterに引っかかるコードがない (多くない) ◦ 機械的に修正できて動作確認が容易である ◦ 設定を少し調整したら有効化できる
• 迷わず有効化する 19
コーディング規約に合う • コーディング規約に合う・簡単に導入できない ◦ 既存のコードが引っかかりまくる ◦ 機械的に修正できるか判断しづらい 20
コーディング規約に合う • 部分的にlinterを有効化できないか検討する ◦ 特定のファイルだけ有効・無効にする ◦ 特定のディレクトリ以下だけ有効・無効にする ◦ 既存のコードに対してlinterを無効化する •
(具体的な実現方法は後述します) 21
コーディング規約に合わない • コーディング規約に合わないlinter • 基本的には導入しなくていいだろう ◦ 簡単には導入できないなら、なおさら ◦ こういうlinterがある、というのを知っておくことは 損にはならない
22
23 部分的にlinterを有効化・無効化する • ファイル単位で切り替える ◦ 例: テストコードかどうかで切り替える • //nolint: ディレクティブを活用する
• 固有のディレクティブを活用する ◦ 例: exhaustruct
24 ファイル単位で切り替える • exclude-files ◦ 指定したファイルは検査しない • exclude-dirs ◦ 指定したディレクトリ以下は検査しない
• exclude-rules ◦ 指定したファイルで有効にするlinterを変える
25 例: テストコードかどうかで切り替える # テストコードでは特定の linterを無効化する例 exclude-rules: - path: _test\.go
linters: - contextcheck - noctx
26 //nolint: を活用する • //nolint: で始まるコメントを書いた行に対す るlintエラーは報告されない ◦ eslint-disable-next-lineみたいなイメージ •
lintエラーを抑制する理由を書ける ◦ //nolint:unused // ここに理由
//nolint: を活用する var x int //nolint:unused // インライン //nolint:unused //
次の行 var y int 27
28 ディレクティブを活用する • linter固有のディレクティブが使える場合があ る ◦ 同じファイル内でも挙動を切り替えられる ◦ 徐々にコードベースを良くする足がかりとなる
29 固有のディレクティブを活用する • 例: exhaustruct ◦ structリテラルの全てのフィールドに値が埋まってい ることを検査するlinter ◦ //exhaustruct:enforce
と書いた次の行だけlinterの 検査対象となる
まとめ • 一気に全部やろうとしない ◦ enable-all, disable-all以外の選択肢もある ◦ 「要はバランス」 • 部分的に有効化できるルールを活用する
◦ 敷いたガードレールに行き手を阻まれないように 30
31 ここから先 時間余ったら・質問があっ たら取り上げるコーナー
トピック集 • linterから見るGoの進化 • 独自linterの運用 (未解決) • 循環的複雑度をlintする? • チームで有効にしているlinter
• ISUCONでもlinterを活用している 32
linterから見るGoの進化 • exportloopref ◦ ループ変数をコピーせずに参照を取るコードを検出する • copyloopvar ◦ ループの先頭でループ変数をコピーするコードを検出する •
linter同士が衝突している? 33
linterから見るGoの進化 • Go 1.22でループ変数がコピーされるように なった ◦ Fixing For Loops in
Go 1.22 • exportlooprefがdeprecatedになった 34
linterから見るGoの進化 • 言語の進化によって正解が変わる • Go 1.23で導入されたiteratorに対する linterもいつかは出てくるでしょう 35
linterから見るGoの進化 • Go 1.22以降のループ変数のコピーについて は以下の資料が詳しい ◦ 詳解 "Fixing For Loops
in Go 1.22" 自作linterを golangci-lintへコントリビュートした話 36
独自linterの運用 (未解決) • 独自linterは意外と簡単に書ける ◦ コツが掴めたらいける ◦ 日本語の情報も割とある ▪ つくってまなぶ静的解析のすすめ
- LayerX エンジニアブロ グ など 37
独自linterの運用 (未解決) • CIにどうやって組み込む? ◦ CIがコケないと無視される (無視してしまう) • golangci-lintにプラグインの仕組みはあるが ◦
カスタムビルドしたバイナリを使う必要がある ◦ linter側でinitでプラグインを登録する必要がある 38
独自linterの運用 (未解決) • go vet -vettoolの仕組みがgolangci-lintでも 使えると楽になりそうだが…… ◦ Goの静的解析ツールを簡単に使うためのエコシステム について考える
#golang - tenntenn.dev 39
独自linterの運用 (未解決) • 既存のlinterで解決できないか検討する ◦ 探すと意外と見つかることもある ◦ 正規表現マッチで事足りるならforbidigoとか • 探したけど見つからない場合
◦ 新規性チャンス 40
独自linterの運用 (未解決) • 作らずに話すのもな、と思って実装した ◦ https://github.com/utgwkk/goqumysqllint ◦ goqu (クエリビルダ) に対するlinter
41
循環的複雑度をlintする? • gocyclo linterで検査できるが • 答えを持ち合わせていない ◦ 最大値をどこに設定すべきか ◦ 「lintエラー」にすべきなのか
42
チームで有効にしているlinter • contextcheck • depguard • exhaustive • exhaustruct •
fatcontext • gocheckcompilerdirec tives • makezero 43 • mirror • misspell • nilerr • noctx • nolintlint • predeclared • reassign • unconvert
contextcheck • context.Contextを引き回しているかどうか検査 するlinter • テストコードでは無効にしている ◦ ヘルパー関数がいっぱいあるから • https://github.com/kkHAIKE/contextcheck
44
exhaustive • enumに対するswitch-caseの分岐が網羅され ているか検査するlinter • https://github.com/nishanths/exhaustive 45
exhaustruct • structの全てのフィールドに値が埋まってい ることを検査するlinter • https://github.com/GaijinEntertainment /go-exhaustruct 46
fatcontext • context.Contextが肥大化するコードを検出 するlinter ◦ 例: forループ内でcontext.Contextを同じ変数に再代 入する • https://github.com/Crocmagnon/fatcon
text 47
gocheckcompilerdirectives • compiler directiveが正しいことを検査する linter ◦ //go: で始まるコメント群のこと • https://github.com/leighmcculloch/goch
eckcompilerdirectives 48
makezero • スライスのlenを指定して初期化したのに appendしているコードを検出するlinter • https://github.com/ashanbrown/makezero 49
misspell • スペルミスを検出するlinter • 同名のツールは有名だと思う ◦ 実はGoのlinterとしても走らせられる • https://github.com/client9/misspell 50
nilerr • 適切にエラーハンドリングできていないコード を検出するlinter ◦ if err != nil の分岐内でエラーを返していない
◦ if err == nil の分岐内でエラーを返している • https://github.com/gostaticanalysis/nilerr 51
noctx • context.Contextを使わずにHTTPリクエス トを送るコードを検出するlinter • https://github.com/sonatard/noctx 52
nolintlint • //nolint コメントが適切に使われていることを 検査するlinter ◦ 抑制するlinterが指定されている、など • https://github.com/ashanbrown/nolintlint 53
predeclared • Goの予約済キーワードと重複する変数名を使っ ていないか検査するlinter ◦ Goの予約済キーワードの一覧 • https://github.com/nishanths/predeclared 54
reassign • package単位のグローバル変数を他のpackageか ら再代入していないか検査するlinter • https://github.com/curioswitch/go-reassign 55
unconvert • 不要な型変換を行うコードを検出するlinter ◦ int型をint型に変換する、など • https://github.com/mdempsky/unconvert 56
チームで有効にしているlinter • いかがでしたか? • デフォルト有効のlinterも有効です 57
ISUCONでもlinterを活用している • 前提: ISUCONについて ◦ >ISUCONとはLINEヤフー株式会社が運営窓口となっ て開催している、お題となるWebサービスを決められ たレギュレーションの中で限界まで高速化を図る チューニングバトルです ◦
https://isucon.net/ 58
ISUCONでもlinterを活用している • 前提: ISUCONについて ◦ つまり? ◦ 8時間でWebサービスを高速にする 59
ISUCONでもlinterを活用している • デフォルト設定でlintされている • 呼んでない関数や使ってない引数が分かる ◦ 実装をスリムにできると有利 ◦ 使ってない実装をじゃんじゃん消せると有利 60