RSS

PHP Code Conventions mit CodeSniffer und Subversion

PHP Code Conventions mit CodeSniffer und Subversion

Ich habe heute diesen PHPAdvent Artikel gelesen.

In dem Artikel von Travis Swiceood geht es darum unter Verwendung Hook-Scripts bei Versionmanagement Werkzeugen wie Git oder SVN, die Übermittlung fehlerhaften Codes zu vermeiden.

Die folgenden Snippets enthalten Code, bei dem ggf. die Pfade anzupassen sind! Ich spare mir einfach das an den Stellen jeweils zu erwähnen.

Im dem Artikel geht es konkret darum die PHP lint Funktion zu nutzen um Syntax Fehler zu entdecken:

<?php
ech "Hallo Welt";
?>

wenn man dies nun mittels PHP mit dem Parameter “-l” ausführt, erhält man folgendes:

xen-developement:~# php -l demo.php

Parse error: syntax error, unexpected T_CONSTANT_ENCAPSED_STRING in demo.php on line 2
Errors parsing demo.php

Nun sollte es doch ein leichtes sein, dieses auch in den Commit-Vorgang zu integrieren, und im Fall von übertragenen PHP Dateien, selbige vorher zu prüfen. Gesagt getan. Dazu habe ich ein bisl rumgesucht und hier folgendes gefunden:

PHP="/usr/bin/php"
AWK="/usr/bin/awk"
GREP="/bin/egrep"
SED="/bin/sed"

CHANGED=`$SVNLOOK changed -t "$TXN" "$REPOS" | $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>&amp;2
echo "***********************************" 1>&amp;2
echo "PHP error in: $FILE:" 1>&amp;2
echo `echo "$MESSAGE" | $SED "s| -| $FILE|g"` 1>&amp;2
echo "***********************************" 1>&amp;2
exit 1
fi
done

Das wird entsprechend in die pre-commit datei deines SVN Repositorys vor exit 0 eingetragen. Die Datei ist von pre-commit.tmpl nach pre-commit umzubennen und mit ausführbaren Rechten zu versehen:

cd /home/repository/svn/hooks/
cp pre-commit.tmpl pre-commit
chmod 0755 pre-commit
vi pre-commit

Damit sollte euer Code schonmal nicht mehr mit syntaktischen Fehler im Repository landen können.

Nun hatte ich aber in der Überschrift von CodeSniffer gesprochen. Darum ging es nämlich in dem ursprünglich inspirierenden Artikel nicht. Und wie der Zufall so will, habe ich den Weg auch direkt zu PHPCS gefunden. Nach wenigen Sekunden fand ich dann auch direkt einen passenden Hook-Script, welcher direkt mit angeboten wird hier. Gesagt getan – der Plan wurde wie folgt umgesetzt:

PHP CodeSniffer via Pear installieren:

xen-developement:~# pear install PHP_CodeSniffer
downloading PHP_CodeSniffer-1.1.0.tgz ...
Starting to download PHP_CodeSniffer-1.1.0.tgz (236,962 bytes)
........................done: 236,962 bytes
install ok: channel://pear.php.net/PHP_CodeSniffer-1.1.0

Anschließend ins Pear Verzeichnis wechseln, scripts verzeichnis anlegen, hook Script herunterladen, umbenennen und ausführbar machen:

cd /usr/share/php/PHP/
ls -la
mkdir scripts
cd scripts/
wget http://cvs.php.net/viewvc.cgi/pear/PHP_CodeSniffer/scripts/phpcs-svn-pre-commit?view=co
mv phpcs-svn-pre-commit\?view\=co phpcs-svn-pre-commit
chmod 0755 phpcs-svn-pre-commit

Die Dokumentation ist zwar vorhanden, hat aber bei mir mehr schlecht als recht funktioniert. Daher spare ich mir dies hier zu zeigen, sondern poste direkt meine Modifikationen, mit denen es bei mir läuft:

vi phpcs-svn-pre-commit

Dort ist die 1. Zeile an den PHP Pfad anzupassen:

@php_bin@ nach /usr/bin/php

Anschließend ist noch eure pre-commit Datei im Repository Verzeichnis wieder anzupassen, meine sieht nun am Ende so aus:

REPOS="$1"
TXN="$2"

# Make sure that the log message contains some text.
SVNLOOK=/usr/bin/svnlook
#$SVNLOOK log -t "$TXN" "$REPOS" | grep "[a-zA-Z0-9]" &gt; /dev/null || exit 1

# Check that the author of this commit has the rights to perform
# the commit on the files and directories being modified.
#/usr/share/subversion/hook-scripts/commit-access-control.pl "$REPOS" "$TXN" "$REPOS"/commit-access-control.cfg || exit 1

#echo "/usr/share/php/PHP/scripts/phpcs-svn-pre-commit \"$REPOS\" -t \"$TXN\" &gt;&amp;2" &gt;&amp;2

PHP="/usr/bin/php"
AWK="/usr/bin/awk"
GREP="/bin/egrep"
SED="/bin/sed"

CHANGED=`$SVNLOOK changed -t "$TXN" "$REPOS" | $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>&amp;2
echo "***********************************" 1>&amp;2
echo "PHP error in: $FILE:" 1>&amp;2
echo `echo "$MESSAGE" | $SED "s| -| $FILE|g"` 1>&amp;2
echo "***********************************" 1>&amp;2
exit 1
fi
done

/usr/share/php/PHP/scripts/phpcs-svn-pre-commit -t "$TXN" "$REPOS" &gt;&amp;2 || exit 1

# All checks passed, so allow the commit.
exit 0

Ich musste, damit es funktioniert auch die phpcs-svn-pre-commit Datei bearbeiten, genau genommen an 2 Stellen. Hier der Diff:

< #!@php_bin@
---
> #!/usr/bin/php
70c70
<     public function processUnknownArgument($arg, $pos, $values)
---
>     public function processUnknownArgument($arg, $pos, $values = array())
134c134,136
<         foreach (preg_split('/\v/', $contents, -1, PREG_SPLIT_NO_EMPTY) as $path) {
---
>       #echo $contents;
>
>         foreach (preg_split('/ /', $contents, -1, PREG_SPLIT_NO_EMPTY) as $path) {

Das war’s dann auch schon. Die Scripte können nun nicht mehr unformatiert oder mit Syntax-Fehlern committed werden. Hier ein Code Beispiel und der fehlgeschlagene Versuch, es zu übertragen:

So – ich wünsche euch viel Spass beim Nachbasteln. Es bleiben natürlich einige Fragen offen, wie effektiv bzw. wie sinnvoll das Ganze ist. Wird man sich dadurch nicht mehr Arbeit machen als nötig? Ich denke das sind Fragen, die hier grad nicht hergehören – ich wollte nur mal aufzeigen was so geht.

Wer weitere Ideen hat, kann diese gerne hier posten!

Popularity: 100% [?]

Gleich bookmarken:
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • LinkArena
  • Live
  • MisterWong.DE
  • BlinkList
  • Furl
  • Spurl
  • StumbleUpon
  • Technorati
  • YahooMyWeb

Werbung:


, , , , , , , , , , ,

This post was written by:

Ronny - who has written 343 posts on Ronny’s Blog.


Contact the author

5 Comments For This Post

  1. Gerd (1 comments) Says:

    Oh, schöner Beitrag!
    Genau das, was ich derzeit brauche.

    Danke!
    Gerd.

  2. galak (1 comments) Says:

    RELEASE_1_2_0RC2 von CodeSniffer räumt mit den ganzen o.g. Umbauten auf und funktioniert bei mir “out-of-the-box”

  3. Ronny (57 comments) Says:

    @galak gut zu wissen :)

  4. alex (2 comments) Says:

    Dies liegt aber nicht (nur) an PHP_CodeSniffer sondern an der PHP Version. Der Reguläre Ausdruck \v ist erst ab PHP 5.2.4 verfügbar. PHP_CodeSniffer benötigt aber nur Version 5.1.2.

    Die Umbauten wie oben funktionieren nicht einwandfrei.
    Verwende ich wie du preg_split(‘/ /’, $contents, … wird nur die erste Datei vom Sniffer geprüft. Alle folgenden nicht. Checkt man also 5 Dateien ein, wird ein Fehler in Datei 2-5 nicht gefunden. (zumindest bei mir PHP 5.1.2)

    Da werde ich wohl um ein PHP update nicht herumkommen.

  5. Ben (1 comments) Says:

    Interessanter Artikel, beim Suchen nach CodeSniffer in Bezug auf PHP bin ich auf diesen Beitrag gestoßen und denke das ich aus deinem Artikel einige interessante Informationen ziehen konnte. Danke!

1 Trackbacks For This Post

  1. FirePHP als Debugger für PHP und Ajax einsetzen « hasematzel.de: Ein Blog von Oliver Schwarz Says:

    [...] B. der phpCodeSniffer an, der sich wiederum im pre-commit hook einsetzen lässt. Dazu gibt es eine großartige Zusammenfassung von Ronny Ristau. Dieser Artikel wurde am 18. April 2009 um 8:40 Uhr veröffentlicht. Tags: debugging, [...]

Leave a Reply

You can add images to your comment by clicking here.