Sinnvolle SVN Hooks für PHP Projekte
Dieser Artikel ist nur für diejenigen gedacht, die SVN bereits kennen. Wer jetzt die Stirn runzelt, möge sich vorher bei wikipedia oder youtube informieren und mal erste Versuche mit einem SVN-Server sammeln.
Erstmal zur Begrifflichkeit ansich: Hooks sind Interfaces zu kleinen externen Programmen, die zu bestimmten Zeiten während eines Programmablaufs aufgerufen werden können. Sie klinken sich also in den Ablauf ein.
Beim SVN gibt es 3 interessante Hooks, die häufig genutzt werden (insgesamt gibt es 9):
– start-commit
– pre-commit
– post-commit
Im SVN Handbuch kann man genauer nachlesen, wann diese Hooks aufgerufen werden.
Das erste Script, welches wir als pre-commit-Hook aufrufen wollen, ist ein einfaches PHP-Lint, wir wollen also die PHP-Syntax testen. Dieses Beispiel mache ich etwas ausführlicher, alle anderen Hook-Scripte hänge ich einfach an dieses Posting dran.
#!/bin/bash REPOS="$1" TXN="$2" PHP="/usr/local/php5/bin/php" SVNLOOK="/usr/bin/svnlook" AWK="/usr/bin/awk" GREP="/bin/egrep" SED="/bin/sed" CHANGED=`$SVNLOOK changed -t "$TXN" "$REPOS" | $GREP "^[U|A]" | $AWK '{print $2}' | $GREP \\.php$` for FILE in $CHANGED do MESSAGE=`$SVNLOOK cat -t "$TXN" "$REPOS" "$FILE" | $PHP -l` if [ $? -ne 0 ] then echo 1>&2 echo "***********************************" 1>&2 echo "PHP error in: $FILE:" 1>&2 echo `echo "$MESSAGE" | $SED "s| -| $FILE|g"` 1>&2 echo "***********************************" 1>&2 exit 1 fi done
Da ich mein SVN auf einem Linux-Server betreibe, habe ich hier das entsprechende Bash-Script. Falls ihr euren SVN-Server unter Windows betreibt, muß man das Script natürlich anpassen.
Was passiert hier? Es werden mittels svnlook alle geänderten oder neu hinzugefügten Dateien gesucht, aufgelistet und dann noch die Dateien mit einer .php Endung gefiltert. Für jede Dieser Dateien wird dann wiederum via svnlook der Quelltext geholt und mittels der Pipe an „php -l“ übergeben. Im Falle eines Fehlers gibt es eine Fehlermeldung, die dann im SVN-Client ausgegeben wird. Der Commit wird also scheitern (da dies ja ein pre-commit-Hook ist).
Ein weiteres Hook-Script, welches pre-commit ausgeführt wird, ist zum Beispiel der PEAR PHP-CodeSniffer. Dieses kleine Script kann PHP-Code auf Coding-Standards überprüfen, also ob beispielsweise PHPdoc vorhanden ist, oder ob die geschweiften Klammern an den richtigen Stellen stehen. Ich persönlich habe dieses Script allerdings nicht als Hook eingebunden, da ich auch ab und zu fremden Code ins SVN packe, der natürlich nicht meinen Code-Standards entspricht. PHP-CodeSniffer führe ich lokal ab und zu aus, und dann auch nur auf meine Verzeichnisse. Beim CodeSniffer wird ein entsprechendes Hook-Script gleich mitgeliefert.
Noch ein einfaches kleines Hook-Script wäre das hier:
/* test to see if svn commit comment length is greater than or equal to 10 chars */ $log = exec("svnlook log -t ". $argv[2] ." ". $argv[1]); if(strlen($log) > 9){ exit(0); }else{ exit(1); }
---------
Weitere Hook-Scripte:
- PHP CodeSniffer: liegt dem Paket bei unter /scripts/phpcs-svn-pre-commit
- PHPUnit: dazu gibt es im Internet keine Quellen (ich habe jedenfalls keine gefunden), wie man das am besten machen kann. Ich habe es früher (vor 2 Jahren) so gelöst: Download Vorgehensweise ist einfach: Nach dem commit einmal das svn komplett auschecken, dann die beiden unit-tests starten, und im Fehlerfall Emails versenden
- Mailer-Script: subversion liegt bereits eins bei, hier eine Weiterentwicklung: http://opensource.perlig.de/svnmailer/
- Jabber Benachrichtung: http://trac.c3d2.de/subversion-hooks/browser (über einen ICQ-Gateway kann man dann auch ICQ-Nachrichten senden)
- Trac Issue Tracking/Wiki: http://trac.edgewall.org/browser/trunk/contrib/trac-post-commit-hook
- Bei Tigris liegen auch noch einige, aber auch viel unnützes Zeug: http://subversion.tigris.org/tools_contrib.html#hook_scripts
Falls ihr noch andere Hook-Scripte habt, nur her damit!
EDIT: Stefan empfiehlt noch ein tolles Hook-Script, mit dem man automatisch nach einem Commit die geänderten Dateien auf einen FTP, SFTP oder Filesystem synchronisieren kann: http://svn2web.sourceforge.net
Hallo,
schöner Artikel. Hältst du es echt für sinnvoll den PHP_CodeSniffer in den hook zu hängen? Ich finde es immer unangebracht den commit zu verhindern, nur weil eine „Kleinigkeit“ nicht stimmt. PHPUnit sehe ich ähnlich. Ist zwar schön, sicher zu sein, dass der Code sauber ist, aber in Notfällen darf Formatierung oder ähnliches kein Hindernis sein.
Wollte ich aber auch mal einen Artikel zu verfassen 🙂
Gruß,
Nils
PS: Mach weiter so 🙂
Nils
16 Jul 09 at 12:36
Vielleicht solltest du den Artikel nochmal lesen. Ich schrieb, dass ich den CodeSniffer selbst nicht eingebunden habe genau aus den Gründen. Man KANN es aber machen, wenn man nur eigenen Code schreibt und korrekten Codestyle als Pflicht ansieht.
Bei PHPUnit wird auch nur eine Email versandt bei Fehlern, der Commit ist trotzdem erfolgreich.
Michael Kliewe
16 Jul 09 at 12:39
Ok, dann nehme ich alles zurück, hab da wohl einen Teil wirklich überflogen (meinte aber eigentlich gar nicht fremden Code, sondern eigenen, egal) 🙂
Wir setzen bei der Geschichte eine Continuous Integration Lösung ein, finde ich in dem Fall ein wenig eleganter, da ich das Ganze noch ein wenig grafisch Aufbereitet habe. Aber php -l ist fast schon Pflicht beim committen.
Nils
16 Jul 09 at 12:49
CI kenne ich nur in der Theorie, wir haben das nirgends im Einsatz. Werde mir das mal anschauen. Schlagworte sind da wohl phpUnderControl, Xinc und CruiseControlPHP.
Kommt da in naher Zukunft von dir/euch ein Artikel? Sonst mach ich einen 😉
Michael Kliewe
16 Jul 09 at 13:27
Ich wäre sehr an einem solchen Artikel interessiert.
Wir haben ja gerade unseren neuen Dienst demobereich.de gelauncht und solche Dinge (phpUnderControl, …) werden wir dort definitiv laut Roadmap anbieten…nur weiß hier noch keiner, wie das genau eingebunden wird. Also wer dort unterstützen kann – und sei es durch einen Artikel – der soll das bitte tun 😉
Ansonsten weiter so. Super Arbeit/Artikel von dir!
Robert Kummer
16 Jul 09 at 14:52
Hi,
ein sehr schönes Skript fand ich auch immer dieses:
http://svn2web.sourceforge.net
Damit wird mittels einer Prop z.B. ein Ordner direkt mittels ftp/sftp übertragen.
Grüße,
Stefan
Stefan
16 Jul 09 at 14:54
Ja einen Artikel zu phpUnderControl wird es sogar recht zeitnah geben. Zumindest wurde er mir zugesagt 🙂 Wir werden übrigens Bamboo als CI Lösung einsetzen.
Nils
16 Jul 09 at 15:34
[…] https://www.phpgangsta.de/sinnvolle-svn-hooks-fur-php-projekte […]
Interessante Links im Netz IV « DaRaFF's Blog
30 Mrz 10 at 10:25
[…] eigentlich leicht automatisch finden kann. Einen kleinen Denkanstoß findet man beispielsweise beim PHP Gangsta. veröffentlicht unter: Magento Kommentar schreiben Kommentare (0) Trackbacks (0) ( Kommentare […]
Fehler in der API von Magento 1.4.1.0 | Binärmüll
22 Jun 10 at 11:25
Vielen Dank für diesen netten Einstieg in pre-commit hooks. Jedoch habe ich ein kleines Phänomen welches ich mir nicht erklären kann. In Zeile 15 wird der Inhalt der jeweiligen Datei „gecattet“ und dann an php -l übergeben. Dies hat auf meinem Server nicht funktioniert. Erst nachdem ich die cat Ausgabe temporär gespeichert habe wollte php -l die parse Errors erkennen. Hat dieses Phänomen noch jemand?
Meine Variante:
MESSAGE=`$SVNLOOK cat -t „$TXN“ „$REPOS“ „$FILE“ > tmp; $PHP -l tmp`
Lutz
17 Aug 11 at 12:07
Ich hab mir damals ein PHP Hook Framework gebastelt, da das CodeSniffer Script (damals) versucht hat, auch gelöschte Dateien zu validieren, ja sogar Verzeichnisse. Gleichzeitig noch Datei, Verzeichnisfilter zu implementieren, weil ich z.B. bei Verwendung Drittkomponenten beim Commiten nicht immer den gleichen Style Guide voraus setzen kann. Je größer das Projekt umso mehr individuelle Hooks möchte man haben und das wird mit Shell Scripte evtl. unübersichtlich.
Das ganze gibt es hier: http://github.com/alexanderzimmermann/HookFramework fertig.
Im Wiki ist eine Doku wie man das ganze implementieren kann.
Alex
22 Aug 11 at 12:47