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
75
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.5k
Other Decks in Technology
See All in Technology
AIで政治は変わるのか? — 中高生と考えたAI時代の民主主義(東海高校サタデープログラム)
eitarosuda
0
390
本当の”仕事”を手放せる未来が見えた
mu7889yoon
0
220
【FinOps】データドリブンな意思決定を目指して
z63d
3
610
グローバルチームと挑むプロダクト開発
sansantech
PRO
1
150
フルAIで個人開発して学んだあれこれ / yuruai vol.1
isaoshimizu
0
180
Agentic AI 時代のテスト手法: Kiro とはじめるプロパティベーステスト (AWS Summit Japan 2026 | DEV212)
ymhiroki
0
210
どうして今サーバーサイドKotlinを選択したのか
nealle
0
200
Why is RC4 still being used?
tamaiyutaro
0
290
AWS Summit Japan 2026の振り返りと2027へ向けて / AWS Summit Japan 2026 Recap and Prospects for 2027
kaminashi
1
200
“全部コピーしない”ファイルデータの活用 : — FSx for ONTAP × S3 Tables × Icebergで作るメタデータカタログ
yoshiki0705
0
420
完全自律ロボットを作りたくて、先に開発を自律させた話(ROS Japan UG #63 LT)
rryz09
0
160
NDIAS CTF 2026 問題解説会資料
bata_24
0
180
Featured
See All Featured
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
Mind Mapping
helmedeiros
PRO
1
280
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
67
56k
Paper Plane
katiecoart
PRO
1
52k
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
0
440
WCS-LA-2024
lcolladotor
0
670
SEO for Brand Visibility & Recognition
aleyda
0
4.6k
How Software Deployment tools have changed in the past 20 years
geshan
0
34k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.8k
The Illustrated Children's Guide to Kubernetes
chrisshort
51
52k
Faster Mobile Websites
deanohume
310
32k
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 のメンテナンスが少し大変) - みんなどうやってるかハッシュタグとかで教えて欲しい〜 まとめ