neophp/codechecker-package

Configurable static code rule checker for NeoPHP projects

Maintainers

Package info

github.com/NeoPHP-Dev/neo-codechecker-package

pkg:composer/neophp/codechecker-package

Transparency log

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v0.2.0 2026-08-08 07:19 UTC

This package is auto-updated.

Last update: 2026-08-08 07:20:21 UTC


README

A configurable static code rule checker for NeoPHP. Define rules once, in a config file, and scan an entire project with a single command — forbidden namespace usages, forbidden code patterns, or required ones, all defined declaratively rather than hard-coded into a script.

Structure

codechecker-package/
├── composer.json
├── README.md
├── src/
│   ├── NeoCodeCheckerPackage.php
│   ├── Commands/
│   │   ├── CodeCheckerScanCommand.php
│   │   └── CodeCheckerAddRuleCommand.php
│   └── Service/
│       ├── RuleLoader.php
│       └── RuleChecker.php
└── config/
    └── codechecker-rules.config.php

Installation

php bin/neo package:require neophp/codechecker-package --project=MyProject

Register it in the project's Config/app.config.php:

return [
    // ...
    'packages' => [
        \Vendor\NeoPHP\CodeCheckerPackage\NeoCodeCheckerPackage::class,
    ],
];

On first boot, config/codechecker-rules.config.php is copied to Config/Packages/CodeChecker/codechecker-rules.config.php in your project — pre-populated with a few baseline rules (no var_dump(), no dd(), no die() in controllers, entities must carry #[Entity]). Edit this file freely; it is never overwritten once it exists.

Usage

Scan the project

php bin/neo codechecker:scan --project=MyProject
Scanning MyProject…

✘ App/Controllers/ReportsController.php:34
  Rule: no-var-dump
  No var_dump() calls should remain in the codebase

1 violation(s) found.

Exits with a non-zero code if any violation is found — usable as a CI step, the same way phpstan analyse is typically wired into a pipeline.

Add a rule interactively

Instead of hand-editing the config array, add a rule step by step:

php bin/neo codechecker:add-rule --project=MyProject
Rule name: no-raw-sql-in-repositories
Description: Repositories must never build raw SQL query strings
Applies to (namespace pattern, * for all): App\Repository\*

Rule type
  [1] forbidden_use   — a specific `use X;` must NOT appear
  [2] forbidden_call  — a specific string must NOT appear
  [3] required_use    — a specific `use X;` MUST appear
  [4] required_call   — a specific string MUST appear
Type (1-4): 2

Value (class-string to require/forbid, or string pattern): ->query(
✔ Rule 'no-raw-sql-in-repositories' added to codechecker-rules.config.php

The existing rules in the file are preserved — the new rule is appended to the array.

Rule format

Each rule is an associative array with 5 keys:

[
    'name' => 'unique-rule-name',
    'description' => 'Shown in scan output when this rule is violated',
    'applies_to' => 'App\\Controllers\\*',   // namespace glob pattern, or '*' for every file
    'type' => 'forbidden_call',                // see table below
    'value' => 'var_dump(',                     // what to search for
],
Type Checks
forbidden_use A specific use X; statement must not appear in the file
forbidden_call A specific string must not appear anywhere in the file
required_use A specific use X; statement must appear in the file
required_call A specific string must appear anywhere in the file

forbidden_use/required_use and forbidden_call/required_call are checked identically under the hood — both search for value as a plain substring of the file's content. _use variants exist as a naming convention for readability (checking a use statement specifically) but technically behave the same as _call. Write the full string you're checking for either way (e.g. 'use Neo\\Core\\Database\\DatabaseManager;' for a forbidden_use rule, not just the class name).

applies_to supports a single trailing wildcard (App\Controllers\* matches any class under that namespace) or * to apply to every scanned file, regardless of namespace.

Known limitations

  • Substring matching, not real static analysis. A rule matches on plain text presence in the file — it does not parse the AST, so it cannot distinguish a real usage from, say, a match inside a comment or a string literal. This makes rules simple to write and fast to run, at the cost of occasional false positives — review scan results, don't treat them as infallible.
  • applies_to matches on namespace, not file path. A file's namespace must be resolvable (a valid PHP class with a namespace declaration) for the rule to apply — non-class files are skipped entirely.
  • The config file is rewritten from scratch by codechecker:add-rule using a custom array exporter (to keep [] short array syntax rather than PHP's default array(...) from var_export()). Any hand-written comments in codechecker-rules.config.php will be lost the next time you run this command — edit the file directly instead if you want to keep comments, and only use add-rule for quick, comment-free additions.

License

MIT