Upgrade to Pro — share decks privately, control downloads, hide ads and more …

golangci-lint徹底入門

sanposhiho
July 19, 2021
1.2k

 golangci-lint徹底入門

sanposhiho

July 19, 2021
Tweet

More Decks by sanposhiho

Transcript

  1. golangci-lint徹底入門
    @sanposhiho

    View full-size slide

  2. お前 is 誰
    名前: Kensei Nakada / sanposhiho
    所属: 京都大学 4回生
    (卒業できれば)22年入社予定
    期末レポートがやばい
    @sanposhiho
    @sanpo_shiho

    View full-size slide

  3. 目次
    0. golangci-lint とは
    1. golangci-lint の使用方法を学ぶ
    2. golangci-lint に搭載されているlinterを学ぶ
    3. golangci-lint の内部実装を学ぶ

    View full-size slide

  4. 目次
    0. golangci-lint とは
    1. golangci-lint の使用方法を学ぶ
    2. golangci-lint に搭載されているlinterを(ちょっとだけ🙏)学ぶ
    3. golangci-lint の内部実装を学ぶ

    View full-size slide

  5. 後でフルバージョンをZennで公開します

    View full-size slide

  6. golangci-lint とは

    View full-size slide

  7. golangci-lint とは
    > golangci-lint is a Go linters aggregator.
    多くのlinterを搭載しており、同時に実行することができる便利ツール

    View full-size slide

  8. golangci-lint の使用方法を学ぶ

    View full-size slide

  9. 基本的な使い方
    設定ファイルをもとに実行する
    auto fixに対応しているlinterに修正までやってもらう

    View full-size slide

  10. 基本的な使い方
    特定のlinterを実行

    View full-size slide

  11. 設定ファイルを書く
    ・ファイル(.golangci.yml)を用いた設定に対応
    → 設定をかけば golangci-lint run するだけ

    View full-size slide

  12. 基本的な設定内容(linters)
    「linters」ではどのlinterを有効にするかを指定
    ・disable-all →全てのlinterを無効にする
    ・enable-all →全てのlinterを有効にする
    ・disable → 指定したlinterを無効にする
    ・enable → 指定したlinterを有効にする

    View full-size slide

  13. 参考: デフォルトで有効なlinter達

    View full-size slide

  14. 基本的な設定内容(linters)
    - [方針1] enable-all/disable パターン

    - [方針2] disable-all/enable パターン

    View full-size slide

  15. [方針1] enable-all/disable パターン
    ブラックリスト方式で指定できる
    メリット
    新たなlinterが自動で追加される
    デメリット
    バージョンによって実行されるlinterが変化して
    しまう

    View full-size slide

  16. [方針2] disable-all/enable パターン
    ホワイトリスト方式で指定できる
    disable-allはデフォルトで有効なlinterも無効
    にします
    メリット
    実行されるlinterを固定できる
    デメリット
    新しいlinterに追従しにくい

    View full-size slide

  17. 基本的な設定内容(linters)
    - [方針1] enable-all/disable パターン

    - [方針2] disable-all/enable パターン

    どちらを使えばいいの?

    多くのlinterを使いたい → 「1. enable-all/disable パターン」

    新しいlinterを積極的に追加する必要がなく、バージョンアップには既存のバグの修正等のみを求める →「2.
    disable-all/enable パターン」


    View full-size slide

  18. [余談] enable-allは一度非推奨になっていた話
    2019年10月
    こちらのPRでドキュメントに
    > please, do not use enable-all:
    it's deprecated and will be removed
    soon.
    という文言が追加されました

    View full-size slide

  19. [余談] enable-allは一度非推奨になっていた話
    理由
    - 新しいlinterが自動で追加されるのはいいこと
    - だけどCIのビルドが落ちるようになったりとか、一つ一つ新しいlinterを無効に設定
    しなきゃとかめんどくさいよね

    View full-size slide

  20. [余談] enable-allは一度非推奨になりかけた話
    時は流れ…
    2021年6月に
    Un-deprecateに

    View full-size slide

  21. [余談] enable-allは一度非推奨になりかけた話
    - enable-allでしか実現できないメリットがある
    - 新しいlinterの追加など
    - 「CIで落ちる」というのはenable-allの問題ではなく、「enable-allを使う」という選択
    の誤り

    View full-size slide

  22. 基本的な設定内容(run)
    linterの実行に関する設定です。
    skip-dirsとskip-filesのみ紹介します。

    View full-size slide

  23. skip-files
    一致するファイルにはlinterを実行しません

    View full-size slide

  24. skip-dirs
    一致するパス以下にはlinterを実行しません

    View full-size slide

  25. 基本的な設定内容(issues)
    linterの報告に関する設定です。例えば特定の報告を無視するような設定ができたりし
    ます。
    excludeとexclude-rulesのみ紹介します。

    View full-size slide

  26. exclude
    特定の文言を含む報告を全て無視する

    View full-size slide

  27. exclude-rules
    ここで設定したルールに合致する報告は無視される
    - 特定のlinterを特定のファイルには実行しない(path)
    - 特定のlinterの特定の文言の報告を無視する(text)
    - 特定のlinterの特定の箇所の報告を無視する(source)

    View full-size slide

  28. nolintによる報告の無視

    View full-size slide

  29. nolintによる報告の無視

    View full-size slide

  30. nolintによる報告の無視
    nolintの理由を記載する
    TIPS: nolintlintというlinterでnolintの理由が記載されているかどうかを確認できる

    View full-size slide

  31. [余談] nolintのシンタックスはGoの慣習に即していない?

    View full-size slide

  32. [余談] nolintのシンタックスはGoの慣習に即していない?
    - goのツールは//go:*というコメントディレクティブを使用することになっている
    - https://golang.org/cmd/compile/
    - 他のツールも//^[a-z]+:[a-z]+.というフォーマットでコメントディレクティブを使用するの
    が一般的である
    - ちゃんと公式にアナウンスするための以下の issueがたっている
    - https://github.com/golang/go/issues/43776
    - //nolint: hoge (nolint:とhogeの間にスペースがある )と書くこともできるがこれもスペースがあるので
    フォーマットに即していないことになる

    View full-size slide

  33. [余談] nolintのシンタックスはGoの慣習に即していない?
    またnolintは”// nolint” (ただのコメント)と書くこともできる
    → コメントディレクティブの形で統一した方が良いんじゃないかという議論もされている

    View full-size slide

  34. golangci-lint に搭載されているlinterを学ぶ

    View full-size slide

  35. golangci-lint に搭載されているlinterを学ぶ
    全部紹介するのは時間的に厳しいので、sanposhihoが個人的に紹介したいlinterの
    みを取り上げます
    → 「後でZennに上げます」と言っていたものには全てのlinterとその一口解説が載って
    います。
    ここで上げるlinterは勿論golangci-lint上以外からも実行できます。

    View full-size slide

  36. [ちょっとその前に]非推奨のlinterって?
    golangci-lintにはgolangci-lint上での使用を非推奨とされているlinterが存在します
    これらのlinterは将来的にgolangci-lint上から削除される予定です
    具体的にどのようにdeprecation cycleをデザインするかは現在議論中。

    View full-size slide

  37. golint(非推奨)(archived)
    Goのorganization下でメンテナンスされていたlinterです。
    今年の5月に非推奨となり、リポジトリもアーカイブされました
    詳しくは→

    View full-size slide

  38. golint(非推奨)(archived)
    - メンテがされていない
    - 2018年から実質的な変更が加わってない
    - Issueも放置されているものが多い
    - golang orgに存在するlinterなのでGoが公式として推奨しているlinterに見える
    - Go が実際には保守されていないプログラムを公式として推奨しているように見えてしまう
    - 開発者は合理的に異なるスタイルを採用したい場合がある
    - Golint単体で特定の警告を無視したりするなどの機能を持っていない

    View full-size slide

  39. revive
    Golintの代替を目指して開発されたlinter
    先のGolintの課題であるカスタマイズ機能を有しているなどする。
    golangci-lint上ではreviveがgolintの代替として推奨されています。
    https://github.com/mgechev/revive

    View full-size slide

  40. errorlint, goerr113
    errorの比較をerrors.Isを使用していない箇所等を検出します。
    (それ以外もそれぞれ色々検出します)
    Go 1.13からerror型はfmt.Errorf()を使用してwrapすることができ、==などで比較すると
    wrapされているerrorをうまく比較できない場合があります、
    詳しくは→ https://golang.org/pkg/errors/

    View full-size slide

  41. paralleltest, tparallel, thelper
    全てテストに関係するlinterです。
    t.Parallel()やt.Helper()などが使用されているかどうかを確認してくれます。

    View full-size slide

  42. wastedassign
    不要な代入を検出するlinterです。
    僕が作ったので宣伝のために紹介に入れました。(正直でよろしい)
    https://github.com/sanposhiho/wastedassign

    View full-size slide

  43. golangci-lint の内部実装を学ぶ

    View full-size slide

  44. golangci-lint の内部実装を学ぶ
    一歩踏み込んで golangci-lint のlinterを実行する様子をコードベースで追ってみましょ
    う。
    参考にしているのはv1.41.1時点でのコードです。

    View full-size slide

  45. golangci-lint の内部実装を学ぶ
    公式ドキュメントにもArchitectureの章が存在します
    https://golangci-lint.run/contributing/architecture/

    View full-size slide

  46. golangci-lint の内部実装を学ぶ
    ではみてみましょう
    (→sanposhihoが頑張ってGoLandで読んでいきます)

    View full-size slide

  47. 終わりに
    設定の話から始まり、搭載されているlinterの話、内部実装など、golangci-lintへの理解
    が少し深まったのではないでしょうか
    Goにおけるlinterの作成/静的解析に興味が出た人は @tenntenn さんが公開している
    「プログラミング言語Go完全入門」の14章がおすすめです

    https://engineering.mercari.com/blog/entry/goforbeginners/

    View full-size slide