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
3.3k
ゆるやかに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
new(1.26) ← これすき / kamakura.go #8
utgwkk
0
1.5k
tparseでgo testの出力を見やすくする
utgwkk
2
580
go test -json そして testing.T.Attr / Kyoto.go #63
utgwkk
4
1.1k
自動で //nolint を挿入する取り組み / Gopher's Gathering
utgwkk
1
1.8k
君たちはどうコードをレビューする (される) か / 大吉祥寺.pm
utgwkk
21
17k
Dive into gomock / Go Conference 2024
utgwkk
14
8.4k
Goでリフレクションする、その前に / Kansai.go #1
utgwkk
4
3.7k
Go製Webアプリケーションのエラーとの向き合い方大全、あるいはやっぱりスタックトレース欲しいやん / Kyoto.go #50
utgwkk
7
4.3k
ありがとう、create-react-app
utgwkk
4
12k
Other Decks in Programming
See All in Programming
AIコーディングの理想と現実 2026 | AI Coding: Expectations vs. Reality 2026
tomohisa
0
960
要求定義・仕様記述・設計・検証の手引き - 理論から学ぶ明確で統一された成果物定義
orgachem
PRO
19
10k
ご飯食べながらエージェントが開発できる。そう、Agentic Engineeringならね。
yokomachi
1
280
Head of Engineeringが現場で回した生産性向上施策 2025→2026
gessy0129
0
210
API Platformを活用したPHPによる本格的なWeb API開発 / api-platform-book-intro
ttskch
1
120
AWS Infrastructure as Code の新機能 2025 総まとめ 〜SA 4人による怒涛のデモ祭り〜
konokenj
10
3.1k
TipKitTips
ktcryomm
0
150
日本だけで解禁されているアプリ起動の方法
ryunakayama
0
370
nilとは何か 〜interfaceの構造とnil!=nilから理解する〜
kuro_kurorrr
3
1.6k
AHC061解説
shun_pi
0
310
24時間止められないシステムを守る-医療ITにおけるランサムウェア対策の実際
koukimiura
2
180
Go Conference mini in Sendai 2026 : Goに新機能を提案し実装されるまでのフロー徹底解説
yamatoya
0
510
Featured
See All Featured
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.3k
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
280
Stop Working from a Prison Cell
hatefulcrawdad
274
21k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
49
9.9k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
97
GraphQLの誤解/rethinking-graphql
sonatard
75
11k
Paper Plane
katiecoart
PRO
0
47k
Statistics for Hackers
jakevdp
799
230k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
141
35k
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
280
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.2k
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