Kotlin開発におけるリンター比較

# 自己紹介
どうも、ikasumi1503です。プログラミング初心者です。
最近JetpackComposeを始めて早速[テトリスアプリ](https://qiita.com/ikasumi1503/items/df81c54a21156b779532)を作りました。そこで、やはりコードの中身をチェックしてくれるリンターツールがないと開発が厳しいので、さっそくリンターを導入していきたいです。というわけで、Kotlin開発においてどんなリンターがあるかを比較していきます。
# 簡単比較
| ツール | 目的 | 対応言語 | 設定自由度 | 自動修正 | リンク |
|:-:|:-:|:-:|:-:|:-:|:-:| 
| Ktlint  | コード整形 | Kotlin | △ | 〇 |[公式](https://pinterest.github.io/ktlint/latest/)<br>[記事](https://qiita.com/ikasumi1503/items/5639d4650bc13be519f0)|
| Detekt  | 構造チェック | Kotlin | 〇 | △ |[公式](https://detekt.dev/)<br>[記事](https://qiita.com/ikasumi1503/items/3300d4fa9a9875f8e6f5)|
| SonarQube | 構造チェック + <br>セキュリティ面など | Kotlin, Java, etc. | 〇 | × |[公式](https://www.sonarsource.com/jp/products/sonarqube/?s_content=SonarQubeServer&s_term=sonarqube&s_category=Paid&s_source=Paid%20Search&s_origin=Google&cq_src=google_ads&cq_cmp=22287288393&cq_con=181349452248&cq_term=sonarqube&cq_med=&cq_plac=&cq_net=g&cq_pos=&cq_plt=gp&gad_campaignid=22287288393)|
| Slack Compose lints | 構造チェック | JetpackCompose | △ | × |[公式](https://slackhq.github.io/compose-lints/)[記事](https://qiita.com/ikasumi1503/items/937b460400a50f87c7ae)|
| Android Lint  | 構造チェック | Kotlin, Java, XML | 〇 | △ |[公式](https://developer.android.com/studio/write/lint?hl=ja)|

設定自由度...〇→詳細設定可、△→一部設定可能
自動修正...〇→可能、△→一部可能、×...不可(orほとんど不可)

※ Android lintはルートディレクトリで``./gradlew lint``コマンドを実行すると手動リントによる警告表示ができ、Android Studioではデフォルトで自動リントが働いているため記事は省略します。

※ SonarQubeのセットアップなどは別投稿者様の[記事1](https://zenn.dev/siva_dev/articles/sonarqube-onboarding),[記事2](https://qiita.com/yuu_1st/items/65074133a7ea12d54d03), [記事3](https://techblog.insightedge.jp/entry/static-analysis-tool-comparison)を参照してください。

# 組み合わせの例

Kotlin開発 → Ktlint + Detekt + Android lint
Jetpack Compose開発 → Slack Compose lint + Ktlint + Detekt + Android lint
大規模開発 → 上記 + SonarQube

といった感じになると思います。

# 詳しく説明

### Ktlint
　Kotlin coding conventionsとAndroid Kotlin Style Guideに則ったコードチェックをしてくれます。コードの見た目のルールを管理してくれます。これがないと見た目がバラバラで読みにくくなり、バグの温床となります。例えば、次のようなものを管理してくれます。
- 関数や変数の命名規則（camelCase を守っているか）
- インデントや空白の使い方（タブではなくスペースを使う、演算子の前後に空白を入れる）
- 中括弧 {} の配置（改行する位置やブロックの書き方）
- 不要なセミコロンや import の検出と除去
- 改行位置や1行の文字数の上限

　設定の自由度はわざと低くされているようですが、複数プロジェクトでも似たようなコードにすることができたり、設定をいじくりまわして実装に取り掛かれないようなことがないようになって、これはこれでアリっぽいです。また、自動修正をサポートしてくれている点もありがたいです。

 ### Detekt
 　コードの書き方のルールはKtlintに任せればいい一方で、構造的な問題はこちらのDetektのほうが得意みたいです。Detektでは次のようなものを管理してくれます。
- 関数の長さやネストの深さ ... 単一責任の原則（SRP）を守っているか、読みやすい関数構造になっているかをチェックします
- 複雑度（Cyclomatic Complexity）... if, when, loop などが多すぎる関数は警告されます
- 命名規則に則っているかをチェックします
- 未使用のコードが残っていないか検出します
- 外部に公開すべきでないクラス・メソッドが public になっていないかを指摘します
- 設計上のアンチパターン ... データクラスにビジネスロジックが含まれていたり、ユーティリティクラスが乱用されていないかをチェックします

　設定の自由度はあるようで、detekt.ymlに記述することで設定していけるようです。自動修正はKtlintに任せてよさそうです。不要な ;（セミコロン）の削除や不要な import の削除はDetektでも自動でしてくれるみたいですが、「整形は自動(Ktlint)、設計ミスは警告(Detekt)」の分担分けをするとよさそうです。

### SonarQube
　SonarQubeはDetektと近いですが、構造チェックに加えてセキュリティ面やハードコードチェックなどを追加でできるようです。ただし、Detektと比べて重いです。検査速度、運用コスト、セットアップ工数など、大掛かりになりがちなようです。プロジェクトがある程度完成したらこれを使ってみるくらいでいいかもしれません。次のような感覚で使うといいかと思います。
 
Ktlint = 歯磨き
Detekt = 歯医者への定期健診
SonarQube = 病院でのMRIみたいな精密検査

Detektと同じく設定自由度はあるようですが、ルールの設定はWEBのほうからやるようです。UIベースでやるということで、初心者でも扱いやすいと思います。

### Slack Compose lints
　上記3つはKotlin用のリンターについてまとめました。一方でSlack Compose lintsはJetpackComposeというKotilinの宣言型UIフレームワーク用のLinterです。Slack Compose lintsを使うと、次のようなリンター設定ができます。

- Modifier の順序チェック ... UIのスタイルを決めていくModifierのプロパティの順番が逆だと期待外れの表示につながるため、推奨通りであるかをチェックします
- remember の誤用検出 ... remember { ... } の中で重い処理をしていたりしないか検出します
- 重い処理を @Composable 関数の中で実行しているようなコードを警告します
- Slot API の誤用 ... ある親コンポーザブルの子コンポーザブルをcontent()のような形で書くことがあります。その時に使われるのがSlotAPIなのですが、その時に適切な Modifier の適用やネストの仕方がされているかをチェックします

### Android lint
　こちらはAndroid Studioを利用する際に必ずついてくるリンターになります。これがあると次のようなことができます。

- リソースのハードコード検出 ... android:text="こんにちは" のように直接文字列を埋め込むと、国際化（i18n）対応できなくなるため、@string/ リソースを使うよう警告されます
- 非推奨 API の使用警告 ... 廃止されたメソッドやクラス（例：AsyncTask）を使っている場合に、それを検知して推奨される代替APIを提案してくれます
- パーミッション漏れの警告 ... 位置情報やカメラなど、特定の機能を使うコードがあるのに AndroidManifest.xml に必要なパーミッションが宣言されていない場合に警告します
- 未使用リソースの検出 ... res/ フォルダ内にある使われていない画像、文字列、スタイルなどを検出し、削除候補として提示してくれます

AndroidStudioに触っていたらおなじみのエラーが出てくる感じですね。


# おわりに
Kotlin開発の時に必要となるリンターの比較についてまとめていきました。
次回からは引き続き、それぞれのリンター設定についてまとめていこうと思います。