Spring Bootにktlintを導入する方法

## はじめに
今回はSpring Bootプロジェクトにktlintを導入して、コードスタイルを統一する方法を紹介します。ktlintはKotlinコードの静的解析ツールで、コードのフォーマットを自動的にチェックして修正することができます。

## 1. プロジェクトの作成
Spring Initializrを利用してGradle - Kotlinのプロジェクトを作成します。
https://start.spring.io/


## 2.ktlintをGradleに追加
build.gradle.ktsファイルを開き、以下のようにktlintを設定します。

```gradle
plugins {
   id("org.springframework.boot") version "3.3.0"
   id("io.spring.dependency-management") version "1.1.5"
   kotlin("jvm") version "1.9.24"
   kotlin("plugin.spring") version "1.9.24"
   id("org.jlleitschuh.gradle.ktlint") version "12.1.1" ★
}
```

https://plugins.gradle.org/plugin/org.jlleitschuh.gradle.ktlint

## 3.ktlintの実行
ktlintを実行して、コードスタイルをチェックすることができます。

```shell
./gradlew ktlintCheck
```

これで、ktlintがコードをチェックして問題があれば表示されます。

試しに、チェックに引っかかる可能性のあるKotlinファイルを作成します。
例えば、*src/main/kotlin/com/example/demo/controller/ExampleController.kt*というファイルを作成し、以下のような内容にします。

```kotlin
package com.example.demo.controller
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController

@RestController
class ExampleController {
    @GetMapping("/example")
    fun example(): String {
        val greeting     = "Hello, world!"
        return greeting
    }
    fun anotherFunction(): Int {
        return 1
    }
}
```

このコードには以下のようなスタイル上の問題があります。

val greetingの後に不要な空白がある
メソッド間に空行がない

この状態で、./gradlew ktlintCheckを実行すると以下のようなエラーが発生します。

```shell
> Task :ktlintMainSourceSetCheck FAILED
demo/src/main/kotlin/com/example/demo/controller/ExampleController.kt:10:22 Unnecessary long whitespace
demo/src/main/kotlin/com/example/demo/controller/ExampleController.kt:13:5 Expected a blank line for this declaration

FAILURE: Build failed with an exception.
```

## 4.自動フォーマットの実行
問題が見つかった場合、自動的に修正することもできます。

```shell
./gradlew ktlintFormat
```

このコマンドを実行すると、3の項目で作成したコードをktlintが自動でフォーマットしてくれます。

## 5. .editorconfigについて
.editorconfigファイルをプロジェクトのルートディレクトリに追加して、フォーマットルールを設定することができます。以下は基本的な設定例です。

```kotlin
root = true

[*]
indent_style = space
indent_size = 4
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.kt]
max_line_length = 100
```

設定項目の説明

- root = true
プロジェクトのルートディレクトリにあることを示します。この設定は、上位ディレクトリに別の.editorconfigファイルが存在する場合でも、このファイルが優先されるようにします。

- [＊]
すべてのファイルに適用される一般的な設定を示します。

- indent_style = space
インデントにスペースを使用することを指定します。tabに設定すると、タブが使用されます。

- indent_size = 4
インデントのスペース数を指定します。この例では、4スペースを使用します。

- charset = utf-8
ファイルの文字エンコーディングを指定します。utf-8が一般的ですが、必要に応じて他のエンコーディング（例：latin1、utf-16）に変更できます。

- trim_trailing_whitespace = true
行末の余分なスペースを削除します。

- insert_final_newline = true
ファイルの最後に改行を追加します。

- [*.kt]
Kotlinファイル（拡張子が.kt）に適用される設定を示します。特定のファイルタイプやディレクトリに対して設定を分けることができます。

- max_line_length = 100
Kotlinファイルの最大行長を100文字に制限します。この設定は、長すぎる行を避けるために使用します。                                                                                            

ktlintの各ルールの詳細については公式サイトを参照ください。
https://pinterest.github.io/ktlint/latest/

## pre-commitの利用
pre-commitフックを利用することで、コミット前に自動的にktlintを実行し、コードスタイルのチェックを行うことができます。これにより、コードスタイルに問題がある場合はコミットが中断され、修正が促されます。


### 1.pre-commitフックの設定

まず、Gitのpre-commitフックを設定するために、プロジェクトの.git/hooksディレクトリに移動します。このディレクトリには、Gitフック用のサンプルファイルが含まれています。

2.pre-commitファイルの作成
次に、pre-commitという名前のファイルを作成し、以下の内容を追加します。このファイルは、コミット時に実行されるスクリプトを定義します。

```kotlin
#!/bin/sh

# Gradle wrapperを使ってktlintチェックを実行
./gradlew ktlintCheck

# ktlintCheckが失敗した場合、コミットを中止
if [ $? -ne 0 ]; then
  echo "ktlint check failed. Please fix the issues before committing."
  exit 1
fi
```

### 3.スクリプトに実行権限を付与
作成したpre-commitスクリプトに実行権限を付与します。これにより、スクリプトが実行可能になります。

```
chmod +x .git/hooks/pre-commit
```

### 4. pre-commitフックの動作確認

設定が完了したら、実際にコミットを試みて、pre-commitフックが正しく動作することを確認します。以下の手順で動作確認を行います。

***3.ktlintの実行***で作成したスタイルエラーが発生するコードでcommitまで行うと以下のようなメッセージが表示されます。

```shell
% git commit

> Task :ktlintMainSourceSetCheck FAILED
/src/main/kotlin/com/example/demo/controller/ExampleController.kt:10:24 Unnecessary long whitespace
/src/main/kotlin/com/example/demo/controller/ExampleController.kt:13:5 Expected a blank line for this declaration

FAILURE: Build failed with an exception.
```

これで、pre-commitフックが正しく設定され、ktlintによるコードスタイルチェックがコミット前に自動的に実行されるようになります。コミット時にスタイルエラーがある場合、修正を促されるようになります。

## まとめ
今回はSpring Bootプロジェクトにktlintを導入して、コードスタイルを統一する方法を紹介しました。
ktlintを活用することで、きれいなコードを保つようにしたいですね。