PHPGangsta - Der praktische PHP Blog

PHP Blog von PHPGangsta


Sinnvolle SVN Hooks für PHP Projekte

with 11 comments

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:

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

Written by Michael Kliewe

Juli 16th, 2009 at 12:24 pm

Posted in PHP

Tagged with , , ,

11 Responses to 'Sinnvolle SVN Hooks für PHP Projekte'

Subscribe to comments with RSS or TrackBack to 'Sinnvolle SVN Hooks für PHP Projekte'.

  1. 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

  2. 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

  3. 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

  4. 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

  5. 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

  6. 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

  7. 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

  8. […] 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 […]

  9. 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

  10. 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

Leave a Reply

You can add images to your comment by clicking here.