Slide 1

Slide 1 text

チームで運用する golangci-lint の向き合い方 golang.tokyo #35 2024.06.14

Slide 2

Slide 2 text

自己紹介 Sugar Sato (@satoIsSugar) ● 2023年 BuySell Technologies 入社 ● 基盤チーム所属 (Portal/Account) PjM ● Go / Angular / Serverless ○ Go歴: 4年くらい ● 熱帯植物 ○ ビカクシダ ● 猫 ○ Lambda (♀ 2才)

Slide 3

Slide 3 text

プロダクト群「バイセルリユースプラットフォーム Cosmos」の開発が進行中 リユースに必要なすべての機能を提供する 「リユースプラットフォーム Cosmos」の開発が進行中です。 Cosmosを活用して、バイセルグループ全体での業務効率改善やデータドリブン経営の深化を目指しています。 リユースプラットフォーム Cosmos 自社開発のリユース特化業務基幹システムでありサービス群の集合体 買取申込 買取・査定 在庫管理 販売 多様なチャネルで収益最大化 CRM -顧客対応- 買取種別に応じた最適なシステム構築 Visit -訪問買取 - Store -店舗買取 - Promas -商材マスタ - Appraisal -専門査定 - Stock -在庫管理 - EXS -販売管理 - Core -会員管理- Portal -データ利用- Pocket -データ基盤- 買取 専門チームによる真贋・査定と連携 査定 申込 効率的な顧客対応 在庫 在庫管理の最適・効率化 販売 データ 各事業プロセスにある データを一元管理 :基幹システム

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

みなさんは golangci-lint 導入してますか?

Slide 6

Slide 6 text

YES!!

Slide 7

Slide 7 text

どんなルールで運用してますか? なんとなく雰囲気で使っていませんか?

Slide 8

Slide 8 text

僕はそうでした😅 なので立ち返って運用ルールや チームでの向き合い方を考えてみました!

Slide 9

Slide 9 text

アジェンダ golangci-lint とは 01 実際の取り組み 02 まとめ 03

Slide 10

Slide 10 text

golangci-lint とは

Slide 11

Slide 11 text

● 高速リンターランナー ○ 最初に解析したパスのディレクトリからルートまでの全てのディレ クトリにある設定ファイルを探す ○ 使い方 ■ ルールを追加する ● .golangci.(yml|yaml|json|toml) ■ コマンド実行 ● $ golangci-lint -v run ./... golangci-lint

Slide 12

Slide 12 text

● 5つの設定 ○ run (解析時の設定) ○ output (解析結果の出力設定) ○ linters (lintの設定) ■ linters-settings ○ issues (除外設定) ○ severity (issue 重大度設定) 設定ファイル( .golangci.yml )について

Slide 13

Slide 13 text

run configuration ● go ● concurrency ● timeout ● issues-exit-code ● tests ● build-tags ● etc…

Slide 14

Slide 14 text

output configuration ● sort-results ● sort-order ● formats ● print-issued-lines ● print-issued-name ● etc…

Slide 15

Slide 15 text

linters configuration ● disable-all ● enable ● enable-all ● disable ● presets ● fast

Slide 16

Slide 16 text

issues configuration ● exclude-rules ● exclude-files ● exclude-dirs ● exclude ● exclude-use-default ● exclude-generated ● etc…

Slide 17

Slide 17 text

severity configuration ● default-severity ● case-sensitive ● rules ○ linters ○ severity

Slide 18

Slide 18 text

golangci-lint コントリビュータ ● sanposhiho さん ● sivchari さん ● karamaru-alpha さん ○ Goconf 2024 で copyloopvar 等について登壇! ■ めっちゃ良かった....(小並) ● etc…

Slide 19

Slide 19 text

実際の取り組み

Slide 20

Slide 20 text

● 必要最低限の設定 ○ run ○ linters ■ linters-settings ○ issues 自分たちの .golangci.yml

Slide 21

Slide 21 text

● 必要最低限の設定 ○ run ○ linters ■ linters-settings ○ issues 自分たちの .golangci.yml

Slide 22

Slide 22 text

● 必要最低限の設定 ○ run ○ linters ■ linters-settings ○ issues 自分たちの .golangci.yml

Slide 23

Slide 23 text

● 基本的に disable-all で運用 ○ 保守的な運用 ○ デフォルトのルールは全て適用す る ○ メリット ■ 気軽に golangci-lint のバー ジョン挙げられる ○ デメリット ■ 考慮漏れが発生するかも linters の運用方法

Slide 24

Slide 24 text

● enable の中でも Must と Should に分 けてルールを適用している ○ Must ■ golangci-lint のデフォルト true のオプション ○ Should ■ 自分たちとしてコード品質を保 つためのオプション linters の運用方法

Slide 25

Slide 25 text

● 「課題が出たタイミング」 ○ 最近はルール追加することは少ない ■ 運用が安定してきた証拠? ■ (最新の追加されたルールを追えてないだけ...??) ルール追加の基準

Slide 26

Slide 26 text

● チームメンバーと制約について目線合わせする ● “納得感”あるルール作りをしていく ○ 自分本位なルールではないか ○ 本当に必要なルールか ■ 実際に導入してみたら却って「開発効率」を下げていないか ■ もしチームにフィットしなくてメリットがなければ思い切って削 除する ルール追加にあたって気をつけていること

Slide 27

Slide 27 text

チームの運用方法については、わかった じゃあ、どんなルールを採用しているの?

Slide 28

Slide 28 text

● lll ● gocyclo ● goconst ● nestif ● tagliatelle enable に採用しているルール

Slide 29

Slide 29 text

● lll ● gocyclo ● goconst ● nestif ● tagliatelle enable に採用しているルール

Slide 30

Slide 30 text

● 一行あたりの文字数制限 (long line linter) ● Go は1行のあたりの文字数を明確に決めていない ○ https://go.dev/doc/effective_go#formatting ● PHP ○ PSR-12: 80文字 or 120文字 ● Java ○ Oracle: 80文字 ○ Google: 100文字 lll

Slide 31

Slide 31 text

● 自分のチームでは ○ line-length: 140文字 ■ 公式の推奨に合わせている ■ デフォルト120文字 ○ tab-width: 2 ● ignore 設定はテストでも適用しない ○ 可読性を担保する ○ コードレビューの負担を減らす lll

Slide 32

Slide 32 text

● lll ● gocyclo ● goconst ● nestif ● tagliatelle enable に採用しているルール

Slide 33

Slide 33 text

● 循環複雑度 (cyclomatic) ○ 関数のソースコードを通る直 線的に独立したパスの数を数 値にしたもの ○ 詳しい仕様については下記 ■ https://github.com/fzipp/ gocyclo/tree/main gocyclo

Slide 34

Slide 34 text

enable に採用しているルール ● lll ● gocyclo ● goconst ● nestif ● tagliatelle

Slide 35

Slide 35 text

● 定数で置き換え可能な繰り返し文字列を指摘 ○ デフォルト 3回繰り返しまで許可する ○ 割とお気に入りのルール ■ 気がつかないうちに全く同じ変数を書いて いたりするため ■ ignore ルール設定も網羅している goconst

Slide 36

Slide 36 text

goconst

Slide 37

Slide 37 text

enable に採用しているルール ● lll ● gocyclo ● goconst ● nestif ● tagliatelle

Slide 38

Slide 38 text

● if のネスト回数制御 ○ デフォルト 5回以上のネストを許可しない ○ とりあえずいれておくだけで OK! ■ 不要なレビューが減る nestif

Slide 39

Slide 39 text

nestif

Slide 40

Slide 40 text

enable に採用しているルール ● lll ● gocyclo ● goconst ● nestif ● tagliatelle

Slide 41

Slide 41 text

● 読み方:タリアテッレ ● タグ名の制御 ○ field 名と一致させている ○ json から envconfig まで対応して いる ■ https://golangci-lint.run/usa ge/linters/#tagliatelle tagliatelle

Slide 42

Slide 42 text

● タグの記述間違いに気が付き やすく、お気に入り ● ただし、独自の命名ケースなど には対応していない tagliatelle

Slide 43

Slide 43 text

以上が linters に適用しているルール

Slide 44

Slide 44 text

● 必要最低限の設定 ○ run ○ linters ■ linters-settings ○ issues 自分たちの .golangci.yml

Slide 45

Slide 45 text

● 基本的に ignore ルールを適用しない方針 ○ テストコードもプロダクションコード同様に扱い品質を保ちたい ○ どうしても ignore ルールを追加したい時はチームで相談する ○ lint 対象ファイルに勝手に ignore ルールを追加しない issues

Slide 46

Slide 46 text

● ファイル単位で ignore ルールを追 加しない ○ 部分的に // nolint:ルール名 を 追加して適用する ○ チーム相談の上で記述 issues

Slide 47

Slide 47 text

以上が issues の運用方法

Slide 48

Slide 48 text

● レビューの工数を ”少し” でも減らせる ○ PR で「わざわざコメントするほどではないか」をなくせる ■ 心理的負担を減らせる ○ 記述が統一されやすくなり可読性向上がみこめる ○ Go を初めて書くメンバーも「記述が、ぶれにくくて良い」との声も 上がる golangci-lint のメリット

Slide 49

Slide 49 text

● gofmt とあわせて lint ルールから自動で修正してもらえるといいなぁ (願望) ● 参画してくるメンバーへ lint ルール浸透が必要 ○ より改善できるチャンス! 今後の展望や課題

Slide 50

Slide 50 text

まとめ

Slide 51

Slide 51 text

● チームでの運用においては、最小限の設定で効果的に利用する ○ 各設定の適用ルールや除外ルールを柔軟に調整することが重 要だと感じている ● 課題感や改善できる箇所も存在している ○ tagliatelle などに独自ルール追加ができないので自作できたら いいな ○ disable-all を使っているので、本来自分たちにピッタリなルール があるかもしれないが見逃している可能性がある まとめ

Slide 52

Slide 52 text

● golangci-lintの導入により、コード品質の向上やレビュー負担の軽減 といったメリットも享受できている ○ これにより、開発プロセスがスムーズになり、新しいメンバーも記 述のぶれが少なくて済むと感じている まとめ

Slide 53

Slide 53 text

● 導入していなかった人は、ぜひ導入を! ● 導入している人は ○ おすすめの運用方法や、これ適用してないの?など会話した い! みなさんの .golangci.yml はどうですか?

Slide 54

Slide 54 text

THANK YOU

Slide 55

Slide 55 text

● https://github.com/golangci/golangci-lint ● https://github.com/golangci/golangci-lint/blob/master/assets/go.png ● https://www.docswell.com/s/takanakahiko/ZQ864X-2024-05-11-022041#p11 ● https://golangci-lint.run/usage/linters/#tagliatelle ● https://go.dev/doc/effective_go#formatting ● https://www.php-fig.org/psr/psr-12/#23-lines ● https://google.github.io/styleguide/javaguide.html#s3.2-package-statement 引用