edgedesign / phpqa
Analyze PHP code with one command.
Installs: 862 918
Dependents: 31
Suggesters: 0
Security: 0
Stars: 566
Watchers: 20
Forks: 57
Open Issues: 5
Language:XSLT
Requires
- php: >=5.4
- ext-xsl: *
- consolidation/robo: ~0.5|>=1
- pdepend/pdepend: *
- phploc/phploc: *
- phpmd/phpmd: *
- phpmetrics/phpmetrics: *
- sebastian/phpcpd: *
- squizlabs/php_codesniffer: *
- symfony/dependency-injection: >=2.8.50
- symfony/filesystem: >=2.8
- symfony/finder: >=2.8
- symfony/process: >=2.8
- symfony/yaml: >=2.8
- twig/twig: ~1.38|~2.7|~3
Requires (Dev)
- hamcrest/hamcrest-php: >=2.0.1
- phpunit/phpunit: >=4.8.28
Suggests
- enlightn/security-checker: Check composer.lock for known security issues
- friendsofphp/php-cs-fixer: A tool to automatically fix PHP coding standards issues
- php-parallel-lint/php-console-highlighter: Colored output in parallel-lint
- php-parallel-lint/php-parallel-lint: Check PHP syntax
- phpstan/phpstan: PHP Static Analysis Tool - discover bugs in your code without running it!
- phpunit/phpunit: The PHP Unit Testing framework
- qossmic/deptrac-shim: Enforce rules for dependencies between software layers
- vimeo/psalm: A static analysis tool for finding errors in PHP applications
- dev-master
- v1.26.2
- v1.26.1
- v1.26.0
- v1.25.0
- v1.24.0
- v1.23.3
- v1.23.2
- v1.23.1
- v1.23.0
- v1.22.1
- v1.22.0
- v1.21.1
- v1.21.0
- v1.20.0
- v1.19.0
- v1.18.0
- v1.17.0
- v1.16.0
- v1.15.0
- v1.14.0
- v1.13.0
- v1.12.1
- v1.12.0
- v1.11.0
- v1.10.0
- v1.9.1
- v1.9.0
- v1.8.0
- v1.7.3
- v1.7.2
- v1.7.1
- v1.7.0
- v1.6.0
- v1.5.1
- v1.5.0
- v1.4.0
- v1.3.0
- v1.2.1
- v1.2.0
- v1.1.0
- v1.0.6
- v1.0.5
- v1.0.4
- v1.0.3
- v1.0.2
- v1.0.1
- v1.0.0
This package is auto-updated.
Last update: 2024-12-08 10:16:13 UTC
README
Analyze PHP code with one command.
Requirements
- PHP >= 5.4.0
xsl
extension for HTML reports
Why?
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
Suggested tools
Newly added tools aren't preinstalled. You have to install relevant composer packages if you want to use them.
Tip: use bin/suggested-tools.sh install
for installing the tools.
Install
Clone + composer
# install phpqa git clone https://github.com/EdgedesignCZ/phpqa.git && cd phpqa && 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
# global installation composer global require edgedesign/phpqa --update-no-dev # Make sure you have ~/.composer/vendor/bin/ in your PATH. # local installation composer require edgedesign/phpqa --dev
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.
Symfony3 components
Symfony3 is supported since version 1.7.
Install at least version ~3.0
of sebastian/phpcpd
, otherwise you'll get error The helper "progress" is not defined.
{ "require-dev": { "edgedesign/phpqa": ">=1.7", "sebastian/phpcpd": "~3.0" } }
Fake global installation in local project
Do you have problems with dependencies and you can't install phpqa globally? Install phpqa in subdirectory.
#!/bin/sh if [ ! -f qa/phpqa ]; then echo "installing phpqa" (git clone https://github.com/EdgedesignCZ/phpqa.git ./qa && cd qa && composer install --no-dev) fi qa/phpqa
Docker
Official docker image repository is https://github.com/EdgedesignCZ/phpqa/pkgs/container/phpqa. Images can be used at Gitlab CI.
docker run --rm -it ghcr.io/edgedesigncz/phpqa:v1.26.2-php7.2 phpqa tools
# using a tool without phpqa
docker run --rm -it ghcr.io/edgedesigncz/phpqa:v1.26.2-php7.2 phploc -v
Beware that images as lean as possible. That can be a problem for running PHPUnit tests. In that case, you might need different PHP version, miss PHP extensions for database etc. You can install phpqa in another php image Or build custom docker image.
docker run --rm -it ghcr.io/edgedesigncz/phpqa:v1.26.2-php7.2 sh -c "php --version && composer --version && composer outdated --direct --all && phpqa tools" docker run --rm -it ghcr.io/edgedesigncz/phpqa:v1.26.2-php8.1 sh -c "php --version && composer --version && composer outdated --direct --all && phpqa tools"
There are also available images eko3alpha/docker-phpqa and sparkfabrik/docker-phpqa.
phpqa
is used as an entrypoint (I haven't been able to use these images at Gitlab CI + Windows probably needs different environment variable).
docker run --rm -u $UID -v $PWD:/app eko3alpha/docker-phpqa --report --ignoredDirs vendor,build,migrations,test
Analyze
Tip: CLI options can be defined in .phpqa.yml
Output modes
Exit code
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
.
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,phpstan:0,phpmetrics,phploc,pdepend
Number of allowed errors can be also defined in .phpqa.yml.
phpqa: # can be overriden by CLI: phpqa --tools phpcs:1 tools: - phpcs:0
File mode
Tip: override phpcs.ignoreWarnings
if you want to count just errors without phpcs warnings.
CLI mode
Tip: use echo $?
for displaying exit code.
Advanced configuration - .phpqa.yml
Provide CLI options from .phpqa.yml
:
Files
.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.
You can specify multiple configurations directory (separated by ,
).
They are loaded in the order they are defined.
This can be useful if you have a common configuration file that you want to use across multiple project but you still want to have per project configuration.
Also, path inside configuration file are relative to where the configuration file is,
so if you have a package that bundle a custom tool, the .phpqa.yml
in the package can refers files within it.
phpqa --config ~/phpqa/,my-config/,$(pwd)
Custom binary
Every tool can define custom binary. Use phar or global tool, if you have troubles with dependencies, e.g.:
- can't install something because of symfony components or php version
- phpstan does not work, if phpmetrics v1 is installed in composer (
Hoa main file (Core.php) must be included once.
) -> use phar for phpmetrics
Generally, composer installation is preferred because of detecting version. Phar works too, but it might be tricky. If a tool has composer package with phar (e.g. vimeo/phar), use it instead of custom binary:
psalm: binary: /usr/local/bin/psalm.phar
Possibilities are infinite. You can define new tool
and run it. For example I like exploring codebase
in phpmetrics v1 and composer info in v2.
Install phpmetrics v2 in composer and use phar for v1 to avoid phpstan conflicts:
$ cat tests/.ci/.phpqa.yml phpmetricsV1: binary: /usr/local/bin/phpmetrics.phar tool: phpmetricsV1: Edge\QA\Tools\Analyzer\PhpMetrics $ phpqa --config tests/.ci/ --tools phpmetricsV1,phpmetrics
Override tools' settings
HTML reports
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
Custom templates
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
Continuous integration
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
Circle.ci - artifacts + global installation
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
Gitlab.ci - docker installation + composer cache + artifacts
stages: - test test: stage: test image: ghcr.io/edgedesigncz/phpqa:v1.26.2-php7.2 variables: BACKEND_QA: "*/backend/var/QA" BACKEND_CACHE: $CI_PROJECT_DIR/.composercache cache: paths: - $BACKEND_CACHE script: - 'export COMPOSER_CACHE_DIR=$BACKEND_CACHE' - 'composer install --ignore-platform-reqs --no-progress --no-suggest' - 'phpqa --report --tools phpcs:0,phpunit:0 --buildDir var/QA --analyzedDirs ./ --ignoredDirs var,vendor' artifacts: when: always paths: - $BACKEND_QA
Github actions - docker installation + composer cache + artifacts
name: QA on: [push] jobs: qa: container: ghcr.io/edgedesigncz/phpqa:v1.26.2-php8.1 runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 # composer is not necessary, if you are not running phpunit/psalm/phpstan - name: Cache composer uses: actions/cache@v2 with: path: | ~/.composer/cache vendor key: php-composer-${{ hashFiles('**/composer.lock') }} restore-keys: "php-composer-74" - name: Install dependencies run: | composer install --no-interaction --no-progress --ignore-platform-reqs; - name: phpqa run: phpqa --report --tools phpunit:0,phpcs:0,phpmd:0,psalm:0,phpstan:0 --buildDir build --analyzedDirs ./ --ignoredDirs build,vendor - name: Upload QA files uses: actions/upload-artifact@v2 with: name: phpqa path: build
Contributing
Contributions from others would be very much appreciated! Send pull request/issue. Thanks!
License
Copyright (c) 2015 - present Edgedesign.cz. MIT Licensed, see LICENSE for details.