November 22, 2010

Sonar for PHP coming

sonarI have received a lot of positive feedback after my The Journey towards Continuous Integration talk at PHP NW 2010 conference. It seems that a lot of people have found it both interesting and inspiring. I am really glad. After the talk many people asked me about Sonar which I briefly mentioned and were eager to know more about it. With this blog post I will try to fill the gap in my talk.

Solving the mistery

I have heard about Sonar for the first time about a year ago I think. It looked cool! All the fancy graphs, statistics, numbers… But, first I couldn’t understand how would it actually fit into our development process and secondly it had no support for PHP. A lot of things has changed since then though.

With a continuous integration process nearly in place at work, we now need to properly track the progress not only of the build itself, but also how in overall our code quality changes. We want to know whether the code complies to the rules we have set up, whether over time it gets better and at the same time we want to communicate the progress to the business.  What a surprise for me it was, when I have found out that actually all of that we could achieve with Sonar! And imagine the grin on my face when I was told that there are people that have started working on PHP plugin for Sonar!

Installing Sonar

Installing Sonar is very easy. Sonar runs on any operating system that support Java and Maven. For version 2.1 which I am gonna install you will need Java Development Kit v1.5 or later and Maven 2.0.9+, 2.1.+ or 2.2.+.

If you’re using Ubuntu distribution, just can just follow the instructions below.

To install Sun JDK you need to enable partner repositories first. Just edit /etc/apt/sources.list , uncomment the following lines:

# deb http://archive.canonical.com/ubuntu maverick partner
# deb-src http://archive.canonical.com/ubuntu maverick partner

and install the JDK:

#> sudo apt-get update
#> sudo apt-get install sun-java6-jdk

To install maven you can use apt-get as well:

#> sudo apt-get install maven2

With all the things in place it’s time to download Sonar. You can get it from its download page. Remember that not all plugins are compatible with all Sonar versions, so before you make a decision which version to download check Sonar Compatibility matrix. Because I am gonna use 0.2 version of PHP plugin I will download Sonar 2.1.2.

#> wget http://dist.sonar.codehaus.org/sonar-2.1.2.zip

Installation is as easy as just unpacking the archive:

#> mkdir ~/apps
#> cd ~/apps && unzip /home/proofek/Downloads/sonar-2.1.2.zip

Configuring Sonar

By default Sonar runs with an embedded Apache Derby database. If you want just to play with Sonar or test it then you can just skip the next step, but if you plan to use it later on or you want to install it in a production environment then you better switch to more robust database server like MySQL, Oracle, Postgresql or MS SqlServer. Sonar suports them all. I will install it and configure it with MySQL server.

First, let’s install MySQL server. Again apt comes handy:

#> sudo apt-get install mysql-server

The server should automatically be started after that and should accept any incoming connections. Now we have to create empty database and a user that Sonar will use. Let’s name the database and user sonar and use S0n4rU53r as a password. Obviously it’s up to you how you will call them, just make sure you use the same names later on in Sonar configuration file. Also remember this is only a sample configuration and you might want to configure the access to database differently for security reasons.

#> mysql -uroot -p -e "CREATE DATABASE sonar"
#> mysql -uroot -p -e "CREATE USER 'sonar'@'%' IDENTIFIED BY 'S0n4rU53r'"
#> mysql -uroot -p -e "GRANT ALL ON sonar.* TO 'sonar'@'%'"

Next, edit conf/sonar.properties configuration file, uncomment template for MySQL support and comment out the default Derby configuration.

#sonar.jdbc.url: jdbc:derby://localhost:1527/sonar;create=true
#sonar.jdbc.driver: org.apache.derby.jdbc.ClientDriver
#sonar.jdbc.defaultTransactionIsolation: 1
#sonar.jdbc.validationQuery: values(1)
sonar.jdbc.url: jdbc:mysql://localhost:3306/sonar?useUnicode=true&characterEncoding=utf8
sonar.jdbc.driver: com.mysql.jdbc.Driver
sonar.jdbc.validationQuery: select 1

At the bottom of that file, in Global database settings section, you can change default database username and password.

sonar.jdbc.username:                       sonar
sonar.jdbc.password:                       S0n4rU53r
sonar.jdbc.maxActive:                      10
sonar.jdbc.maxIdle:                        5
sonar.jdbc.minIdle:                        2
sonar.jdbc.maxWait:                        5000
sonar.jdbc.minEvictableIdleTimeMillis:     600000
sonar.jdbc.timeBetweenEvictionRunsMillis:  30000

If you want to run Sonar on different IP address or port you can configure that at the top of this configuration file:

# Listen host/port and context path (for example / or /sonar). Default values are 0.0.0.0:9000/
#sonar.web.host:                           0.0.0.0
#sonar.web.port:                           9000
#sonar.web.context:                        /

Now we’re ready to start Sonar for the first time. Start  and stop scripts are located in bin directory.

Execute the following script to start the server :

  • on linux/mac : bin/[YOUR PLATEFORM]/sonar.sh start
  • on windows : bin/windows-x86-32/StartSonar.bat

Note that you can also run as a NT service with bin/windows-x86-32/InstallNTService.bat, then bin/windows-x86-32/StartNTService.bat

For Linux start command will look like this:

#> ~/apps/sonar-2.1.2/bin/linux-x86-32/sonar.sh start

and you stop Sonar like this:

#> ~/apps/sonar-2.1.2/bin/linux-x86-32/sonar.sh stop

It gets a while to start it for the first time as the database schema is being set up. Have a look at the log file to see the progress and watch for any issues that might prevent Sonar from starting.

#> tail -f ~/apps/sonar-2.1.2/logs/sonar.log

Message like this indicates that application is ready to use:

2010.11.09 21:55:39 INFO  org.sonar.INFO  Sonar started: http://0.0.0.0:9000/

Just browse now to http://localhost:9000/. Sonar is ready to use.

Sonar dashboard
Sonar dashboard (after first run)

Installing PHP plugin

At the moment (mid Nov 2010), only version 0.2 of the plugin has been released, and you can download it from the official plugin site.

It’s split into 5 separate jar files:

  • core PHP plugin
  • PHPUnit plugin
  • PHP_Codesniffer plugin
  • PHP Depend plugin
  • PHP MD plugin
#> wget http://repository.codehaus.org/org/codehaus/sonar-plugins/sonar-php-plugin/0.2/sonar-php-plugin-0.2.jar
#> wget http://repository.codehaus.org/org/codehaus/sonar-plugins/sonar-php-unit-plugin/0.2/sonar-php-unit-plugin-0.2.jar
#> wget http://repository.codehaus.org/org/codehaus/sonar-plugins/sonar-php-codesniffer-plugin/0.2/sonar-php-codesniffer-plugin-0.2.jar
#> wget http://repository.codehaus.org/org/codehaus/sonar-plugins/sonar-php-depend-plugin/0.2/sonar-php-depend-plugin-0.2.jar
#> wget http://repository.codehaus.org/org/codehaus/sonar-plugins/sonar-php-pmd-plugin/0.2/sonar-php-pmd-plugin-0.2.jar

But that’s not all. The plugin actually requires the following tools to be installed on a machine that you are going to analyse your project on (and it actually doesn’t have to be the same machine you install Sonar on):

If you are already using them, you will know how to install/configure them. Only PHP_Codesniffer requires special treatment, so I strongly recommend you follow my installation guide for PHP_Codesniffer below. For those of you, who are not really familiar with these tools yet, here is a quick guide how to set them all up.

PHP + PEAR

Fairly simple installation, especially with apt:

#> sudo apt-get install php5-cli
#> php -v
PHP 5.3.3-1ubuntu9.1 with Suhosin-Patch (cli) (built: Oct 15 2010 14:17:04)
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies
#> sudo apt-get install php-pear
#> pear list
Installed packages, channel pear.php.net:
=========================================
Package          Version State
Archive_Tar      1.3.7   stable
Console_Getopt   1.2.3   stable
PEAR             1.9.1   stable
Structures_Graph 1.0.3   stable
XML_Util         1.2.1   stable

PHPUnit + Xdebug

Now lets use PEAR installer to install PHPUnit. This is a standard installation procedure for PHPUnit.

#> sudo pear channel-discover pear.phpunit.de
#> sudo pear channel-discover components.ez.no
#> sudo pear channel-discover pear.symfony-project.com
#> sudo pear install --alldeps phpunit/PHPUnit
#> phpunit --version
PHPUnit 3.5.3 by Sebastian Bergmann.

and pecl installer to install Xdebug. We will need php sources and some development tools as well, because pecl will actually compile Xdebug on the fly before installing it. For systems from Ubuntu/Debian family just use apt to install php5-dev package.

#> sudo apt-get install php5-dev

And after that install Xdebug and enable the extension by creating xdebug.ini file with the following content:

#> sudo pecl install xdebug
#> sudo vim /etc/php5/conf.d/xdebug.ini
zend_extension=/usr/lib/php5/20090626+lfs/xdebug.so
xdebug.auto_trace = "Off"
xdebug.collect_params = "On"
xdebug.collect_return = "Off"
xdebug.trace_format = "0"
xdebug.trace_options = "1"
xdebug.trace_output_dir = "/local/tmp/xdebug"
xdebug.trace_output_name = "timestamp"
xdebug.profiler_enable = "0"
xdebug.auto_profile = "1"
xdebug.auto_profile_mode = "6"
xdebug.output_dir = "/local/tmp/xdebug"
xdebug.profiler_output_dir = "/local/tmp/xdebug"
xdebug.profiler_output_name = "timestamp"

Refer to Xdebug documentation for specific configuration options. Let’s just verify now that PHP has Xdebug support.

#> php -v
  PHP 5.3.3-1ubuntu9.1 with Suhosin-Patch (cli) (built: Oct 15 2010 14:17:04)
  Copyright (c) 1997-2009 The PHP Group
  Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies
      with Xdebug v2.1.0, Copyright (c) 2002-2010, by Derick Rethans

PHP_Codesniffer

With PHP_Codesniffer it’s a little bit different. The stable version 1.2.2 which is available now (mid Nov 2010) doesn’t support rulesets yet (but bear in mind version 1.3 will). So guys at SQLi have come up with a work around.

First of all if you already have PHP_Codesniffer installed with version bigger then 1.2.2 you have to uninstall it first. And that’s because we have to install a modified version 1.2.3 of PHP_CodeSniffer. BUT REMEMBER, this is not an official release. It has been created specifically to work with Sonar. So:

#> sudo pear uninstall PHP_CodeSniffer

and

#> wget https://www.assembla.com/spaces/sqlics/documents/dSJnowvZqr35SUeJe5cbLr/download/dSJnowvZqr35SUeJe5cbLr -O PHP_CodeSniffer_1.2.3.tgz
#>  sudo pear install ~/Downloads/PHP_CodeSniffer_1.2.3.tgz
#> phpcs --version
PHP_CodeSniffer version 1.2.3 (stable) by Squiz Pty Ltd. (http://www.squiz.net)

Then we have to download and install SQLi Codesniffer which will work like a bridge between Sonar and PHP_Codesniffer.

#> wget https://www.assembla.com/spaces/sqlics/documents/ak6024vZur34RweJe5cbLA/download/ak6024vZur34RweJe5cbLA -O SQLI_CodeSniffer_0.4.0dev1.tgz
#> sudo pear install /home/proofek/Downloads/SQLI_CodeSniffer_0.4.0dev1.tgz
#> sqlics --version
SQLI_CodeSniffer version 0.4.0dev1 (alpha) by SQLI (http://www.sqli.com)

If for any reasons these links or instructions doesn’t work anymore, check the original instructions at SQLi site.

PHP Depend

PHP Depend installation is also a standard one:

#> sudo pear channel-discover pear.pdepend.org
#> sudo pear install pdepend/PHP_Depend-beta
#> pdepend --version
PHP_Depend 0.9.19 by Manuel Pichler

PHPMD

Same with PHP Mess Detector:

#> sudo pear channel-discover pear.phpmd.org
#> sudo pear install --alldeps phpmd/PHP_PMD-alpha
#> phpmd --version
PHPMD 0.2.7 by Manuel Pichler

With all tools in place, just stop Sonar, copy the jar files to Sonar’s plugins directory (~/apps/sonar-2.1.2/extensions/plugins/) and start Sonar again:

#> ~/apps/sonar-2.1.2/bin/linux-x86-32/sonar.sh stop
#> cp sonar-php-plugin-0.2.jar sonar-php-codesniffer-plugin-0.2.jar sonar-php-depend-plugin-0.2.jar sonar-php-pmd-plugin-0.2.jar sonar-php-unit-plugin-0.2.jar /home/proofek/apps/sonar-2.1.2/extensions/plugins/
#> ~/apps/sonar-2.1.2/bin/linux-x86-32/sonar.sh start

If you carefully watch logs now you will see the plugins being loaded and set up!

#> tail -f ~/apps/sonar-2.1.2/logs/sonar.log
2010.11.09 22:51:18 INFO  org.sonar.INFO  Load metrics...
2010.11.09 22:51:19 INFO  org.sonar.INFO  cleaning alert thresholds...
2010.11.09 22:51:19 INFO  org.sonar.INFO  Load metrics done: 1118 ms
2010.11.09 22:51:19 INFO  org.sonar.INFO  Load rules...
2010.11.09 22:51:19 INFO  org.sonar.INFO  loading 365 findbugs rules...
2010.11.09 22:51:21 INFO  org.sonar.INFO  loading findbugs extensions...
2010.11.09 22:51:21 INFO  org.sonar.INFO  loading 97 PHP CODESNIFFER rules...
2010.11.09 22:51:22 INFO  org.sonar.INFO  loading PHP CODESNIFFER extensions...
2010.11.09 22:51:22 INFO  org.sonar.INFO  loading 12 PHP PMD rules...
2010.11.09 22:51:22 INFO  org.sonar.INFO  loading PHP PMD extensions...
2010.11.09 22:51:22 INFO  org.sonar.INFO  loading 123 checkstyle rules...
2010.11.09 22:51:23 INFO  org.sonar.INFO  loading checkstyle extensions...
2010.11.09 22:51:23 INFO  org.sonar.INFO  loading 216 pmd rules...
2010.11.09 22:51:25 INFO  org.sonar.INFO  loading pmd extensions...
2010.11.09 22:51:25 INFO  org.sonar.INFO  loading 3 squid rules...
2010.11.09 22:51:25 INFO  org.sonar.INFO  loading squid extensions...
2010.11.09 22:51:25 INFO  org.sonar.INFO  Load rules done: 6566 ms
2010.11.09 22:51:25 INFO  org.sonar.INFO  Load profiles...
2010.11.09 22:51:27 INFO  org.sonar.INFO  loading findbugs profiles...
2010.11.09 22:51:27 INFO  org.sonar.INFO  loading the profile Sonar way with Findbugs/java from findbugs
2010.11.09 22:51:34 INFO  org.sonar.INFO  loading PHP CODESNIFFER profiles...
2010.11.09 22:51:34 INFO  org.sonar.INFO  loading the profile Default Php Profile/php from PHP CODESNIFFER
2010.11.09 22:51:37 INFO  org.sonar.INFO  loading PHP PMD profiles...
2010.11.09 22:51:37 INFO  org.sonar.INFO  loading the profile Default Php Profile/php from PHP PMD
2010.11.09 22:51:38 INFO  org.sonar.INFO  loading checkstyle profiles...
2010.11.09 22:51:38 INFO  org.sonar.INFO  loading the profile Sonar way/java from checkstyle
2010.11.09 22:51:39 INFO  org.sonar.INFO  loading the profile Sonar way with Findbugs/java from checkstyle
2010.11.09 22:51:40 INFO  org.sonar.INFO  loading the profile Sun checks/java from checkstyle
2010.11.09 22:51:43 INFO  org.sonar.INFO  loading pmd profiles...
2010.11.09 22:51:43 INFO  org.sonar.INFO  loading the profile Sonar way/java from pmd
2010.11.09 22:51:47 INFO  org.sonar.INFO  loading the profile Sonar way with Findbugs/java from pmd
2010.11.09 22:51:51 INFO  org.sonar.INFO  loading the profile Sun checks/java from pmd
2010.11.09 22:51:51 INFO  org.sonar.INFO  loading squid profiles...
2010.11.09 22:51:51 INFO  org.sonar.INFO  activating php default profile...
2010.11.09 22:51:51 INFO  org.sonar.INFO  activating java default profile...
2010.11.09 22:51:51 INFO  org.sonar.INFO  Load profiles done: 25681 ms
2010.11.09 22:51:51 INFO  org.sonar.INFO  Start sonar done: 37528 ms
2010.11.09 22:52:12 INFO  org.sonar.INFO  Loading web services...
2010.11.09 22:52:13 INFO  org.sonar.INFO  Sonar started: http://0.0.0.0:9000/

Preparing for analysis

We’re just about to analyse our first project then. How exciting! There is only a few things left before we can start though.

Sonar uses maven to analyse projects and needs a pom file to perform it. A typical pom file for PHP project looks like this:

<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsichemaLocation="http://maven.apache.org/POM/4.0.0">
    <modelVersion>4.0.0</modelVersion>
    <groupId>group-name</groupId>
    <artifactId>artifact-id</artifactId>
    <name>project-name</name>
    <version>1.0</version>
    <packaging>pom</packaging>
    <build>
        <directory>build-directory</directory>
        <sourceDirectory>source-directory</sourceDirectory>
        <testSourceDirectory>tests-directory</testSourceDirectory>
    </build>
</project>

All you have to do, is to replace underscored values with relevant ones. I’ll show you a complete example of it in a minute.

We need to configure maven first, so it knows how to connect to sonar mysql database. There are two locations, where maven keeps its settings.xml file:

  • The Maven install: $M2_HOME/conf/settings.xml
  • A user’s install: ${user.home}/.m2/settings.xml

Refer to your operating system documentation to find out how maven is installed by default. In Ubuntu/Debian family system global configuration file is in /etc/maven2/settings.xml, while in MacOsX it is in /usr/share/maven/conf/settings.xml.

All we have to do now, is to create custom maven profile and activate it. First locate <profiles> section in the xml file. Although there are a few profile examples inside this section already, they are probably all commented out. We will simply add our profile section to it:

<profiles>
    <!-- profile
    Existing profiles definitions (...)
    -->
    <profile>
        <id>sonar-profile</id>
        <properties>
            <sonar.jdbc.url>jdbc:mysql://localhost:3306/sonar?useUnicode=true&amp;characterEncoding=utf8</sonar.jdbc.url>
            <sonar.jdbc.driver>com.mysql.jdbc.Driver</sonar.jdbc.driver>
            <sonar.jdbc.username>sonar</sonar.jdbc.username>
            <sonar.jdbc.password>S0n4rU53r</sonar.jdbc.password>
        </properties>
    </profile>
</profiles>

Next activate the new profile in activeProfiles section. Remove the comments around this section and just add bolded section to it:

<activeProfiles>
    <activeProfile>sonar-profile</activeProfile>
</activeProfiles>

If there are any profiles activated already there, just simply delete them. They don’t exists anyway and will only cause maven to complain during analysis.

If Sonar has been installed on a separate machine and you want to analyse your project on a different machine, then you will have to adjust sonar.jdbc.url option to point it to the sonar database and at the same time grant relevant permissions to the database itself. Also you have to tell maven how it can access Sonar server by specifying sonar.host.url option in profile section:

<sonar.host.url>http://sonar.server.org/</sonar.host.url>

The last thing we have to do is to switch on a few options and make some tweaks for the PHP plugin itself. Integration with the PHP tools is pretty basic at the moment, but is enough to perform some simple analysis. So I am gonna run Sonar in so called dynamic analysis mode, run the tools manually to create all xml reports, and then run Sonar maven task to parse them and add the results to Sonar dashboard. The only exception will be PHP_CodeSniffer – I will let Sonar run the SQLi version and produce compatible report. Bear in mind in future plugin releases I expect the integration to get much better and then, if  you would like to you will be able to use Sonar to run the tools.

Let’s add the following lines to the maven settings.xml file then:

<profile>
    <id>sonar-profile</id>
    <properties>
        <sonar.jdbc.url>jdbc:mysql://localhost:3306/sonar?useUnicode=true&amp;characterEncoding=utf8</sonar.jdbc.url>
        <sonar.jdbc.driver>com.mysql.jdbc.Driver</sonar.jdbc.driver>
        <sonar.jdbc.username>sonar</sonar.jdbc.username>
        <sonar.jdbc.password>S0n4rU53r</sonar.jdbc.password>
       <sonar.language>php</sonar.language>
       <sonar.dynamicAnalysis>true</sonar.dynamicAnalysis>
       <sonar.phpUnit.analyzeOnly>true</sonar.phpUnit.analyzeOnly>
       <sonar.phpDepend.analyzeOnly>true</sonar.phpDepend.analyzeOnly>
    </properties>
</profile>

Analysing projects with Sonar

I have picked up vfsStream project as an example for analysis. Unfortunately this is the only open source project I have found so far, that requires a minimal effort to get it up and running. I have tried PHPUnit, pdepend, PHP_CodeSniffer, Zend Framework and many many more, but they either fail analysis, they are not compatible with PHPUnit 5.3 yet or they have very custom test suite runners which would need some major changes before we could actually perform analysis.

From my experience so far, Sonar often can not analyse the project because it still has problems parsing coverage report. I expect this to improve in next plugin versions though. Most problems can be solved by stopping using AllTests.php files and properly defining phpunit.xml file with filter whitelist section. I have analysed dosens of projects at work using that approach without a problem.

So let’s get vfsStream sources first:

#> svn checkout http://bovigo.googlecode.com/svn/vfs/trunk/ vfsStream

Let’s make it PHPUnit 3.5 compatible first by removing the following line from src/test/AllTests.php file:

PHPUnit_Util_Filter::addDirectoryToWhitelist(SOURCE_DIR);

Next let’s create a directory we will use to store xml reports in:

mkdir -p build/logs

and run PHPUnit to generate both junit log file and coverage clover report file:

#> phpunit --coverage-clover build/logs/phpunit.coverage.xml --log-junit build/logs/phpunit.xml src/test/AllTests.php
PHPUnit 3.5.3 by Sebastian Bergmann.

............................................................  60 / 169
............................................................ 120 / 169
.................................................

Time: 3 seconds, Memory: 13.75Mb

OK (169 tests, 759 assertions)

Writing code coverage data to XML file, this may take a moment.

vfsStream doesn’t have phpunit.xml file, but fortunately  AllTests.php works just fine.

Now let’s run PHP Depend to create pdepend report.

#> pdepend --phpunit-xml=build/logs/pdepend.xml src/main
PHP_Depend 0.9.19 by Manuel Pichler

Parsing source files:
.........                                                        9

Executing CyclomaticComplexity-Analyzer:
.....                                                          119

Executing ClassLevel-Analyzer:
.....                                                          112

Executing CodeRank-Analyzer:
                                                                10

Executing Coupling-Analyzer:
.......                                                        148

Executing Hierarchy-Analyzer:
......                                                         139

Executing Inheritance-Analyzer:
..                                                              57

Executing NPathComplexity-Analyzer:
.....                                                          119

Executing NodeCount-Analyzer:
......                                                         122

Executing NodeLoc-Analyzer:
......                                                         131

Generating pdepend log files, this may take a moment.

Time: 00:01; Memory: 19.25Mb

With all the reports in place

#> ls -ltr build/logs/
total 184
-rw-r--r--  1 smarek  staff  15565 22 Nov 10:18 pdepend.xml
-rw-r--r--  1 smarek  staff  41787 22 Nov 10:18 phpunit.xml
-rw-r--r--  1 smarek  staff  32455 22 Nov 10:18 phpunit.coverage.xml

it’s time to create pom.xml file based on the template mentioned before. Our pom.xml file will look like this:

<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsichemaLocation="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>com.googlecode.bovigo</groupId>
<artifactId>vfsStream</artifactId>
<name>vfsStream</name>
<version>1.0</version>
<packaging>pom</packaging>
<build>
    <directory>build</directory>
    <sourceDirectory>src/main</sourceDirectory>
    <testSourceDirectory>src/test</testSourceDirectory>
</build>
</project>

Let’s save the file in top level project directory and run analysis command from there:

smarek@14:~/apps/vfsStream$ mvn sonar:sonar
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'sonar'.
[INFO] Ignoring available plugin update: 2.0-beta-1 as it requires Maven version 3.0
[INFO] ------------------------------------------------------------------------
[INFO] Building vfsStream
[INFO]    task-segment: [sonar:sonar] (aggregator-style)
[INFO] ------------------------------------------------------------------------
[INFO] [sonar:sonar {execution: default-cli}]
[INFO] Sonar host: http://localhost:9000
[INFO] Sonar version: 2.1.2
[INFO] Execute: org.codehaus.sonar.runtime:sonar-core-maven-plugin:20101122103356:internal
[INFO] [sonar-core:internal {execution: default-internal}]
[INFO]  Database dialect class org.sonar.api.database.dialect.MySql
[INFO]  -------------  Analyzing vfsStream
[INFO]  Selected quality profile : Default Php Profile, language=php
[INFO]  Configure maven plugins...
[INFO]  Sensor PhpSourceImporter[getLanguage()=PHP,getClass()=class org.sonar.plugins.php.core.sensors.PhpSourceImporter]...
[INFO]  Importing files from project vfsStream
[INFO]  main
[INFO]  test
[INFO]  Sensor PhpSourceImporter[getLanguage()=PHP,getClass()=class org.sonar.plugins.php.core.sensors.PhpSourceImporter] done: 409 ms
[INFO]  Sensor AsynchronousMeasuresSensor...
[INFO]  Sensor AsynchronousMeasuresSensor done: 20 ms
[INFO]  Sensor PhpCodesnifferSensor...
[INFO]  ExecutePHPCodeSniffer with command 'sqlics --report-file=/Users/smarek/apps/vfsStream/build/logs/codesniffer.xml --report=checkstyle --level=warning --standard=GN --extensions=php,php3,php4,php5,phtml,inc /Users/smarek/apps/vfsStream/src/main'
[INFO]  PHPCodeSniffer ended with returned code '1'.
[INFO]  Analysing project with file:/Users/smarek/apps/vfsStream/build/logs/codesniffer.xml
[INFO]  Sensor PhpCodesnifferSensor done: 4233 ms
[INFO]  Sensor SurefireSensor...
[INFO]  parsing /Users/smarek/apps/vfsStream/build/surefire-reports
[INFO]  Sensor SurefireSensor done: 2 ms
[INFO]  Sensor CpdSensor...
[INFO]  Sensor CpdSensor done: 228 ms
[INFO]  Sensor PhpUnitSensor...
[INFO]  Parsing file :
[INFO]  Parsing file : {0}
[INFO]  Sensor PhpUnitSensor done: 637 ms
[INFO]  Sensor ProfileSensor...
[INFO]  Sensor ProfileSensor done: 13 ms
[INFO]  Sensor ProjectLinksSensor...
[INFO]  Sensor ProjectLinksSensor done: 6 ms
[INFO]  Sensor VersionEventsSensor...
[INFO]  Sensor VersionEventsSensor done: 9 ms
[INFO]  Sensor PHP Depend Sensor...
[INFO]  Collecting measures...
[INFO]  Saving measures...
[INFO]  Sensor PHP Depend Sensor done: 173 ms
[INFO]  Sensor Maven dependencies...
[INFO]  Sensor Maven dependencies done: 7 ms
[INFO]  Execute decorators...
[INFO]  ANALYSIS SUCCESSFUL, you can browse http://localhost:9000
[INFO]  Database optimization...
[INFO]  Database optimization done: 83 ms
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 19 seconds
[INFO] Finished at: Mon Nov 22 10:34:50 GMT 2010
[INFO] Final Memory: 25M/81M
[INFO] ------------------------------------------------------------------------

Let’s get back to the browser now and refresh the dashboard.

sonar-vfsStream
Sonar dashboard after running analysis
vfsStream-dashboard
vfsStream analysis details

Congratulations! You have just analysed your first PHP project with Sonar!

Understanding the measures

I will only briefly tell you about different sections of the dashboard this time. Feel free to explore it and remember – there is quite comprehensive documentation at http://www.sonarsource.org/ including wiki, tutorials and even some screencasts!

At the top of the dashboard you have all the results of static code analysis, including all sort of statistics about your code complexity and size.

code-complexity
Code complexity analysis

On the right side of the dashboard, Sonar reports all rules violations generated by PHP_CodeSniffer. Don’t be surprised with the results you see. Remember we didn’t configure the plugin to use any specific standard. 0.2 version of the plugin uses an included GN standard, just for illustration purposes. That will definitely improve in future plugin versions and complete integration with PHP_CodeSniffer 1.3.

rules-violations
Rules violations based on PHP_CodeSniffer report

And finally at the bottom you have got results of the test suite run:

unittest-results
Unit tests results

phpUnderControl integration

Integration with phpUnderControl is really trivial. All you have to do is to add another task to your ant build file and execute it at the end of the build!

<project default="build" basedir=".">

    <!--
    All the other targets here
    -->

    <target name="sonar">
        <exec dir="${basedir}/Source/" executable="mvn" failonerror="false" >
           <arg line="sonar:sonar" />
        </exec>
    </target>

    <target name="build" depends="clean,checkout-code,update-branches,generate-configs,php-documentor,php-codesniffer,php-depend,phpunit,sonar" />

</project>

What’s next?

Version 0.3 of the plugin is coming soon to your houses soon, and with it comes:
  • better integration with PHP_CodeSniffer 1.3 (SQLi CodeSniffer no longer required)
  • rulesets support – import/export feature
  • Copy/Paste detector support (phpcpd)
  • better code coverage analysis
  • one plugin – one jar – easier installation
It will only get better! Happy analysis!

7 Comments

  • You’re right. At the moment we’re working on 0.3 version which is gonna be compatible with Sonar 2.3. Also we’re working on a process and official roadmap that will help us develop the plugin in a way we can make it compatible with all the future Sonar releases. So stay tuned!

  • Hi, I’ve just found this how to and it helped a lot. Some remarks:

    It’s a bit outdated, new version of sonars php plugin has come out resolving some of the issues you mentioned.

    What I think a good addition to this, is how to work with PHP projects *Without* unit tests defined (most of them). I work a lot with Drupal, and they use a different test approach.

    So do you know a simple way to bypass unittests when there are none and still be able to use sonar?

    Thanks

  • Hi,

    I am trying to do sonar analysis through maven of a PHP project.
    I am using maven 3.04 version, sonar 3.3 version, Php 5.3.5 vesrion, and sonar-php-plugin 1.1(http://repository.codehaus.org/org/codehaus/sonar-plugins/php/sonar-php-plugin/1.1/sonar-php-plugin-1.1.jar)
    I have kept this jar file in sonar-3.3\extensions\plugins directory.

    When I am running mvn sonar:sonar command, I am getting below error.
    This error gets genarated after pdeped genrates report:

    [ERROR] Failed to execute goal org.codehaus.mojo:sonar-maven-plugin:2.0:sonar (d
    efault-cli) on project espritKM: Can not execute Sonar: PHPMD execution failed w
    ith returned code ‘255’. Please check the documentation of PHPMD to know more ab
    out this failure. -> [Help 1]
    org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal o
    rg.codehaus.mojo:sonar-maven-plugin:2.0:sonar (default-cli) on project espritKM:
    Can not execute Sonar

    I am using PHPMD version 1.4.1.

Leave a Reply

Your email address will not be published. Required fields are marked *