Alat kualitas dari dua Chapter sebelumnya hanya berguna bila dijalankan — dan kenyataannya orang (termasuk kita) kadang lupa menjalankan ruff sebelum git commit, lalu CI di server yang memerah. Git punya mekanisme bawaan untuk menutup celah lupa ini: hooks, skrip yang dieksekusi otomatis pada momen tertentu, salah satunya tepat sebelum commit dibuat. Pada Chapter ini kita memasang pemeriksaan kualitas ke hook pre-commit dengan bantuan tool bernama pre-commit (tanda hubung memang bagian dari namanya).
Konsep Git Hook #
Folder tersembunyi .git/hooks/ di setiap repository berisi skrip yang git jalankan pada momen tertentu. File bernama pre-commit, bila ada dan dapat dieksekusi, berjalan sebelum commit benar-benar tercipta; exit code bukan nol membatalkan commit tersebut. Menulis skrip hook manual berarti setiap anggota tim harus memasangnya sendiri di masing-masing mesin — dan hook tidak ikut ter-commit ke repository. Tool pre-commit menyelesaikan keduanya sekaligus: konfigurasi hook disimpan sebagai file proyek, lalu tool memasang skrip penghubung ke .git/hooks/pre-commit dengan satu perintah.
Anatomi .pre-commit-config.yaml #
Konfigurasi disimpan di akar repository dengan nama .pre-commit-config.yaml:
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.17.0
hooks:
- id: ruff
args: [--fix]
- id: ruff-formatMari kita bedah strukturnya:
repos: daftar repository sumber hook. Setiap hook hidup di repo yang dikelola terpisah, sehingga bisa diperbarui tanpa menunggu rilis tool utamanya.repo: https://github.com/pre-commit/pre-commit-hooks: kumpulan hook serbaguna dari maintainer pre-commit sendiri.rev: v5.0.0: versi hook yang dikunci — semua anggota tim memakai versi sama, hasil pemeriksaan pun konsisten.id: end-of-file-fixer: memastikan setiap file diakhiri satu baris kosong baku;trailing-whitespacemenghapus spasi menempel di akhir baris.repo: .../ruff-pre-commitdenganid: ruff: menjalankan linter ruff versi 0.17.0;args: [--fix]memperbaiki temuan aman secara otomatis.id: ruff-format: menjalankan formatter pada file yang di-commit.
File YAML di atas sudah diperiksa keabsahan strukturnya (parsing valid), dan nomor versi rev mengikuti pola rilis resmi tiap repo hook.
Memasang dan Menjalankan #
Instalasi tool dilakukan sekali per mesin:
python3 -m pip install pre-commit
pre-commit installOutput yang Dihasilkan (ilustrasi — teks persisnya menyesuaikan versi tool dan sistem operasi):
pre-commit installed at .git/hooks/pre-commitMulai saat itu, setiap git commit menjalankan seluruh hook pada file yang staging. Ringkasan hasilnya terlihat seperti berikut:
Output yang Dihasilkan (ilustrasi):
end-of-file-fixer.........................................................Passed
trailing-whitespace......................................................Passed
ruff...........................................................................Passed
ruff-format..............................................................PassedHook yang memodifikasi file (misalnya ruff --fix yang menghapus import tak terpakai) menandai dirinya Failed sambil memperbaiki file tersebut; git membatalkan commit pertama dan kita diminta git add ulang lalu commit sekali lagi dengan file yang sudah bersih.
Untuk mencoba seluruh hook tanpa melakukan commit:
pre-commit run --all-filesPerintah ini berguna saat pertama kali memperkenalkan pre-commit ke proyek lama — lebih baik memperbaiki seluruh temuan di satu sesi daripada terkejut hook gagal di tengah commit mendesak.
Hook Populer untuk Proyek Python #
| Hook | Tugasnya |
|---|---|
ruff | linting dan perbaikan otomatis gaya kode Python |
ruff-format | formatting konsisten seluruh tim |
end-of-file-fixer | baris kosong penutup file |
trailing-whitespace | spasi menempel di ujung baris |
check-yaml | memastikan file YAML bisa di-parse sebelum masuk repo |
Hook menjaga titik masuk perubahan di mesin lokal. Lapisan terakhir berada di server: memastikan seluruh test dan linter benar-benar hijau sebelum perubahan menyatu ke branch utama — tugas continuous integration pada Chapter berikutnya.