# 為何要使用 spotless

## Spotless

[https://github.com/diffplug/spotless](https://github.com/diffplug/spotless/tree/main/plugin-gradle#google-java-format)

讓你的專案乾淨, 整潔, 對齊, 就是這個專案的主要目的. 可以用來處理專案格式化, 縮排, coding style 一致性, 除了支援目前的主流語言, 與整合了各種打包工具, 甚至不用安裝在專案內, 透過 IDE 的 plugins 安裝就能完成 source code 排版格式化, 目前在 github 有 4.7 k stars.

我傾向於使用 google-java-format 而 spotless 100% 支援 google-java-format.

若想了解 google-java-format 有哪些規則, 可以參考這連結. [https://google.github.io/styleguide/javaguide.html](https://google.github.io/styleguide/javaguide.html)

## Setup by gradle

配置非常簡單, 基本上就是安裝 gradle plugin (在寫這篇的時候 spotless 剛好是 [7.0.2](https://plugins.gradle.org/plugin/com.diffplug.spotless)).

```bash
id 'com.diffplug.spotless' version '7.0.2'
```

然後配置你要哪些格式化工具, 設定參數

```bash
// 配置你要的工具, 設定, 參數, etc.
spotless {
 ....
}
```

完整配置跟說明如下

```bash
plugins {
    id 'java'
    id 'com.diffplug.spotless' version '7.0.2'
}

repositories {
    mavenCentral()
}

dependencies {
    testImplementation platform('org.junit:junit-bom:5.10.0')
    testImplementation 'org.junit.jupiter:junit-jupiter'
}

spotless {
    java {
        // 100% 支援 google-java-format
        googleJavaFormat()

        // 移除沒有被使用的 imports
        removeUnusedImports()

        // 清理行末的空白
        trimTrailingWhitespace()

        // 指定要格式化的 source code 目錄
        target 'src/*/java/**/*.java'
    }

    // 格式化其他檔案類型 (可選)
    format 'misc', {
        target '*.gradle', '*.md', '.gitignore'

        trimTrailingWhitespace()
        endWithNewline()
    }
}

// 在建置前執行格式化
tasks.withType(JavaCompile).configureEach {
    dependsOn 'spotlessApply'
}

test {
    useJUnitPlatform()
}
```

## Run

簡單的 compiler run 就幫你把專案格式化完畢了.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1738168194300/31a089f8-efa6-4645-a638-03fed858e6f2.png align="center")

## 其他

google-java-format 是非常老派的格式, 整體規則並不多, 非常陽春, 但就不支援客製, 比如縮排固定是 2, 要改為 4 則要特別配置 [AOSP Java Code Style](https://source.android.com/docs/setup/contribute/code-style).

某些狀況 [palantir-java-format](https://github.com/palantir/palantir-java-format) 更適合在現在 lambda 為主流的開發格式, [palantir-java-format](https://github.com/palantir/palantir-java-format) 繼承自 google-java-format.

```bash
spotless {
  java {
    // optional: you can specify a specific version and/or switch to AOSP/GOOGLE style
    palantirJavaFormat('2.9.0').style("GOOGLE")
```

紅色為 google-java-format 綠色為 palantir-java-format

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1738171177155/d10d70fa-9a79-4409-aa75-5fa258cc29b4.png align="center")

### AI 的結論

Palantir Java Format (PJF) vs Google Java Format (GJF) 比較, 但其實並沒有很準確, 兩者都支持漸進式格式化, 也就是說可以指定說要 format 哪些檔案, 避免一次產生大量的 diff.  
  
遷移策略, 我會這樣考量

1. 新的 code 優先配置 format.
    
2. 舊的 code 先 format, 再進行功能修改. 發兩次 PR.
    

這樣慢慢的迭代, 或許是比較無痛的方式 ?

| **特性** | **Palantir Java Format (PJF)** | **Google Java Format (GJF)** |
| --- | --- | --- |
| **格式化標準** | 參考 Google Java Format，但做了調整 | 嚴格遵循 Google Java Style Guide |
| **可配置性** | 提供少量可選項，如最大行長等 | 幾乎無法配置，只能接受預設格式 |
| **換行策略** | 盡量壓縮行長，避免過多換行 | 更傾向於保持簡潔，但有時換行過多 |
| **注釋格式化** | 支援對 JavaDoc 及多行註解的格式化 | 會自動重新格式化 JavaDoc |
| **支援的工具** | Spotless、Gradle、Maven、IntelliJ Plugin | Spotless、Gradle、Maven、IntelliJ Plugin |
| **性能** | 一般來說比 GJF 快，適合大型代碼庫 | 格式化速度較慢，對大文件影響較大 |
| **與 IDE 的整合** | 提供 IntelliJ Plugin，可與 IDE 格式化保持一致 | 可能與 IDE 自帶的格式化規則衝突 |
| **與現有代碼的兼容性** | 更適用於增量採用，可慢慢遷移 | 一旦使用，幾乎所有代碼都會被重新格式化 |
