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

golangci-lint徹底入門

sanposhiho
July 19, 2021
920

 golangci-lint徹底入門

sanposhiho

July 19, 2021
Tweet

More Decks by sanposhiho

Transcript

  1. golangci-lint徹底入門
    @sanposhiho

    View Slide

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

    View Slide

  3. View Slide

  4. View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  8. golangci-lint とは

    View Slide

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

    View Slide

  10. View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

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

    View Slide

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

    View Slide

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

    View Slide

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

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

    どちらを使えばいいの?

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

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


    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  31. nolintによる報告の無視

    View Slide

  32. nolintによる報告の無視

    View Slide

  33. View Slide

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

    View Slide

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

    View Slide

  36. [余談] 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 Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

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

    View Slide