Analyze PHP code with one command.
## Requirements
- PHP >= 5.4.0
xsl
extension for HTML reports
Every analyzer has different arguments and options in different formats (no surprise in PHP world :). If you ever tried to get ignoring directories to work then you know what I mean. On the other hand CLI tools are cool because you can analyze any directory or file. Unfortunately Jenkins, Travis, Scrutiziner needs special configuration file. What if you want to analyze every bundle in your Symfony app? Will you create e.g. Jenkins project/task for each bundle?
- I want to analyze selected directory without complex configuration and creating extra files/tasks
- I don't care about format of ignored directories in phploc, phpmd, ...
- I don't want to update all projects when QA tool is updated or if I've found cool tool like PHPMetrics
- I don't want to analyze XML files → tool should be able to build html reports
- I want fast execution time → tools should run in parallel (thanks Robo)
Available tools
Tool | Description |
---|---|
phploc | Measure the size of a PHP project |
phpcpd | Copy/Paste Detector (CPD) for PHP code |
phpcs | Detect violations of a coding standard |
pdepend | PHP adaptation of JDepend |
phpmd | Scan PHP project for messy code |
phpmetrics | Static analysis tool for PHP |
Newly added tools aren't preinstalled. You have to install relevant composer packages if you want to use.
Tool | Supported since | Description |
---|---|---|
parallel-lint | >= 1.9 |
Check syntax of PHP files |
Tip: use bin/suggested-tools.sh install
for installing the tools.
### Without composer
# install phpqa
git clone https://github.com/EdgedesignCZ/phpqa.git
composer install --no-dev
# make phpqa globally accessible
## you can symlink binary
sudo ln -s /path-to-phpqa-repository/phpqa /usr/bin/phpqa
## or add this directory to your PATH in your ~/.bash_profile (or ~/.bashrc)
export PATH=~/path-to-phpqa-repository-from-pwd:$PATH
### Composer
composer global require edgedesign/phpqa --update-no-dev
# Make sure you have ~/.composer/vendor/bin/ in your PATH.
Of course you can add dependency to require-dev
section in your composer.json
.
But I wouldn't recommend it. In my experience one QA tool which analyzes
N projects is better than N projects with N analyzers. It's up to you
how many repositories you want to update when new version is released.
Do you have problems with dependencies
(symfony components, phpcpd, ...)?
Check if you can install phpqa globally.
Or install dev-master versions of sebastian/phpcpd
:
{
"require-dev": {
"edgedesign/phpqa": ">=1.7",
"sebastian/phpcpd": "dev-master"
}
}
### Docker
docker run --rm -u $UID -v $PWD:/app eko3alpha/docker-phpqa --report --ignoreDirs vendor,build,migrations,test
For full documentation please visit eko3alpha/docker-phpqa.
Command | Description |
---|---|
phpqa --help |
Show help - available options, tools, default values, ... |
phpqa --analyzedDirs ./ --buildDir ./build |
Analyze current directory and save output to build directory |
phpqa --analyzedDirs src,tests |
Analyze source and test directory (phpmetrics analyzes only src ) |
phpqa --analyzedDir ./ |
Deprecated in v1.8 in favor of --analyzedDirs |
phpqa --ignoredDirs build,vendor |
Ignore directories |
phpqa --ignoredFiles RoboFile.php |
Ignore files |
phpqa --tools phploc,phpcs |
Run only selected tools |
phpqa --tools phpmd:1,phpcs:0,phpcpd:0 |
Check number of errors and exit code. New in v1.6 |
phpqa --verbose |
Show output from executed tools |
phpqa --quiet |
Show no output at all |
phpqa --output cli |
CLI output instead of creating files in --buildDir |
phpqa --execution no-parallel |
Don't use parallelism if --execution != parallel |
phpqa --config ./my-config |
Use custom configuration |
phpqa --report |
Build html reports |
phpqa tools |
Show versions of available tools |
Tool | --output file (default) - generated files |
--output cli |
---|---|---|
phploc | phploc.xml | ✓ |
phpcpd | phpcpd.xml | ✓ |
phpcs | checkstyle.xml | full report |
pdepend | pdepend-jdepend.xml, pdepend-summary.xml, pdepend-dependencies.xml, pdepend-jdepend.svg, pdepend-pyramid.svg | ✗ |
phpmd | phpmd.xml | ✓ |
phpmetrics | phpmetrics.html, phpmetrics.xml | ✓ |
parallel-lint | parallel-lint.html | ✓ |
phpqa
can return non-zero exit code since version 1.6. It's optional feature that is by default turned off.
You have to define number of allowed errors for phpcpd, phpcs, phpmd in --tools
.
mode | Supported version |
---|---|
--output file |
>= 1.6 |
--output cli |
>= 1.9 |
Let's say your Travis CI or Circle CI build should fail when new error is introduced. Define number of allowed errors for each tools and watch the build:
phpqa --report --tools phpcs:0,phpmd:0,phpcpd:0,parallel-lint:0,phpmetrics,phploc,pdepend
File mode
CLI mode
Tip: use echo $?
for displaying exit code.
Override tools' settings with .phpqa.yml
:
Tool | Settings | Default Value | Your value |
---|---|---|---|
phpcs | Coding standard | PSR2 | Name of existing standard (PEAR , PHPCS , PSR1 , PSR2 , Squiz , Zend ), or path to your coding standard |
phpmd | Ruleset | Edgedesign's standard | Path to ruleset |
phpcpd | Minimum number of lines/tokens for copy-paste detection | 5 lines, 70 tokens |
.phpqa.yml
is automatically detected in current working directory, but you can specify
directory via option:
# use .phpqa.yml from defined directory
phpqa --config path-to-directory-with-config
You don't have to specify full configuration. Missing or empty values are replaced
with default values from our .phpqa.yml
. Example of minimal config
that defines only standard for CodeSniffer:
phpcs:
standard: Zend
Tip: use PHP Coding Standard Generator for generating phpcs/phpmd standards.
If you don't have Jenkins or other CI server, then you can use HTML reports.
HTML files are built when you add option --report
. Take a look at
report from phpqa.
# build html reports
phpqa --report
Define custom templates if you don't like default templates.
You have to define path to xsl
files in your .phpqa.yml
:
# use different template for PHPMD, use default for other tools
report:
phpmd: my-templates/phpmd.xsl
Be aware that all paths are relative to .phpqa.yml
. Don't copy-paste section report
if you don't have custom templates!
### Requirements
xsl
extension
must be installed and enabled for exporting HTML reports.
Otherwise you'll get error PHP Fatal error: Class 'XSLTProcessor' not found
.
# install xsl extension in Ubuntu
sudo apt-get update
sudo apt-get install php5-xsl
sudo service apache2 restart
We use Jenkins-CI in Edgedesign. Below you can find examples of
Phing, Robo and bash
tasks.
### Project with one directory
Typically in Symfony project you have project with src
directory with all the code and tests. So you don't need ignore vendors, web directory etc.
Phing - build.xml
<target name="ci-phpqa">
<exec executable="phpqa" passthru="true">
<arg value="--analyzedDirs=./src" />
<arg value="--buildDir=./build/logs" />
<arg value="--report" />
</exec>
</target>
Robo - RoboFile.php
public function ciPhpqa()
{
$this->taskExec('phpqa')
->option('analyzedDirs', './src')
->option('buildDir', './build/logs')
->option('report')
->run();
}
### Project with multiple directories (src, tests, ...)
When you analyze root directory of your project don't forget to ignore vendors and other non-code directories. Otherwise the analysis could take a very long time.
Since version 1.8 phpqa supports analyzing multiple directories. Except phpmetrics that analyzes only first directory. Analyze root directory and ignore other directories if you rely on phpmetrics report.
Phing - build.xml
<target name="ci-phpqa">
<exec executable="phpqa" passthru="true">
<arg value="--analyzedDirs=./" />
<arg value="--buildDir=./build/logs" />
<arg value="--ignoredDirs=app,bin,build,vendor,web" />
<arg value="--ignoredFiles= " />
<arg value="--verbose" />
<arg value="--report" />
</exec>
</target>
Robo - RoboFile.php
public function ciPhpqa()
{
$this->taskExec('phpqa')
->option('verbose')
->option('report')
->option('analyzedDirs', './')
->option('buildDir', './build')
->option('ignoredDirs', 'build,bin,vendor')
->option('ignoredFiles', 'RoboFile.php,error-handling.php')
->run();
}
Bash
phpqa --verbose --report --analyzedDirs ./ --buildDir ./var/CI --ignoredDirs=bin,log,temp,var,vendor,www
machine:
php:
version: 7.0.4
dependencies:
cache_directories:
- ~/.composer/cache
post:
- 'git clone https://github.com/EdgedesignCZ/phpqa.git ./qa && cd qa && composer install --no-dev'
test:
override:
- vendor/bin/phpunit --testdox-html ./var/tests/testdox.html --testdox-text ./var/tests/testdox.txt --log-junit $CIRCLE_TEST_REPORTS/phpunit/junit.xml
- qa/phpqa --report --verbose --buildDir var/QA --ignoredDirs vendor --tools=phpcs:0,phpmd:0,phpcpd:0,phploc,pdepend,phpmetrics
post:
- cp -r ./var/QA $CIRCLE_ARTIFACTS
- cp -r ./var/tests $CIRCLE_ARTIFACTS
Contributions from others would be very much appreciated! Send pull request/ issue. Thanks!
Copyright (c) 2015, 2016 Edgedesign.cz. MIT Licensed, see LICENSE for details.