Selamat siang!Nama saya Andrey Sobolev dan hari ini saya akan memberi tahu Anda bagaimana kami menyiapkan .pre-commit hook pada proyek kami.pengantar
Untuk mulai dengan, beberapa kata tentang apa kait secara umum dan mengapa mereka mungkin diperlukan. Git out of the box menyediakan alat yang dapat menjalankan skrip Anda ketika suatu peristiwa terjadi (misalnya, mendorong ke server, dll.)Pra-komit adalah add-on yang nyaman untuk kait pre-komit git default git yang menjalankan skrip yang dijelaskan dalam .pre-commit-config.yaml sebelum melakukan. Secara teori, kedengarannya sederhana, mari kita berlatih.Instalasi
Atur dependensi yang diperlukan:pre-commit
autoflake
black
pyupgrade
reorder-python-imports
yesqa
flake8
flake8-annotations
flake8-annotations-coverage
flake8-bandit
flake8-broken-line
flake8-bugbear
flake8-builtins
flake8-commas
flake8-comprehensions
flake8-debugger
flake8-eradicate
flake8-executable
flake8-fixme
flake8-future-import
flake8-pyi
flake8-pytest
flake8-pytest-style
flake8-mutable
flake8-string-format
flake8-todo
flake8-unused-arguments
pytest
Saya akan menyampaikan pendapat saya tentang flake-8 dan linter secara umum. Jika Anda sudah memiliki proyek besar dengan banyak kode lawas, maka Anda dapat menghapus linter dengan aman. Biaya yang akan dihabiskan untuk "membawa ke ideal", pihak berwenang tidak akan menghargai. Kami menempatkan linter untuk proyek-proyek baru (dan kecil). Saya ulangi, ini adalah pendapat pribadi saya, saya tidak memaksakannya pada siapa pun.Integrasi Lingkungan
Kami pergi ke direktori root dari lingkungan pengembangan dan menjalankan perintah berikut$ pre-commit install
pre-commit installed at .git/hooks/pre-commit
$ pre-commit --version
pre-commit 2.4.0
Jika .pre-commit akan bersumpah pada sqlite, maka Anda harus menginstalnya (misalnya $ yum install sqlite) dan kompilasi python lagi
Menyiapkan file .pre-commit-config.yaml
Di direktori root lingkungan, buat file .pre-commit-config.yaml- repo: https://github.com/pre-commit/pre-commit-hooks
rev: "v2.5.0"
hooks:
- id: check-merge-conflict
- id: debug-statements
- repo: local
hooks:
- id: black
name: black
entry: black
language: system
types: [python]
args: [--line-length=200, --target-version=py37]
- id: autoflake
name: autoflake
entry: autoflake
language: system
types: [python]
args: [--in-place, --remove-all-unused-imports, --remove-duplicate-keys]
- id: pyupgrade
name: pyupgrade
entry: pyupgrade
language: system
types: [python]
args: [--py37-plus]
- id: reorder-python-imports
name: reorder-python-imports
entry: reorder-python-imports
language: system
types: [python]
args: [--py37-plus]
- id: yesqa
name: yesqa
entry: yesqa
language: system
types: [python]
- id: tests
name: Run tests
entry: "bash tests.sh"
language: system
verbose: true
Tes
Selain memeriksa dan memformat kode, kami akan melakukan tes pada tahap membuat komit. Untuk melakukan ini, kita akan menggunakan pytest (https://docs.pytest.org/en/latest/) dan mengkonfigurasinya untuk kebutuhan kita.Di direktori root lingkungan, buat folder tes dan letakkan file berikut initest_example_without_db.py, test_example_with_db.py di sanauntuk kenyamanan, konfigurasikan tes sehingga Anda dapat menggunakan database saat ini (misalnya, salinan database dari server pertempuran), dan tidak membuat yang baru setiap kali .Tes sederhana test_example_without_db.pydef inc(x):
return x + 1
def test_answer():
assert inc(3) == 4
Dalam tes sederhana, kita dapat terhubung misalnya webbot dan memotong node sistem kami untuk mengotomatiskan pekerjaan manual tester.Uji menggunakan database test_example_with_db.pyimport pytest
from chat.models import ChatRoom
from settings import POSTGRES_DB, POSTGRES_USER, POSTGRES_PASSWORD, \
POSTGRES_HOST, POSTGRES_PORT
@pytest.fixture(scope='session')
def django_db_setup():
settings.DATABASES['default'] = {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': POSTGRES_DB,
'USER': POSTGRES_USER,
'PASSWORD': POSTGRES_PASSWORD,
'HOST': POSTGRES_HOST,
'PORT': POSTGRES_PORT,
}
@pytest.fixture
def db_access_without_rollback_and_truncate(request, django_db_setup, django_db_blocker):
django_db_blocker.unblock()
request.addfinalizer(django_db_blocker.restore)
def chat():
return ChatRoom.objects.all().count()
@pytest.mark.django_db
def test_chat():
assert chat() > 0
Contohnya agak buatan dan dibuat khusus untuk catatan ini, namun demikian memungkinkan kita untuk mengakses database saat ini dan melakukan tes kompleks yang melampaui pengujian manual.Kami menyertakan tes dalam .pre-commit
Untuk menghubungkan tes, kita memerlukan skrip shell di direktori root lingkungan, yang akan kita panggil tests.sh:source ../../python38_env/bin/activate && python -m pytest -v tests
Isinya sangat jelas, tetapi Anda mungkin memperhatikan bahwa aktivasi lingkungan virtual secara eksplisit ditulis dalam kode. Ini bisa merepotkan jika tim Anda mengembangkan di stasiun kerja yang berbeda (misalnya, yang menyebarkan lingkungan pada mesin lokal, dan seseorang berkembang di server).Anda dapat memecahkan masalah ini melalui variabel dalam .envContoh penerapan :github.com/Sobolev5/starlette-vue-backend/blob/master/.env.example (perhatikan variabel ENV_ACTIVATE)github.com/Sobolev5/starlette-vue-backend /blob/master/tests.sh (parse ENV_ACTIVATE dan aktifkan lingkungan)Buat komit
Sekarang tinggal membuat komit dan melihat cara kerjanya$ git add .
$ git commit -m Sobolev:TestPreCommitHook
Check for merge conflicts................................................Passed
Debug Statements (Python)................................................Passed
black....................................................................Failed
- hook id: black
- files were modified by this hook
reformatted /var/www/file.py
All done!
1 file reformatted, 2 files left unchanged.
autoflake................................................................Passed
pyupgrade................................................................Passed
reorder-python-imports...................................................Failed
- hook id: reorder-python-imports
- exit code: 1
- files were modified by this hook
Reordering imports in file.py
yesqa....................................................................Passed
Run tests................................................................Passed
- hook id: tests
- duration: 2.85s
tests/test_example_with_db.py::test_chat PASSED [ 66%]
tests/test_example_without_db.py::test_answer PASSED [100%]
Komit sekarang dibuat dalam dua langkah. Pada tahap pertama, kait memformat kode, jadi setelah mereka bekerja, kita hanya perlu "mengulang" perintah.Ternyata urutan berikut.$ git add .
$ git commit -m Sobolev:TestPreCommitHook
$ git add .
$ git commit -m Sobolev:TestPreCommitHook
Sekian, terima kasih atas perhatiannya.Tautan situs
→ Daftar lengkap kait