Standardisasi Format Kode Tanpa Perdebatan Code Review
Perbedaan preferensi format kode di antara engineer sering memicu perdebatan trivial pada pull request (PR) dan mengaburkan substansi perubahan logika bisnis. Pendekatan manual berbasis konvensi dokumen jarang berhasil dalam jangka panjang. Solusi deterministik untuk ekosistem Java/Spring Boot adalah mendelegasikan pemformatan ke tool otomatis seperti Spotless.
Spotless bertindak sebagai formatter sekaligus linter gaya kode yang dapat diintegrasikan langsung pada Gradle. Dengan menghubungkan Spotless ke Git hook lokal dan pipeline Continuous Integration (CI), standardisasi kode berjalan otomatis tanpa membebani developer.
1. Konfigurasi spotless-plugin-gradle pada build.gradle
Tambahkan plugin Spotless ke build.gradle. Spotless mendukung berbagai engine pemformat, dua yang paling populer untuk Java adalah Google Java Format dan Palantir Java Format.
- Google Java Format: Menggunakan indentasi 2 spasi. Sangat ketat, tanpa opsi kustomisasi lanjutan.
- Palantir Java Format: Berbasis Google Java Format, namun menggunakan indentasi 4 spasi standar Java enterprise serta penanganan format lambda yang lebih bersih.
Implementasi berikut menggunakan Palantir Java Format pada proyek Spring Boot berbasis Gradle (Groovy DSL):
plugins {
id 'org.springframework.boot' version '3.3.0'
id 'io.spring.dependency-management' version '1.1.5'
id 'java'
id 'com.diffplug.spotless' version '6.25.0'
}
spotless {
java {
target 'src/*/java/**/*.java'
// Menggunakan Palantir Java Format versi kompatibel
palantirJavaFormat('2.47.0')
// Membersihkan import yang tidak terpakai
removeUnusedImports()
// Menghapus whitespace berlebih di akhir baris
trimTrailingWhitespace()
// Memastikan file diakhiri baris baru (newline)
endWithNewline()
}
}
Verifikasi konfigurasi melalui baris perintah:
./gradlew spotlessCheck: Memeriksa kepatuhan kode tanpa memodifikasi file (exit code 1 jika ada pelanggaran)../gradlew spotlessApply: Memformat ulang seluruh file yang terdaftar di konfigurasi target.
2. Otomasi Git Pre-commit Hook via Task Gradle Native
Meminta developer menjalankan ./gradlew spotlessApply secara manual sebelum commit rawan terlewat. Dependensi eksternal seperti Python pre-commit atau Node.js Husky menambah overhead dependensi pada workstation Java.
Gunakan task Gradle native untuk mendistribusikan script hook langsung ke .git/hooks/pre-commit setiap kali build dijalankan.
Buat file template script di scripts/git-hooks/pre-commit:
#!/bin/sh
# scripts/git-hooks/pre-commit
echo "Menjalankan Spotless format sebelum commit..."
# Jalankan spotlessApply hanya pada staged files atau seluruh modul
./gradlew spotlessApply
# Masukkan kembali perubahan format ke staging area Git
git update-index --again
exit 0
Daftarkan task instalasi otomatis pada build.gradle:
tasks.register('installGitHooks', Copy) {
from new File(rootProject.rootDir, 'scripts/git-hooks/pre-commit')
into new File(rootProject.rootDir, '.git/hooks')
filePermissions {
unix('0775')
}
}
// Pasang hook secara otomatis sebelum kompilasi kode
compileJava.dependsOn installGitHooks
Saat developer menjalankan ./gradlew build atau membuka proyek di IDE yang memicu kompilasi, Git hook otomatis terpasang tanpa setup manual.
3. Verifikasi Fail-Fast di GitHub Actions CI
Git hook lokal dapat dilewati menggunakan flag git commit --no-verify. Oleh karena itu, CI pipeline wajib memiliki guardrail verifikasi yang memblokir merge jika aturan format dilanggar.
Tempatkan task spotlessCheck di awal tahapan pipeline sebelum unit test dan build artifact dijalankan untuk menghemat waktu komputasi CI (fail-fast):
name: CI Pipeline
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
jobs:
code-quality:
name: Code Quality & Linting
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
cache: 'gradle'
- name: Make gradlew executable
run: chmod +x gradlew
- name: Run Spotless Check
run: ./gradlew spotlessCheck --no-daemon
Jika terdapat pelanggaran gaya penulisan, workflow langsung berhenti dalam hitungan detik dengan log detail file dan baris yang melanggar.
4. Menjaga Riwayat Git Blame dengan .git-blame-ignore-revs
Menerapkan reformat massal pada basis kode legacy yang sudah berjalan lama akan mengubah ratusan baris file sekaligus. Dampaknya, perintah git blame akan menandai commit reformat tersebut sebagai pengubah terakhir, menyembunyikan riwayat penulis asli logika kode.
Git mendukung pengabaian commit tertentu melalui konfigurasi ignore revisions:
- Eksekusi
./gradlew spotlessApplypada codebase. - Commit perubahan format tersebut secara mandiri:
git commit -m "chore: format codebase using spotless" - Ambil hash commit tersebut (misal:
a1b2c3d4e5f67890abcdef1234567890abcdef12). - Buat file bernama
.git-blame-ignore-revsdi root repositori dan masukkan hash commit:
# Mass formatting commit with Spotless
a1b2c3d4e5f67890abcdef1234567890abcdef12
Aktifkan konfigurasi ini pada environment lokal masing-masing developer:
git config blame.ignoreRevsFile .git-blame-ignore-revsGitHub, GitLab, dan Bitbucket secara native mendeteksi file .git-blame-ignore-revs pada branch utama, sehingga tampilan Git blame pada antarmuka web tetap mempertahankan identitas author logika asli.5. Developer Experience (DX) & Mitigasi Konflik
Integrasi IntelliJ IDEA
Meskipun Git hook memformat kode sebelum commit, feedback instan saat mengetik meningkatkan kenyamanan engineer. Untuk pengguna Palantir Java Format:
- Pasang plugin Palantir Java Format dari JetBrains Marketplace.
- Aktifkan opsi plugin di Settings > Tools > Palantir Java Format.
- Shortcut
Ctrl + Alt + L(Linux/Windows) atauCmd + Option + L(macOS) akan langsung menggunakan standar Spotless tanpa menunggu proses commit.
Mitigasi Merge Conflict saat Penerapan Massal
Jangan pernah menggabungkan commit reformat massal bersamaan dengan fitur baru. Strategi transisi yang aman:
- Merge semua PR aktif yang mendekati tahap final.
- Terapkan Spotless dalam satu commit khusus ke branch utama.
- Untuk branch fitur yang sedang berjalan, lakukan rebase atau merge dengan flag ignore whitespace:
git merge -Xignore-all-space main
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!