pre-commit

Ich war auf der Suche nach eine L├Âsung, um bestimmte Dateien in meinem GIT-Repository zu ├╝berpr├╝fen. Die f├╝r mich naheliegendste L├Âsung war, die Pipeline um diese ├ťberpr├╝fung zu erweitern. Das funktioniert ohne Probleme, das unpraktische ist allerdings, dass Fehler erst in der Pipeline auftauchen. Ich kann die Tools zur ├ťberpr├╝fung zwar lokal ausf├╝hren, aber wenn ich ehrlich bin, dann mache ich das einfach nicht. Daher w├Ąre eine automatische lokale ├ťberpr├╝fung von Vorteil, die im besten Fall auch noch einfach f├╝r Andere zug├Ąnglich ist. Die Antwort lautet pre-commit, welches auf git hooks aufbaut und vor dem Commit (also pre-commit) ausgef├╝hrt wird. Es werden auch alle anderen hooks von git unterst├╝tzt, das soll jedoch heute nicht das Thema sein.

Die Einrichtung von pre-commit ist recht einfach und ich werde dies hier erl├Ąutern. Zu n├Ąchste ben├Âtigt ihr Python und dessen Paketmanagementsystem pip, da pre-commit in Python geschrieben wurde.

Unter Linux (Debian/Ubuntu) geht das wie folgt. Auf anderen Systemen findet ihr hier die Installationsanleitungen.

sudo apt update
sudo apt install python3 python3-pip python3-venv -y

Jetzt k├Ânnt ihr pre-commit in der aktuellen Version installieren. Unter Debian m├╝sst ihr hierzu eine virtuelle Umgebung einrichten, die ihr dann immer mit source ~/.venv/bin/activate aktivieren m├╝sst, bevor ihr pre-commit verwenden k├Ânnt. Das ist notwendig, da ihr sonst eventuell Python-Abh├Ąngigkeiten von eurem Betriebssystem und anderen Applikationen durcheinander bringen k├Ânnt.

cd ~
python -m venv .venv
source ~/venv/bin/activate
pip install pre-commit

Wenn euch die aktuellste Version nicht so wichtig ist, kommt unter Debian auch pre-commit als Paket mit sudo apt install pre-commit -y. Dann m├╝sst ihr auch nicht die virtuelle Umgebung einrichten und habt das Tool immer direkt zur Verf├╝gung.

Ihr k├Ânnt jetzt erst mal pr├╝fen, ob die Installation von pre-commit funktioniert hat.

pre-commit --version

Jetzt k├Ânnt ihr pre-commit f├╝r euer Repository konfigurieren. Dazu ben├Âtigt ihr als Erstes eine .pre-commit-config.yaml-Datei im Wurzelverzeichnis eures Repository. Ihr k├Ânnt diese wie folgt initialisieren.

pre-commit sample-config > .pre-commit-config.yaml

Als Zweites m├╝sst ihr jetzt noch pre-commit in eurem Repository aktivieren/installieren. Das ist immer notwendig, wenn ihr das Repository neu auf einen Rechner klont. Das liegt daran, dass pre-commit, sich in das .git/hooks/pre-commit einh├Ąngt und die githooks nicht Teil eures Sourcecodes sind.

pre-commit install

pre-commit ist jetzt konfiguriert. Wenn man sich die .pre-commit-config.yaml-Datei anschaut, dann sieht man, dass dort unterschiedliche hocks definiert sind. Unter anderem ein trailing-whitespace, und end-of-file-fixer. Diese hooks k├Ânnt ihr jetzt einfach mal mit dem folgenden Befehl f├╝r alle Dateien ausf├╝hren.

pre-commit run --all-files

Die Ausf├╝hrung dieses Befehls ist auch die Empfehlung beim Einf├╝hren neuer hooks, da damit automatisch alle Dateien den gew├╝nschten Regeln entsprechen. Wenn man das nicht m├Âchte, dann ist das auch nicht notwendig, dann werden immer nur die Dateien, die teil des Commits sind, an die Regeln angepasst.

Die hooks arbeiten, wie ich finde, sehr intelligent, da ihr alle Tools einbinden k├Ânnt, sobald diese ein .pre-commit-hooks.yaml in ihrem Repository eingecheckt haben, die beschreibt, wie pre-commit das Tool ausf├╝hren muss. Dazu einfach das gew├╝nschte Repository ├╝ber repo referenzieren und die in der .pre-commit-hooks.yaml definierte id als hooks hinzuf├╝gen. Eine gro├če Auswahl an hooks findet ihr hier.

Wenn ihr jetzt also ganz normal einen Commit macht, wird immer automatisch pre-commit ausgef├╝hrt und wenn ihr das Repository auf einen anderen Computer herunterladet, dann m├╝sst ihr nur pre-commit install ausf├╝hren, um dort den gleichen Regeln zu folgen.

git add .
git commit -m 'Add `pre-commit` to lookslikematrix.'

Das wird zu dem folgenden Output f├╝hren, wenn alle Regeln passen.

trim trailing whitespace.................................................Passed
fix end of files.........................................................Passed
check yaml...............................................................Passed
check for added large files..............................................Passed
[feature/pre-commit d0f5f59] Write `pre-commit` blog post.
 30 files changed, 139 insertions(+), 40 deletions(-)
 create mode 100644 .pre-commit-config.yaml
 create mode 100644 _posts/2023-12-18-pre-commit.markdown
 create mode 100644 assets/pre-commit.png

Oder zu folgendem Output, wenn ein Fehler in der Datei war.

trim trailing whitespace.................................................Failed
- hook id: trailing-whitespace
- exit code: 1
- files were modified by this hook

Fixing _posts/2023-12-18-pre-commit.markdown

fix end of files.........................................................Passed
check yaml...........................................(no files to check)Skipped
check for added large files..............................................Passed

Ich finde den Ansatz von pre-commit toll, weil man einfach die M├Âglichkeit hat ein eigenes Tool zu entwickeln, dass dann nur ├╝ber eine Datei im Repository erweitert wird, um im pre-commit Kontext zu funktionieren.

Ich hoffe, diese Anleitung hat euch geholfen. Solltet ihr noch Fragen oder Anregungen haben, dann hinterlasst gerne ein Kommentar. Ansonsten k├Ânnt ihr mir gerne einen Kaffee ÔśĽ ausgeben.


[1]: https://pre-commit.com/

[2]: https://git-scm.com/docs/githooks

[3]: https://pre-commit.com/hooks.html