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.7k
学生が OSS に挑戦すること
takanakahiko
0
3.1k
プリパラで学ぶ プログラミング(&表現の極意)
takanakahiko
0
1.9k
gas-kastu-2
takanakahiko
1
1.4k
Other Decks in Technology
See All in Technology
フロンティアAIのゲート化と地政学リスク
nagatsu
0
130
AWSシリコン最前線 〜AI時代のチップ選択を読み解く〜
htokoyo
2
540
AmazonRoute 53ではじめてのドメイン取得!HTTPS化までの道のりを整理してみた
usanchuu
3
130
"何を作るか"を任される エンジニアは、どう育つのか
yutaokafuji
1
650
AI-DLCを活用した高品質・安全なAI駆動開発実践 / AI Driven Development with AI-DLC
yoshidashingo
0
180
データサイエンスを価値につなげるプロジェクト設計 〜 DS一年目が現場で得た気づき 〜
ysd113
1
220
200個のGitHubリポジトリを横断調査したかった
icck
0
120
自宅LLMの話
jacopen
1
500
Amazon Bedrock AgentCore ワークショップ JAWS UG TOHOKU / amazon-bedrock-agentcore-workshop-jawsug-tohoku-2026
gawa
9
770
LLMにもCAP定理があるという話
harukasakihara
0
310
中期計画、2回作ってみた ~業務委託と正社員、両方の視点から~
demaecan
1
730
AIはどのように 組織のアジリティを変えるのか?
junki
1
610
Featured
See All Featured
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
122
22k
Being A Developer After 40
akosma
91
590k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
2k
Context Engineering - Making Every Token Count
addyosmani
9
960
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.5k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
55k
A Modern Web Designer's Workflow
chriscoyier
698
190k
Imperfection Machines: The Place of Print at Facebook
scottboms
270
14k
Building AI with AI
inesmontani
PRO
1
1.1k
First, design no harm
axbom
PRO
2
1.2k
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
2k
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 のメンテナンスが少し大変) - みんなどうやってるかハッシュタグとかで教えて欲しい〜 まとめ