Pre-commit demi kenyamanan bersama
Dalam beberapa waktu terakhir saat saya setup project python setidaknya ada 3 hal yang harus ikut dipasang di awal:
- isort: untuk konsisten runutan dari "import"
- black: formating
- flake8: linter
Dengan tambahan konfigurasi masing-masing seperti
#.isort.cfg
[isort]
line_length = 80
multi_line_output = 3
include_trailing_comma = true
#.flake8
[flake8]
max-line-length = 80
select = C,E,F,W,B,B950
ignore = E501,W503,E203
Jangan tanya dulu tentang konfigurasi di atas karena sayapun mendapatkan dari random blog di internet sudah lama sekali. Lalu saya pasang konfigurasi di vscode saya seperti ini
{
"python.defaultInterpreterPath": "/path/to/virtualenv/python",
"python.formatting.provider": "black",
"python.formatting.blackArgs": [
"--line-length=80"
],
"python.sortImports.args": [
"-rc",
"-sp isort.cfg"
],
"editor.formatOnSave": true,
"python.linting.flake8Enabled": true,
"python.linting.pylintEnabled": false,
"[python]": {
"editor.codeActionsOnSave": {
"source.organizeImports": true
}
},
"html.suggest.html5": true,
"html.autoClosingTags": true,
}
Efeknya adalah setiap saya menulis kode python dan menyimpannya maka vscode akan mengubah format sesuai aturan yang sudah ditetapkan dan juga kita akan mendapatkan informasi warning secara langsung di bagian terminal. Contoh saya menulis kode seperti ini:
from blog.models import Content, Tags
from django.contrib import admin
# Register your models here.
admin.site.register(Tags)
def some_function_with_long_param(first, second, third, fourth, fifth, sixth, seventh, more
):
greeting = 'hallo'
return greeting
Saat saya melakukan save, vscode akan membantu untuk merapihkan jadi seperti ini
from django.contrib import admin
from blog.models import Content, Tags
# Register your models here.
admin.site.register(Tags)
def some_function_with_long_param(
first, second, third, fourth, fifth, sixth, seventh, more
):
greeting = "hallo"
return greeting
Dan bonus warning di terminal seperti ini
'blog.models.Content' imported but unused
Dengan seperti ini saya mendapatkan benefit:
- konsisten format
- mengurangi kesalahan-kesalahan yang muncul saat ngoding.
Selesai? Betul selesai selama ngoding sendiri dan teman ngoding menggunakan vscode sehingga konfigurasi bisa copas dan kami akan sama-sama menggunakan format dan aturan baku yang sama. Tapi semua berubah saat ada yang menggunakan IDE lain dan tidak otomatis melakukan sesuai aturan yang sudah dibuat di config file.
pre-commit
Untuk mengetes linter bisa saja dipasang di repository sehingga saat melakukan push atau pull-request dicek dulu keabsahan linternya, tapi bagaimana jika ingin sebelum masuk repo bahkan orang sudah aware dengan perbedaan? Pre-commit ini bisa menjadi jawaban.
Sesuai namanya pre-commit membantu kita untuk melakukan suatu tugas sebelum programmer melakukan commit kepada berkas yang dikerjakan.
Pertama mari install dahulu pre-commit menggunakan package manager favorit masing-masing, di sini saya pakai pipenv
pipenv install pre-commit
Setelah terpasang buat berkas .pre-commit-config.yaml
dan isikan sebagai berikut (sesuaikan versi dengan yang diinginkan)
repos:
- repo: https://github.com/PyCQA/isort
rev: 5.10.1
hooks:
- id: isort
- repo: https://github.com/ambv/black
rev: 22.6.0
hooks:
- id: black
language_version: python3.9
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.3.0
hooks:
- id: flake8
Setelah selesai jalankan di root aplikasi pre-commit install
sampai mendapatkan response pre-commit installed at .git/hooks/pre-commit
Instalasi selesai.
Sekarang saya coba di IDE yang berbeda, saya menggunakan pycharm community.
Kembali ke kode pertama yang belum kena format
from blog.models import Content, Tags
from django.contrib import admin
# Register your models here.
admin.site.register(Tags)
def some_function_with_long_param(first, second, third, fourth, fifth, sixth, seventh, more
):
greeting = 'hallo'
return greeting
Saat disimpan tidak otomatis mengubah format, tapi saat saya melakukan commit, pre-commit akan mengecek kesesuaian dan yang bisa diformat akan diformat dan yang tidak akan ditandai
git commit -am "precommit"
[INFO] Installing environment for https://github.com/PyCQA/isort.
[INFO] Once installed this environment will be reused.
[INFO] This may take a few minutes...
[INFO] Installing environment for https://github.com/ambv/black.
[INFO] Once installed this environment will be reused.
[INFO] This may take a few minutes...
[INFO] Installing environment for https://github.com/pre-commit/pre-commit-hooks.
[INFO] Once installed this environment will be reused.
[INFO] This may take a few minutes...
isort....................................................................Failed
- hook id: isort
- files were modified by this hook
Fixing /home/ariesm/Work/ninja-api/blog/admin.py
black....................................................................Failed
- hook id: black
- files were modified by this hook
reformatted blog/admin.py
All done! ✨ 🍰 ✨
1 file reformatted.
Flake8...................................................................Failed
- hook id: flake8
- exit code: 1
blog/admin.py:3:1: F401 'blog.models.Content' imported but unused
Hasilnya kode kita seperti ini
from django.contrib import admin
from blog.models import Content, Tags
# Register your models here.
admin.site.register(Tags)
def some_function_with_long_param(
first, second, third, fourth, fifth, sixth, seventh, more
):
greeting = "hallo"
return greeting
tapi ini belum bisa di-commit karena masih ada error yang tidak otomatis keformat yaitu flake8 blog/admin.py:3:1: F401 'blog.models.Content' imported but unused
Hapus atau gunakan Content
sesuai anjuran dari flake, lalu lakukan commit lagi dan hasilnya.
from django.contrib import admin
from blog.models import Content, Tags
# Register your models here.
admin.site.register(Tags)
admin.site.register(Content)
def some_function_with_long_param(
first, second, third, fourth, fifth, sixth, seventh, more
):
greeting = "hallo"
return greeting
isort....................................................................Passed
black....................................................................Passed
Flake8...................................................................Passed
[feat/scafolding d8a338d] precommit
1 file changed, 2 insertions(+), 8 deletions(-)
Kode berhasil di-commit dan ketika dipush ke repo sudah tertib mengikuti aturan.
Referensi: https://rohitgupta.xyz/blog/keeping-python-code-clean-with-pre-commit-hooks-black-flake8-and-isort/