Gerade beim Thema Qualität ist es zielführend möglichst viele Prüfungen durchzuführen bevor Erweiterungen/Änderungen ins Source Control (in meinem Falle Mercurial) veröffentlicht werden. Mercurial bietet zu diesem Zwecke Hooks an, die auch für prüfende “Tasks” verwendet werden können. Hooks sind dabei “Eingreifpunkte”, die vor oder nach bestimmten Repository-Ereignissen aufgerufen werden und so zusätzliche Funktionalität in den Prozess aufnehmen lassen.

Mögliche Hooks

Nachfolgend findet sich eine Liste an Hooks und wann diese zur Ausführung gelangen.

  • changegroup: Wird für eine Gruppe an Changesets, welche von anderer Stelle eingereicht wurde, einmalig aus ausgeführt.
  • commit: Ein neues Changeset wurde im lokalen Repository erstellt.
  • incoming: Wird für jedes neue Changeset ausgeführt, welches von anderer Stelle eingereicht wurde.
  • outgoing: Wenn eine Gruppe an Changesets in das Remote Repository transferiert wird.
  • prechangegroup: Bevor eine Gruppe an Changesets ins Repository übernommen wird.
  • precommit: Bevor ein Commit tatsächlich gestartet wird.
  • preoutgoing: Bevor eine Gruppe an Changesets ans Remote Repository übertragen wird.
  • pretag: Bevor ein Tag erstellt wird.
  • pretxnchangegroup: Nachdem eine Gruppe an Changesets ins lokale Repository übertragen wurde, jedoch bevor die Transaktion abgeschlossen wird und Änderungen somit permanent verfügbar sind.
  • pretxncommit: Nachdem ein Changeset lokal erstellt wurde, aber bevor die Transaktion abgeschlossen wird und Änderungen somit permanent verfügbar sind.
  • preupdate: Bevor ein Update oder Merge im Arbeitsverzeichnis gestartet wird.
  • tag: Nachdem ein Tag erstellt wurde.
  • update: Nachdem ein Update oder Merge im Arbeitsverzeichnis abgeschlossen wurde.

Diese Liste zeigt, dass hier ausreichend Eingriffsmöglichkeiten vorhanden sind.

Wozu nun Hooks verwenden?

Anwendungsfälle für Hooks gibt es viele. Hier einige derjenigen, die ich für meine Arbeit verwende:

  • Prüfung JavaScript. In Webprojekten kommt natürlich jede Menge JavaScript zum Einsatz. Sinnvollerweise wird der JavaScript Code hinsichtlich Fehler und potentielle Probleme hin geprüft. Dafür steht unter anderem JSHint zur Verfügung. Es empfiehlt sich sowohl dieses Tool einzusetzen, als auch den vorhandenen JavaScript Code VOR einem Commit zu prüfen, damit Änderungen/Fixes sofort erledigt werden können und Teil des Commits werden. Außerdem wird so sichergestellt, dass die Prüfung bei jedem Commit stattfindet und etwaige Prüfungen bei Kollegen nicht fehlschlagen. Es hilft auch, unnötige Changesets, die ausschließlich JavaScript Fehler bereinigen zu vermeiden.
  • Ausführen der Tests. Tests sind die Versicherung eines jeden Entwicklers. Nicht nur sollten laufend welche geschrieben werden, sie sollten auch vor jedem Commit ausgeführt werden, um die “Fehlerfreiheit” des Codes zu gewährleisten. Auch hierauf vergisst man dann doch gerne einmal. Warum also nicht vor jedem Commit automatisch durch einen Hook ausführen? Damit kann zusätzlich auch geprüft werden, ob der Code überhaupt kompiliert (muss er schließlich auch, damit die Tests durchlaufen können).
  • Prüfung Incoming Changesets. Eines der wohl nervigsten Punkte ist das Beziehen neuer Changesets vom Server und ein darauf folgender Stillstand, da der Code nicht kompiliert etc. Hier muss man manuell auf eine Variante zurückgehen auf deren Basis man weiterarbeiten kann und schlussendlich warten, bis der Fix kommt. Daher können einkommende Changesets durchaus geprüft werden. Gibt es ein Problem, werden die Änderungen nicht ins Arbeitsverzeichnis übernommen.

Natürlich gibt es noch viele, viele weitere Anwendungsmöglichkeiten (Bei Open Source Projekten werden teilweise auch gerne Commit Meldungen per Twitter verteilt und dergleichen). Wer beispielsweise nach einer Definition of Done (DoD) arbeitet, sollte diese auf Umsetzbarkeit einzelner Punkte durch Hooks prüfen. Dadurch kann viel manuelle Arbeit automatisiert und sichergestellt werden, dass sie auch tatsächlich ausgeführt wird.

Hook erstellen

Die einfachsten Hooks bestehen aus einem Command Line Aufruf (man kann auch gerne mit Python umherwüten, wenn man möchte) und müssen entsprechend konfiguriert werden. Die Konfiguration kann in der globalen Mercurial Konfiguration geschehen und besitzt dann Gültigkeit für alle Mercurial Repositories, oder aber speziell für ein gewünschtes.

Hier eine Beispielkonfiguration für die Ausführung eines Tools vor der Durchführung eines Commits:

[hooks]
precommit=C:\ToolsPath\MyCommandSript.cmd

Hierbei sind folgende Punkte zu beachten:

  • Hooks werden mit den Privilegien des angemeldeten Benutzers ausgeführt.
  • Ausführungsverzeichnis ist das Root-Verzeichnis des Repositories. Dies ist wichtig zu wissen, um Pfade korrekt setzen zu können.

Für zusätzliche Informationen empfiehlt sich Kapitel 10 aus Mercurial: The Definitive Guide.

Fazit

Der Einsatz von Hooks ist sehr zu empfehlen, um wiederkehrende Aufgaben hinsichtlich eines Repositories zu automatisieren bzw. sicher zu stellen, dass diese Aufgaben auch für jedes Vorkommen einer Aktion oder mehrerer bestimmter Aktionen ausgeführt werden. So kann nicht nur die Anzahl der Commits verkleinert, sondern auch deren Qualität stark gesteigert werden (die korrekten Prüfungen vorausgesetzt. Natürlich muss bedacht werden, dass sich gerade durch precommit-Hooks (und zeitlich ähnlich gelagerte Hooks) der Commit-Vorgang verlängert, dies sollte aber für die erhaltenen Vorteile in Kauf genommen werden.

Über den Autor

Norbert Eder

Ich bin ein leidenschaftlicher Softwareentwickler und Fotograf. Mein Wissen und meine Gedanken teile ich nicht nur hier im Blog, sondern auch in Fachartikeln und Büchern.