PHPackages                             lvandi/php-crap-checker - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [CLI &amp; Console](/categories/cli)
4. /
5. lvandi/php-crap-checker

ActiveLibrary[CLI &amp; Console](/categories/cli)

lvandi/php-crap-checker
=======================

A CLI tool to fail CI when PHP CRAP score exceeds a configured threshold.

v1.0.0(1mo ago)11↓100%[1 issues](https://github.com/LucianoVandi/php-crap-checker/issues)[7 PRs](https://github.com/LucianoVandi/php-crap-checker/pulls)MITPHPPHP &gt;=8.3CI passing

Since Apr 26Pushed 2w agoCompare

[ Source](https://github.com/LucianoVandi/php-crap-checker)[ Packagist](https://packagist.org/packages/lvandi/php-crap-checker)[ RSS](/packages/lvandi-php-crap-checker/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (9)Versions (9)Used By (0)

php-crap-checker
================

[](#php-crap-checker)

[![CI](https://github.com/LucianoVandi/php-crap-checker/actions/workflows/ci.yml/badge.svg)](https://github.com/LucianoVandi/php-crap-checker/actions/workflows/ci.yml)[![Latest Stable Version](https://camo.githubusercontent.com/8617eeea28c0a4cea816a50b24a9688074801f0eae3d0d0012f383f0c4222658/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6c76616e64692f7068702d637261702d636865636b6572)](https://packagist.org/packages/lvandi/php-crap-checker)[![PHP Version](https://camo.githubusercontent.com/14f99a10bd27e2ac3cf03627a9fe6da93482fe3e221aef0d639f1f4b6c2ca36b/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f6c76616e64692f7068702d637261702d636865636b6572)](https://packagist.org/packages/lvandi/php-crap-checker)[![codecov](https://camo.githubusercontent.com/871a487eab2cddb931b2347bc866e9ead9be251034ffce183777b181225e14b0/68747470733a2f2f636f6465636f762e696f2f67682f4c756369616e6f56616e64692f7068702d637261702d636865636b65722f6272616e63682f6d61696e2f67726170682f62616467652e737667)](https://codecov.io/gh/LucianoVandi/php-crap-checker)[![License: MIT](https://camo.githubusercontent.com/784362b26e4b3546254f1893e778ba64616e362bd6ac791991d2c9e880a3a64e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d677265656e2e737667)](LICENSE)

A CI quality gate for method-level change risk in PHP projects.

Why this tool exists
--------------------

[](#why-this-tool-exists)

Complex code with low test coverage is risky to change. The CRAP score captures this pattern in a single number. `crap-check` turns that signal into a CI gate: if any method exceeds the threshold, the build fails.

This matters in any workflow where code can be generated, refactored, or expanded quickly — including AI-assisted development — because static analysis and basic tests can pass while change risk quietly accumulates at method level.

What is the CRAP score?
-----------------------

[](#what-is-the-crap-score)

CRAP (Change Risk Anti-Patterns) is a metric that combines cyclomatic complexity and test coverage. A method scores higher when it is both complex and poorly tested. The formula is:

```
CRAP(m) = comp(m)² × (1 - cov(m)/100)³ + comp(m)

```

A low CRAP score means the method is either simple, well-tested, or both. A high score is a signal worth investigating — not necessarily a hard blocker, but a starting point for review.

What this package does
----------------------

[](#what-this-package-does)

- Reads a Crap4J XML report generated by PHPUnit
- Compares each method's CRAP score against a configurable threshold
- Prints the violations sorted by severity
- Exits with a non-zero code so CI fails when the threshold is exceeded
- Diagnoses environment and PHPUnit configuration (`doctor` command)

What this package does NOT do
-----------------------------

[](#what-this-package-does-not-do)

- Generate code coverage (that is PHPUnit's job, with PCOV or Xdebug)
- Replace tools like Codecov for overall coverage tracking
- Apply per-method or per-path ignores (planned for a future release)
- Read Clover or other coverage formats

Installation
------------

[](#installation)

```
composer require --dev lvandi/php-crap-checker
```

Usage
-----

[](#usage)

### Basic usage

[](#basic-usage)

```
# 1. Generate the Crap4J report with PHPUnit
php -d pcov.enabled=1 vendor/bin/phpunit --coverage-crap4j build/crap4j.xml

# 2. Check the threshold
vendor/bin/crap-check check build/crap4j.xml --threshold=30
```

The `report` argument defaults to `build/crap4j.xml` and `--threshold` defaults to `30`.

### Options

[](#options)

OptionDefaultDescription`report``build/crap4j.xml`Path to the Crap4J XML report`--threshold``30`Maximum allowed CRAP score (exclusive)`--max-violations`*(none)*Maximum number of violations before CI fails`--max-age`*(none)*Maximum report age; accepts minutes (`60`), or duration strings (`30m`, `2h`)`--format``text`Output format (`text`, `json`)Usage in GitHub Actions
-----------------------

[](#usage-in-github-actions)

```
- name: Run PHPUnit with Crap4J coverage
  run: php -d pcov.enabled=1 vendor/bin/phpunit --coverage-crap4j build/crap4j.xml

- name: Check CRAP threshold
  run: vendor/bin/crap-check check build/crap4j.xml --threshold=30
```

Full example with PHP matrix:

```
jobs:
  ci:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        php: ["8.3", "8.4"]
    steps:
      - uses: actions/checkout@v4

      - uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ matrix.php }}
          extensions: pcov
          coverage: pcov

      - run: composer install --no-interaction --prefer-dist

      - run: php -d pcov.enabled=1 vendor/bin/phpunit --coverage-crap4j build/crap4j.xml

      - run: vendor/bin/crap-check check build/crap4j.xml --threshold=30
```

Usage with Codecov
------------------

[](#usage-with-codecov)

`php-crap-checker` and Codecov serve different purposes and work well together:

```
- name: Run PHPUnit with coverage
  run: |
    php -d pcov.enabled=1 vendor/bin/phpunit \
      --coverage-clover build/clover.xml \
      --coverage-crap4j build/crap4j.xml

- name: Check CRAP threshold
  run: vendor/bin/crap-check check build/crap4j.xml --threshold=30

- name: Upload coverage to Codecov
  uses: codecov/codecov-action@v5
  with:
    files: build/clover.xml
    fail_ci_if_error: true
```

Codecov tracks overall and patch coverage. `crap-check` enforces a per-method CRAP threshold. They complement each other.

Exit codes
----------

[](#exit-codes)

CodeMeaning`0`OK — no violations`1`CRAP threshold exceeded`2`Invalid input (e.g. non-numeric threshold)`3`Report file not found or not readable`4`Invalid XML in report`5`Report valid but contains no methodsOutput examples
---------------

[](#output-examples)

### No violations

[](#no-violations)

```
CRAP threshold OK. Max allowed: 30
Analyzed methods: 128
Violations: 0

```

### Violations found

[](#violations-found)

```
CRAP threshold exceeded. Max allowed: 30

3 violations found:

1) App\Legacy\ReportGenerator::generate()
   File: src/Legacy/ReportGenerator.php:10
   CRAP: 72.00
   Complexity: 18
   Coverage: 0.00%

2) App\Service\OrderImporter::import()
   File: src/Service/OrderImporter.php:42
   CRAP: 46.23
   Complexity: 12
   Coverage: 41.60%

3) App\Service\ShippingCalculator::calculate()
   File: src/Service/ShippingCalculator.php:88
   CRAP: 35.10
   Complexity: 9
   Coverage: 22.00%

```

### Report not found

[](#report-not-found)

```
Report not found: build/crap4j.xml

Generate it with:
php -d pcov.enabled=1 vendor/bin/phpunit --coverage-crap4j build/crap4j.xml

```

A note on PCOV and Xdebug
-------------------------

[](#a-note-on-pcov-and-xdebug)

**PCOV and Xdebug are not required by this package.** They are required by PHPUnit to *generate* the Crap4J report. Once the report exists, `crap-check` reads the XML and needs no coverage driver.

In CI, install PCOV (faster) or Xdebug only in the step that generates coverage:

```
- uses: shivammathur/setup-php@v2
  with:
    php-version: "8.3"
    extensions: pcov
    coverage: pcov
```

If you already have a report from a previous step or artifact, you can run `crap-check` without any coverage extension.

Interpreting a high CRAP score
------------------------------

[](#interpreting-a-high-crap-score)

A high CRAP score on a method is a signal, not a verdict. Before raising the threshold or suppressing the check, consider:

- **Add tests**: if the method is complex but untested, coverage will bring the score down
- **Reduce complexity**: extract helper methods or simplify branching logic
- **Accept and document**: some methods are inherently complex and well-understood — a future baseline feature will allow explicit exceptions

Mechanically writing tests just to lower the number defeats the purpose. Use the score to guide meaningful improvement.

Adopting on a legacy project
----------------------------

[](#adopting-on-a-legacy-project)

If your codebase already has many violations, a zero-tolerance threshold from day one is counterproductive. See **[docs/ADOPTING.md](docs/ADOPTING.md)** for gradual adoption strategies: start permissive and tighten over time, cap violations with `--max-violations`, and how to talk to your team about the metric.

Planned
-------

[](#planned)

Future releases may add:

- baseline support (snapshot a list of known violations, block only new ones)
- `--fail-on=new` and `--fail-on=worsened`
- ignore rules for paths and specific methods
- GitHub Actions annotations

Requirements
------------

[](#requirements)

- PHP `>=8.3`
- `ext-simplexml`
- `symfony/console` `^7.0`

Development
-----------

[](#development)

PHP runs inside Docker. Build the image once (uses your host UID/GID to avoid file permission issues):

```
make build
make install
```

Common commands:

```
make test        # PHPUnit
make qa          # PHPUnit + PHPStan (CI gate)
make stan        # PHPStan level 9
make cs-fix      # PHP CS Fixer
make infection   # Mutation testing
```

Contributing
------------

[](#contributing)

Contributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines on opening issues and submitting pull requests.

To report a security vulnerability, follow the process described in [SECURITY.md](SECURITY.md).

This project is released under the [MIT License](LICENSE).

###  Health Score

37

—

LowBetter than 81% of packages

Maintenance74

Regular maintenance activity

Popularity4

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity54

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 95.5% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

44d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/df6338d951a78ed18c9cf91a501188887444dc9b6adbba1bfe6a5a0d26d52645?d=identicon)[lvandi](/maintainers/lvandi)

---

Top Contributors

[![LucianoVandi](https://avatars.githubusercontent.com/u/1780622?v=4)](https://github.com/LucianoVandi "LucianoVandi (21 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (1 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan, Rector

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/lvandi-php-crap-checker/health.svg)

```
[![Health](https://phpackages.com/badges/lvandi-php-crap-checker/health.svg)](https://phpackages.com/packages/lvandi-php-crap-checker)
```

###  Alternatives

[illuminate/console

The Illuminate Console package.

13045.3M6.1k](/packages/illuminate-console)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
