Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions analysis-bootstrap.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php
/**
* Shared bootstrap for static analysis (PHPStan `bootstrapFiles`, Psalm `autoloader`).
*
* Two dependencies we analyse against declare no Composer `autoload` section,
* so their symbols are invisible to the analysers unless loaded explicitly:
*
* - nextcloud/ocp ships the OCP/NCU API as analysis stubs only.
* - squizlabs/php_codesniffer ships its own autoloader, and defines its
* custom `T_*` token constants at runtime via `define()` inside
* src/Util/Tokens.php. Touching the Tokens class forces that file to load
* so the constants exist during analysis.
*
* Without this file PHPStan reports 52 errors and Psalm 19 — all of them
* "unknown class / undefined constant" noise from the missing symbol sources,
* not defects. Supplying the symbols is the fix; suppressing them would hide
* real findings behind the same rule names.
*
* @license EUPL-1.2
* @copyright Conduction b.v.
*/

$autoloader = require __DIR__ . '/vendor/autoload.php';
$autoloader->addPsr4('OCP\\', __DIR__ . '/vendor/nextcloud/ocp/OCP/');
$autoloader->addPsr4('NCU\\', __DIR__ . '/vendor/nextcloud/ocp/NCU/');

require_once __DIR__ . '/vendor/squizlabs/php_codesniffer/autoload.php';
class_exists('PHP_CodeSniffer\Util\Tokens');
18 changes: 9 additions & 9 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@
"cs:fix": "./vendor/bin/phpcbf --standard=phpcs.xml",
"phpcs": "./vendor/bin/phpcs --standard=phpcs.xml",
"phpcs:fix": "./vendor/bin/phpcbf --standard=phpcs.xml",
"phpmd": "phpmd lib text phpmd.xml || echo 'PHPMD not installed, skipping...'",
"phpmetrics": "./vendor/bin/phpmetrics --report-html=phpmetrics lib/",
"phpmetrics:violations": "./vendor/bin/phpmetrics --violations-xml=phpmetrics/violations.xml lib/",
"psalm": "./vendor/bin/psalm --threads=1 --no-cache || echo 'Psalm not installed, skipping...'",
"phpstan": "./vendor/bin/phpstan analyse --memory-limit=1G || echo 'PHPStan not installed, skipping...'",
"test:unit": "./vendor/bin/phpunit --colors=always || echo 'Tests require Nextcloud environment, skipping...'",
"test:all": "./vendor/bin/phpunit --colors=always || echo 'Tests require Nextcloud environment, skipping...'",
"phpmd": "./vendor/bin/phpmd phpcs-custom-sniffs text phpmd.xml",
"phpmetrics": "./vendor/bin/phpmetrics --report-html=phpmetrics phpcs-custom-sniffs",
"phpmetrics:violations": "./vendor/bin/phpmetrics --violations-xml=phpmetrics/violations.xml phpcs-custom-sniffs",
"psalm": "./vendor/bin/psalm --threads=1 --no-cache",
"phpstan": "./vendor/bin/phpstan analyse --memory-limit=1G",
"test:unit": "./vendor/bin/phpunit --colors=always || echo 'No PHP test suite in this repo (no phpunit.xml, no tests/) - skipping...'",
"test:all": "./vendor/bin/phpunit --colors=always || echo 'No PHP test suite in this repo (no phpunit.xml, no tests/) - skipping...'",
"check": "E=0; for CMD in lint phpcs psalm test:unit; do echo; echo \"=== $CMD ===\"; composer $CMD || E=1; done; echo; if [ $E -eq 0 ]; then echo \"ALL CHECKS PASSED\"; else echo \"SOME CHECKS FAILED (see above)\"; fi; exit $E",
"check:full": "E=0; for CMD in lint phpcs psalm phpstan test:all; do echo; echo \"=== $CMD ===\"; composer $CMD || E=1; done; echo; if [ $E -eq 0 ]; then echo \"ALL CHECKS PASSED\"; else echo \"SOME CHECKS FAILED (see above)\"; fi; exit $E",
"check:strict": "E=0; for CMD in lint phpcs phpmd psalm phpstan test:all; do echo; echo \"=== $CMD ===\"; composer $CMD || E=1; done; echo; if [ $E -eq 0 ]; then echo \"ALL CHECKS PASSED\"; else echo \"SOME CHECKS FAILED (see above)\"; fi; exit $E",
Expand All @@ -35,8 +35,8 @@
],
"test:coverage": "./vendor/bin/phpunit --coverage-html=coverage/html --coverage-clover=coverage/clover.xml --colors=always",
"coverage:check": "php -r \"\\$xml = simplexml_load_file('coverage/clover.xml'); \\$metrics = \\$xml->project->metrics; \\$statements = (int)\\$metrics['statements']; \\$covered = (int)\\$metrics['coveredstatements']; \\$percentage = \\$statements > 0 ? round((\\$covered / \\$statements) * 100, 2) : 0; echo 'Coverage: ' . \\$percentage . '%' . PHP_EOL; exit(\\$percentage < 75 ? 1 : 0);\"",
"quality:phpcs-score": "./vendor/bin/phpcs --standard=phpcs.xml --report=json lib/ | php -r \"\\$json = json_decode(file_get_contents('php://stdin'), true); \\$errors = \\$json['totals']['errors'] ?? 0; \\$warnings = \\$json['totals']['warnings'] ?? 0; \\$score = 1000 - \\$errors - (\\$warnings / 2); echo 'PHPCS Score: ' . \\$score . ' (Errors: ' . \\$errors . ', Warnings: ' . \\$warnings . ')' . PHP_EOL;\"",
"quality:phpmd-score": "phpmd lib/ json phpmd.xml | php -r \"\\$input = file_get_contents('php://stdin'); \\$json = json_decode(\\$input, true); \\$violations = count(\\$json['files'] ?? []); \\$score = 1000 - (\\$violations * 10); echo 'PHPMD Score: ' . \\$score . ' (Violations: ' . \\$violations . ')' . PHP_EOL;\" || echo 'PHPMD not available'",
"quality:phpcs-score": "./vendor/bin/phpcs --standard=phpcs.xml --report=json phpcs-custom-sniffs | php -r \"\\$json = json_decode(file_get_contents('php://stdin'), true); \\$errors = \\$json['totals']['errors'] ?? 0; \\$warnings = \\$json['totals']['warnings'] ?? 0; \\$score = 1000 - \\$errors - (\\$warnings / 2); echo 'PHPCS Score: ' . \\$score . ' (Errors: ' . \\$errors . ', Warnings: ' . \\$warnings . ')' . PHP_EOL;\"",
"quality:phpmd-score": "./vendor/bin/phpmd phpcs-custom-sniffs json phpmd.xml | php -r \"\\$input = file_get_contents('php://stdin'); \\$json = json_decode(\\$input, true); \\$violations = count(\\$json['files'] ?? []); \\$score = 1000 - (\\$violations * 10); echo 'PHPMD Score: ' . \\$score . ' (Violations: ' . \\$violations . ')' . PHP_EOL;\" || echo 'PHPMD not available'",
"quality:psalm-score": "./vendor/bin/psalm --output-format=json --no-cache | php -r \"\\$input = file_get_contents('php://stdin'); \\$json = json_decode(\\$input, true); \\$errors = count(\\$json ?? []); \\$score = 1000 - (\\$errors * 5); echo 'Psalm Score: ' . \\$score . ' (Errors: ' . \\$errors . ')' . PHP_EOL;\" || echo 'Psalm not available'",
"quality:phpstan-score": "./vendor/bin/phpstan analyse --memory-limit=1G --error-format=json --no-progress | php -r \"\\$input = file_get_contents('php://stdin'); \\$json = json_decode(\\$input, true); \\$errors = \\$json['totals']['file_errors'] ?? 0; \\$score = 1000 - (\\$errors * 5); echo 'PHPStan Score: ' . \\$score . ' (Errors: ' . \\$errors . ')' . PHP_EOL;\" || echo 'PHPStan not available'",
"quality:score": [
Expand Down
Loading
Loading