GIT Hook um C# Code mit Editorconfig zu formatieren

Tobias Janssen

Backend Software-Developer und GIT Enthusiast bei traperto GmbH

In vielen Unternehmen ist es Entwickler überlassen, mit welchen IDEs ihre Software entwickelt wird.

Bei uns sind häufig Visual Studio Code, sowie JetBrains Rider im Einsatz. Mit steigender Anzahl der Entwickler wächst jedoch auch der Stil der Entwicklung. Damit sich jeder Entwickler im Code zügig zurecht findet, werden häufig Conventions und Code-Richtlinien vereinbart. 

Conventions und insbesondere Formatierungen funktionieren in vielen Fällen IDE-abhängig. Für JetBrains Rider verwenden wir eine Editorconfig. Diese Konfigdatei liegt im Root Verzeichnis unseres .NET Projekts und wird mitversioniert. Die Konfigdatei ist eine Standarddatei um Formatierungen vorzunehmen und kann unteranderem auch von Visual Studio eingelesen und verwendet werden.

In dieser Datei steht beispielsweise welche Art von Abständen verwenden werden soll. Siehe hier einen kleinen Ausschnitt:

indent_style = space //Einrückungstil ist ein leerzeichen
indent_size = 3 //Eine Einrückung entspricht 3 Leerzeilen
max_line_length = 120 //Die maximal Länge einer Zeile ist 120 Zeichen

Weitere Regeln können hier gefunden werden: https://docs.microsoft.com/de-de/dotnet/fundamentals/code-analysis/code-style-rule-options

Sollte entwicklungsübergreifend ein Mitarbeiter den Code mit einer anderen IDE ändern wollen, kann die Formatierung unter Umständen nicht korrekt sein.

Hier kommt ein GIT Hook ins Spiel, der mithilfe eines Scripts die Formatierung übernimmt.

Kleine Randnotiz: In einem Pull Request sollte möglichst wenig Wert auf Formatierung und stattdessen auf Logik gelegt werden.

Ein GIT Hook ist ein Shell-Script, welches automatisch bei einem bestimmten Ereignis in einem GIT Repository ausgeführt wird.

Unsere Anforderung: Formatiere unseren geänderten Code, sobald die Änderungen committed werden.

Dafür schreiben wir ein Script in die Datei pre-commit. Die Datei pre-commit liegt im versteckten .git Verzeichnis unter dem Ordner hooks eures Repositories.

Dotnet Format

Bevor wir das Script implementieren, müssen wir eine Möglichkeit schaffen unseren Code per CLI mithilfe der Editorconfig zu formatieren. Dazu bedienen wir uns dem dotnet tool dotnet-format.
Dieses muss zunächst installiert werden:

dotnet tool install -g dotnet-format

Befehle und Erklärung zu dotnet-format können hier nachgelesen werden: https://github.com/dotnet/format
In unserem Beispiel möchten wir die Whitespaces der geänderten Datei überprüfen und ggf. anpassen lassen.
Dazu verwenden wir folgenden Befehl:

dotnet format whitespace --folder . --include <FILES>

Erklärung:

  • Formatiere die Whitespaces
  • Unter/in der aktuellen Ordnerstruktur
  • Und verwende explizit folgende Dateien

Wir erweitern unseren GIT Hook so, dass dieser nur *.cs Dateien formatieren soll.

Pre-Commit Script

Die Anforderungen an unser Script sind folgende:

  • Überprüfe ausschließlich *.cs Dateien, die im Stage liegen
  • Wende die Editorconfig an
  • Führe alle Schritte automatisch durch
STAGED_FILES=$(git diff --cached --name-only -- '*.cs')
if [[ ! -z "$STAGED_FILES" ]];
then
    dotnet format whitespace --folder . --include $STAGED_FILES
fi

Erklärung des Scripts:

  • git diff –cached –name-only — ‚*.cs‘ 
    • Liefert alle *.cs Dateien, die als „committed“ markiert sind
  • if [[ ! -z „$STAGED_FILES“ ]]; 
    • Die Liste der Dateien ist nicht leer
  • dotnet format whitespace –folder . –include $STAGED_FILES
    • Überprüfe und formatiere alle Dateien mithilfe des Tools dotnet-format

Fazit

Bei der Entwicklung oder einem Code Review sollte kein Augenmerk auf die Formatierung gelegt werden, sodass Scripts, die einem Entwickler diese Arbeit abnehmen können generell gut sind. Trotzdem sollten Conventions und Richtlinien allen Entwickler bekannt sein, sodass hier keine Überraschungen entstehen können.

Das Script ist unteranderem hier zu finden: https://github.com/kryptobi/githooks/blob/main/pre-commit