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 の enable-all で コーディングルールを明確にする試み
Search
takanakahiko
May 10, 2024
Technology
73
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
golangci-lint の enable-all で コーディングルールを明確にする試み
takanakahiko
May 10, 2024
More Decks by takanakahiko
See All by takanakahiko
Vivliostyle Pub の現状と課題 #vivliostyle / Current status and issues of Vivliostyle Pub
takanakahiko
0
1.8k
思いつきで実装した web-demo-suit が そこそこバズってメディアとかにも取り上げられた.pdf
takanakahiko
1
220
オタクLODをやりませんか #uzimaru生誕LT会
takanakahiko
0
140
かしこま! 女児向けアニメのLODをみんなで作ってる話
takanakahiko
0
340
学生だけど OSS 始めちゃいました
takanakahiko
3
2.7k
GAS活 #4 「Claspを用いた モダンGAS開発」
takanakahiko
2
1.8k
学生が OSS に挑戦すること
takanakahiko
0
3.1k
プリパラで学ぶ プログラミング(&表現の極意)
takanakahiko
0
1.9k
gas-kastu-2
takanakahiko
1
1.4k
Other Decks in Technology
See All in Technology
LayerXにおけるセキュリティ管理の現在地と次の一手
tosho
0
250
2026TECHFRESH畢業分享會 - 原生還是跨平台? App 開發踩坑實錄
line_developers_tw
PRO
0
1.3k
Chainlitで作るお手軽チャットUI
ynt0485
0
280
アンオフィシャルな、オフィシャルからのお願い
wyamazak_devrel
0
140
Claude Codeをどのように キャッチアップしているか
oikon48
13
8.6k
2026TECHFRESH畢業分享會 - Lightning Talk - 打造精準高效的 MCP 設計模式與測試實務
line_developers_tw
PRO
0
1.3k
コミュニティの有益性 ~JAWS Days 2026 での体験を通して~ / The Benefits of a Community ~Through My Experience at JAWS Days 2026~
seike460
PRO
0
190
Bucharest Tech Week 2026 - Reinventing testing practices in the AI era
edeandrea
PRO
1
170
SONiCのLinuxベースを活かしたZabbix監視
sonic
0
230
FPC(フレキシブル)基板にZephyr実装してみた。
iotengineer22
0
120
200個のGitHubリポジトリを横断調査したかった
icck
0
140
攻撃者視点で考えるDetection Engineering
cryptopeg
3
2k
Featured
See All Featured
Scaling GitHub
holman
464
140k
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
65
56k
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
310
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
1
1.3k
HDC tutorial
michielstock
2
720
Tell your own story through comics
letsgokoyo
1
960
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
2.1k
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.5k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
610
GraphQLとの向き合い方2022年版
quramy
50
15k
The untapped power of vector embeddings
frankvandijk
2
1.8k
Transcript
golangci-lint の enable-all で コーディングルールを明確にする試み なかひこくん(@takanakahiko) @Asakusa.go #2
誰? @takanakahiko なかひこくん 新横浜(実は浅草の飛び地なんです!)に住んでいます
さっそく 皆さんに質問 type Runer interface { Run() } type Human
struct { name string } func (h *Human) Run() { ... } // 上記の Human が Runer を実装していることを確認する // 皆さんはどっちで書きますか? var _ Runer = &Human{} // ① var _ Runer = (*Human)(nil) // ② Human が Runer を実装して いることを確認したいです。 皆さんならどっちの書き方にし ますか?
- どっちでも問題はない(メリットやデメリットはあるが)と思う - ただしどちらかに統一されていると必要はある(これが大事) こういうのとても多いですよね。 補足: go.dev/doc ではポインタなら②が例示はされている https://go.dev/doc/faq#guarantee_satisfies_interface 自分としては
チームではこういうのを決めて統一する必要がある - 結局どちらに統一するのか? - これを決めるための何かしらの方針が欲しい - なぜそちらの書き方で書くのか? - この理由を明確にしておきたい(とりあえず?明確に必然性があるから?) -
どう徹底(統一)する? - レビュワーが指摘する?でもそれって仕組み化したいよね なんだかんだこういうのが大変なんですよね チームで書くときは?
- go向けのlinter詰め合わせセット - サードパーティで開発されたやつを取り込んでいる形 - 利用者側は .golangci.yml で利用する linter を選択する
- 君だけの最強の .golangci.yml で勝利を勝ち取れ! こういう時に役立つのが golangci-lint
こんな感じで叱ってくれる。 色々なlinterから叱られてるのがわかると思う。
(再掲) 皆さんに質問 type Runer interface { Run() } type Human
struct { name string } func (h *Human) Run() { ... } // 上記の Human が Runer を実装していることを確認する // 皆さんはどっちで書きますか? var _ Runer = &Human{} // ① var _ Runer = (*Human)(nil) // ② Human が Runer を実装して いることを確認したいです。 皆さんならどっちの書き方にし ますか?
そこで golangci-lint enable-all を使ってみる。 すると何やら怒られる。 # .golangci.yml linters: # enable-all
で全てのlinterを有効化 enable-all: true
main.Human is missing field name (exhaustruct) → なるほど!① var _
Runer = &Human{} だとstruct fieldの設定漏れを許 容するようなソースコードになるから指摘されるんだね → struct fieldの設定漏れは検知できる仕組みが欲しいし、それに変な 例外は作りたくなので② var _ Runer = (*Human)(nil) に統一しよう こうやって対応を決めることができる
- やらないことを決める方が負荷が少ない - やらないことの理由を挙げる方が明確にしやすい - linterを逐次設定する方針だと「採用しない理由」がわかりづらい - disable-all かつ enable
で逐次指定する形 - 「イケているlinterが採用されていない!」→「考慮漏れ?」「後回しになっているだ け?」「理由があって対応していない?」と分かりづらい なぜ enable-all ?
この運用をするときの .golangci-lint.yml の例 # https://github.com/takanakahiko/discord-tts/blob/2195764ba46d1d6b251cea4f29b0cd9e6839d824/.golangci.yml linters: enable-all: true disable: -
wsl # 余計な改行をなるべく含まないようにすることで得られる見通しの良さを重視するため - nlreturn # 上記と同様 - gosmopolitan # 現在はi18n/l10nを検討していないため - depguard # 規模的に依存関係の流れを厳格に管理する必要性はないため - forbidigo # いまのところ特に禁止したい表現はないため - gomnd # The linter 'gomnd' is deprecated - execinquery # The linter 'execinquery' is deprecated # 続く (大袈裟だが) 理由をつけてdisableをする
この運用をするときの .golangci-lint.yml の例(2) # 続き linters-settings: varnamelen: ignore-decls: - v
*discordgo.VoiceStateUpdate # パッケージの使用例がその命名であるため - m *discordgo.MessageCreate # パッケージの使用例がその命名であるため revive: rules: - name: unexported-return disabled: true # ireturnへの対応を優先するため # 続く linterの個別設定の カスタマイズにも理由があると嬉しい
この運用をするときの .golangci-lint.yml の例(3) # 続き linters-settings: funlen: lines: 100 #
デフォルトの60だと余計な関数の分割が発生するため statements: 60 # デフォルトの40だと余計な関数の分割が発生するため gomoddirectives: replace-allow-list: - github.com/jonas747/dca # 該当パッケージが壊れているので独自にパッチを当てたものを利用したいため cyclop: max-complexity: 24 # デフォルトの10だと余計な関数の分割が発生するため 現状このリポジトリの最大値は 23なので24を設定。(この場合は「23になるのは仕方がないよね」という共通認識を作れているはず ) こう設定することで、 complexityの最大値を更新するような次の変更があったらそのタイミングで議論の機会が生まれる。
- .golangci.yml の編集のハードルは極力下げるように努力すべき - 必要以上にコーディングに制約を作ることが目的ではない - 「いまこうなっている理由」を明確にしているだけ - 「いまこうなっている理由」より優先すべきものがあったらガンガン変更する -
「今考えたものが最高で絶対的なルール」なんてあり得ない → 後から入る人がその人 たちにとって心地よいルールにしてくれるという信頼をチームで醸成する - disabeの理由として「あとで対応する」もガンガン許容する - 「あとで対応する」ことが分かっているなら目的は達成できている - 「なぜ対応されていないのか分からない」が一番避けるべき状態 注意点
- golangci-lint のアップデート時にlinterが増えるのでメンテが大変 - だが、その時に方針をチームメンバーで話し合えるのは良いことだと思う - 言語のバージョンをあげてから暫くして上げるのがおすすめ (linterが対応する期間 を待つ) -
明らかに不要なlinterにも理由をつけてdisableする必要がある - でも「明らかに」って自分の感想でしかないので、やっぱり明文化は必要だと自分は 思います - 言語化することでジュニアに「当たり前」の感覚を共有するのも大事 デメリット(と感じられそうなもの)
- golangci-lint で enable-all をすると表記のブレが減らせる - 取り上げていないlinterを理由付きで無効化することができる - 「対応していない理由」が明確になる! -
(アップデート時の .golanci.yml のメンテナンスが少し大変) - みんなどうやってるかハッシュタグとかで教えて欲しい〜 まとめ