Slide 1

Slide 1 text

2024/02/07 【Oracle Cloud Hangout Cafe Season 8 #1 】 株式会社IDCフロンティア 岡本泰典 BB流 golangci-lintのイロハ

Slide 2

Slide 2 text

Agenda ● WHORU? ● golangci-lintってなに? ● BBが思う「これはいいぞ」Linter 集 ● BB流 golangci-lint の活用方法 ● まとめ

Slide 3

Slide 3 text

岡本泰典 a.k.a BigBaBy 株式会社IDCフロンティア KaaS Engineer (Storage, Network etc...) ◆趣味 DJ、たまにVJ(Visual Jockey)もします ◆最近の出来事 Cloud Native Days Tokyo 2024 Co-chair に就任しました @taisuke_bigbaby WHORU?

Slide 4

Slide 4 text

本LTのgolangci-lintに関することはBB本人の経 験と調査に基づくものであり、全ての見解は、BB自 身のものです。 CAUTION

Slide 5

Slide 5 text

golangci-lintってなに?

Slide 6

Slide 6 text

● Goの便利な静的解析ツールの1つ ● 1つで多くのLinterを管理・実行が可能 ● 複数のLinterを並列に実行可能 ● キャッシュで高速化を実現 ● YAMLファイルでの設定管理 ○ TOML, JSONでも可 ● 様々なエディタやIDEでサポート golangci-lint https://github.com/golangci/golangci-lint/blob /master/assets/go.png

Slide 7

Slide 7 text

デフォルトで有効化されているLinter Description Preset 未チェックエラーをチェックする bugs, error Linter errcheck gosimple govet ineffassign staticcheck unused 不要なコードを簡素化してくれる style コンパイラとは別の観点でチェックを行い サジェストをしてくれる bugs, metalinter 不要な代入をチェック unused govetよりも包括的にチェックを行う bugs, metalinter 未使用の変数や定数、関数や型などをチェック する unused

Slide 8

Slide 8 text

● 下のコマンドを実行するだけで良い 一般的な操作 # 設定ファイルがない場合、全てデフォルトの設定値で実行 # 実行したディレクトリ直下に設定ファイルがある場合、そのファイルを参照 $ golangci-lint run ● --fix オプションをつけることで自動的に修正 # Auto Fixに対応しているLinterにのみ有効 $ golangci-lint run --fix

Slide 9

Slide 9 text

設定ファイルの構成 run: # golangci-lintの実行に関する設定 option: value output: # 出力時の設定 option: value linters-settings: # Linter固有の設定 option: value linters: # 使用するLinterに関する設定 option: value issues: # Linterの報告に関しての設定 (特定の報告を無視するなど) option: value severity: # issuesに対する重要度の設定 option: value

Slide 10

Slide 10 text

Field: run (一部抜粋) ● concurrency ○ 実行時に使用するCPU数 (Default: マシンの論理CPU数) ● timeout ○ タイムアウト時間 (Default: 1min) ● tests ○ テストファイル(XXX_test.go)を解析に含むかどうか (Default: true) ● skip-dirs / skip-files ○ 除外するディレクトリ・ファイルの設定 (Default: []) ● allow-parallel-runners ○ 並列実行の可否 (Default: false) ■ デフォルトでは、シーケンシャルな実行を行っている ● go ○ Goのバージョン制御を行う

Slide 11

Slide 11 text

Field: output (一部抜粋) ● format ○ 出力時の形式を設定 (Default: colored-line-number) ■ line-number, json, colored-tab, tab, checkstyle, code-climate, junit-xml, github-actions, teamcity ○ カンマ区切りで複数指定することができ、フォーマット名とパスをコロン記号で区切る ことで、それぞれに出力を与えることができる output: format: checkstyle:report.xml, json:stdout, colored-line-number

Slide 12

Slide 12 text

Field: linters ● disable-all ○ すべてのLinterを無効化 (Default: false) ● enable-all ○ すべてのLinterを有効化 (Default: false) ● enable ○ 指定したLinterを有効化 ● disable ○ 指定したLinterを無効化 ● presets ○ Preset別にLinterを有効化 ● fast ○ 有効化されたLinterから実行結果が早かったもののみを実行する (Default: false) ■ なので、最初の実行は高速にならない

Slide 13

Slide 13 text

Field: linters-settings ● Linterごとの固有の設定を記述 ○ 詳しい設定は公式ドキュメントを参考にするのが良い ■ Linters | golangci-lint

Slide 14

Slide 14 text

Field: issues (一部抜粋) ● exclude ○ 特定の文言を含むissueを無視する ● exclude-rules ○ path ■ 特定のLinterを指定したファイルには実行しない ○ path-except ■ 特定のLinterを指定したファイル以外には実行しない ○ text ■ 特定のLinterの文言を含むissueを無視する ○ source ■ 特定のLinterの箇所のissueを無視する ● 例: ^//go:generate

Slide 15

Slide 15 text

Field: severity (一部抜粋) ● default-severity ○ issueのデフォルトの重大度を設定する (Default: "") ○ 深刻度のルールが定義されており、問題が一致しない場合やルールに深刻度が提供さ れていない場合は、これが適用されるデフォルトの深刻度になる ● rules ○ Linterごとにseverityを設定可能 severity: rules: - linters: - dupl severity: info

Slide 16

Slide 16 text

BBが思う「これはいいぞ」Linter 集

Slide 17

Slide 17 text

gofumpt ● gofmtをもう少し厳格化したLinter ○ ただし、gofmtと後方互換性をもっているgofmtとの違い ○ 1. フォーマットのスタイル ■ Goの公式のformatterに厳格で一貫性のあるスタイルルールを追加している ○ 2. セミコロンの自動挿入は行わない ■ Goのコーディングスタイルではセミコロンを明示的に記述する必要がないため ○ 3. インポート文の整理 ■ インポート文を整理し、アルファベット順に並べ替える ■ また、不要なインポート文を削除する ○ 4. スペースの挿入と削除 ■ コード内のスペースの挿入と削除を行い、一貫性のあるスペースの配置を確保する ● Auto Fixに対応

Slide 18

Slide 18 text

gci ● goimportsと同じで、Goパッケージのインポート順序を制御 ○ 結果が一意に決定される ● Auto Fix対応 package main import ( "fmt" go "github.com/golang" _ "github.com/golang/blank" . "github.com/golang/dot" "github.com/daixiang0/gci" _ "github.com/daixiang0/gci/blank" . "github.com/daixiang0/gci/dot" ) package main import ( "fmt" go "github.com/golang" "github.com/daixiang0/gci" _ "github.com/daixiang0/gci/blank" _ "github.com/golang/blank" . "github.com/daixiang0/gci/dot" . "github.com/golang/dot" )

Slide 19

Slide 19 text

その他のBBおすすめLinter ● dupl ○ 重複しているコードを検知し、冗長化を防ぐ ● misspell ○ スペルミスを検知 (Auto Fix対応) ■ localeのオプションはUSとUKを選べるが、USでいいかも? ● unconvert ○ 不要な型の変換を検知 ● whitespace ○ 関数や、if文、for文などに不要な改行がないかを検知 ● go-critic ○ 「これでもか!」ってくらいに解析をしてほしい人向け ○ より細かい範囲まで検知をおこなってくれます

Slide 20

Slide 20 text

BB流 golangci-lint の活用方法

Slide 21

Slide 21 text

● 基本的に、デフォルトで有効になっているLinterはそのままでいい ○ ソフトウェア品質を担保するためのツールは十二分に用意されている まず、「郷に入っては郷に従え」(Goだけに)

Slide 22

Slide 22 text

○ GitHub Actionsの場合 ■ GitHubではすでにプラグインが存在しているため導入も簡単 ● キャッシュなども設定でよしなに設定してくれるので楽ちん ■ 下図のような感じでUIでもわかりやすく検知箇所を教えてくれる CIには必ず組み込むべし https://github.com/golangci/golangci-lint-action/blob/master/static/annotations.png

Slide 23

Slide 23 text

● 様々なエディタに簡単に組み込むことが可能 ● VSCodeの場合 ○ プロジェクト配下に.vscodeディレクトリを作成し、以下のsetting.jsonを追加 ■ チームでの検知差分をなくす ローカルとCIの環境は統一化する { "go.lintTool": "golangci-lint", "go.lintFlags": [ "--config=${workspaceFolder}/.golangci-lint.yaml", "--fast" ] }

Slide 24

Slide 24 text

○ //nolintって? ■ golangci-lintにおいて記述した箇所の検知を無視することができる ● 「//nolint:linter」で特定のLinterのみ無視することも可能 ○ ただ、むやみにつけることは良くない ■ nolintの記載した理由は明記しておくことがベスト ● 「やむを得ない」ときに使いましょう ○ nolintを付与するときの基準 ■ 意図的な例外 ■ 外部ライブラリや自動生成コードの適用 //nolintはむやみに使わない

Slide 25

Slide 25 text

○ メンバーとの検知差分をなくすため、ファイルは必ず作成したほうが良い ○ 最初の linters-settings の設定は最低限で ■ 使用していく中で、各Linterをチューニングしていくのが良い ○ disable-all VS enable-all ■ disable-all ● 必要最低限のLinterを絞りたい人はオススメ ● 既存のバグの修正等のみを求める場合は、この設定でOK ■ enable-all ● 新しいLinterを積極的に使いたい ● ただし、アップデート時の追従は少し辛さを感じることも... 設定ファイルはシンプルに

Slide 26

Slide 26 text

まとめ

Slide 27

Slide 27 text

○ まずは触ってみよう ■ デフォルトの設定のままでも良い ○ Linterにも似たものはたくさんある ■ デフォルトのLinterは厳格なものはあまり入っていない ■ チーム、環境にあった強度のものを選ぶのが良い ○ Linterに興味を持った方 ■ ぜひ自分で作成してみましょう!! ● https://tenntenn.dev/ja/analysis/ まとめ