I've just commit a new script to PHP_CodeSniffer called phpcs-svn-pre-commit. It sits in the scripts dir with phpcs and phpcs.bat. This script was contributed by Jake Bates, who has also volunteered to maintain the Debian package, and will be available in the 1.1.0 release.
Using the script is pretty easy, but you'll need to modify it slightly.
Edit /path/to/PHP_CodeSniffer/scripts/phpcs-svn-pre-commit and replace @php_bin@ in the first line with the path to the PHP CLI. For example,
#!@php_bin@becomes
#!/usr/bin/php
Then, ensure the path to svnlook is correct by modifying the line:
define('PHP_CODESNIFFER_SVNLOOK', '/usr/bin/svnlook');Now, add the following line to your pre-commit file in the SVN hooks directory:
/.../phpcs-svn-pre-commit "$REPOS" -t "$TXN" >&2 || exit 1
This will cause the SVN commit to fail if PHP_CodeSniffer finds any errors. The error report will be displayed to the user so they can fix errors before attempting the commit again.
You can also use all the standard phpcs command line options to do things like set the standard to use, the tab width and the error report format:
/.../phpcs-svn-pre-commit --standard=Squiz --tab-width=4 ...
And some example output:
$ svn commit -m "Test" temp.php
Sending temp.php
Transmitting file data .svn: Commit failed (details follow):
svn: 'pre-commit' hook failed with error output:
FILE: temp.php
---------------------------------------------------------------
FOUND 1 ERROR(S) AND 0 WARNING(S) AFFECTING 1 LINE(S)
---------------------------------------------------------------
2 | ERROR | Missing file doc comment
---------------------------------------------------------------

17 comments:
Can the script be configured to be not so nazi? E.g. allowing 1 CS error / 10 lines or that the overall CS error count may not increase (if you only change some lines of a file)
Not with this script. You'd have to copy the phpcs-svn-pre-commit script and modify how it exits. You are able to get the total error and warning count, and the number of lines, so you could add whatever calculations you want.
Hi Greg,
A good start for a helpful pre-commit hook. However there are situations where an error is almost certain, and nothing can be done about it. For instance, I just submitted a PEAR proposal for a stream package, and per the stream API, the class cannot satisfy the PEAR coding standards due to method names like stream_open(), stream_close(), etc... So a pre-commit hook would never let such valid code go through. A whitelist might be useful, but that requires PHP_CodeSniffer to recognize and fingerprint the error.
Anyway, PHP_CS is great! Keep up the good work.
Started writing my own pre-commit hook for CodeSniffer when I ran across this. Yours is, shall I say, a bit more robust?
Any hint on when it might be released?
@Philippe
You are right, and I wont be stopping commits in work projects using this hook, although I'll probably write a post-commit hook to name and shame people :)
@Gerard
I don't have a fixed date for the next release, but it should be in the next couple of weeks. You can checkout PHP_CodeSniffer from cvs.php.net and install it using PEAR (or run it stand-alone) if you want it sooner. Info is here: http://pear.php.net/manual/en/installation.cvs.php
@Greg
Let this good ideas keep coming
@Philippe
The value you have on your flag standard defines which standard class will be used for validating your commit. If you want something like a specialization of PEAR or Zend, you can extend that Standard Class using a white list as a parameter of your sub-class.
I installed PHP_CodeSniffer using pear and copied the scripts folder to path-where-phpcodesniffer-exists
The pre-commit hook looks something like this
#!/bin/sh
REPOS="$1"
TXN="$2"
/usr/local/php5/lib/php/PHP/CodeSniffer/scripts/phpcs-svn-pre-commit --standard=Himanshu "$REPOS" -t "$TXN" >&2 || exit 1
the phpcs-svn-pre-commit has the php path as
/usr/local/php5/bin/php.
On committing a php code it doesn't show any error whereas if I use
phpcs --standard=Himanshu test.php
I get the error.
FILE: /usr/local/svn/Test/hooks/test.php
--------------------------------------------------------------------------------
FOUND 1 ERROR(S) AND 0 WARNING(S) AFFECTING 1 LINE(S)
--------------------------------------------------------------------------------
2 | ERROR | Spaces must be used to indent lines; tabs are not allowed
--------------------------------------------------------------------------------
What could be the reason ?
@Anonymous Try using the latest code from CVS. There is a bug in the latest version: http://pear.php.net/bugs/bug.php?id=16054
Hey Greg,
Thanks for replying. Well could you send me the correct path from where I can download this.
Moreover do I need to compile PHP_CodeSniffer (if not using pear install)
Hey Greg,
Works fine with PHP_CodeSniffer-1.2.0RC1.
Thanks a ton !!
Cheers !!
Hey Greg,
My repository setup is something like this.
---- Development
Repo---- QA
---- Production
Now with pre-commit hook in place if I try to add any directory in any of the trunks it returns an error.
[root@localhost Production]# svn add Release0/
A Release0
[root@localhost Production]# svn commit -m "done"
Adding Production/Release0
svn: Commit failed (details follow):
svn: Commit blocked by pre-commit hook (exit code 1) with output:
svnlook: Path 'Production/Release0' is not a file
Is there a way I could tell the script to check only php scripts and exclude everything else. Also when I tried to commit a file x.php
I get the following error
--------------------------------------------------------------------------------
FOUND 1 ERROR(S) AND 0 WARNING(S) AFFECTING 1 LINE(S)
--------------------------------------------------------------------------------
2 | ERROR | Spaces must be used to indent lines; tabs are not allowed
--------------------------------------------------------------------------------
On removing the extra spaces I am able to commit this file but later when I delete this file I get the following error
[root@localhost Resdex]# svn commit -m "done"
Deleting x.php
svn: Commit failed (details follow):
svn: Commit blocked by pre-commit hook (exit code 1) with output:
svnlook: Try 'svnlook help' for more info
svnlook: Missing repository path argument
Please help !!
Hi,
I am having difficulty using CodeSniffer with SVN. The phpcs-svn-pre-commit script works fine with files but not with directory i.e. everytime I try to add a directory the pre-commit hook gives the following error
Transmitting file data .svn: Commit failed (details follow):
svn: Commit blocked by pre-commit hook (exit code 1) with output:
svnlook: Path 'b' is not a file
PHP Fatal error: Uncaught PHP_CodeSniffer_Exception: Could not auto-detect line endings from content in /usr/local/php5/lib/php/PHP
What could be the reason for the same? I installed PHP_CodeSniffer using pear and phpcs version is 1.2.0RC1.
Also, on deleting a file that was earlier committed (after making changes in the php file) it gives error
svn: Commit failed (details follow):
svn: Commit blocked by pre-commit hook (exit code 1) with output:
svnlook: Try 'svnlook help' for more info
svnlook: Missing repository path argument
PHP Fatal error: Uncaught PHP_CodeSniffer_Exception: Could not auto-detect line endings from content in /usr/local/php5/lib/php/PHP/CodeSniffer/File.php on line 435
Thanks in advance.
@Himanshu and Anonymous: I'll take a look. Probably just a bug. I encourage you to submit bug reports to the official bug tracker by clicking the link at: http://pear.php.net/package/PHP_CodeSniffer
Hi,
I'm trying to configure the pre-commit-hook. The script gets started, however there are never errors reported.
If I run the CLI script phpcs over the file I'm committing, I've 22 errors.
Any idea what could be wrong? I've tried both the latest stable as the latest beta version.
Any advice would be very appreciated!
i have managed to add the precommit script but i get no errors.
I have another check for a log message after the codeSniffer check ... and i get prepended this string:
[M m8
i think that is the output from code sniffer.
can you please help me
Hey Greg,
I have a tree structure within the repo i.e a repo has following branches
1> Dev
2> QA
3> Prod
How can I restrict php code sniffer only to Dev and QA branches and not production??
Thanks in advance !!
@Anonymous I'm not 100% sure. I think you do it in the commit hook script itself and not touch anything in PHP_CodeSniffer or the command that runs it, but I'm not very familiar enough with those hooks to give an example.
Post a Comment