Skip to content

Commit

Permalink
RFC: Add basic PHPStan validation for split packages. (cakephp#17412)
Browse files Browse the repository at this point in the history
* Add basic PHPStan validation for split packages.

* Enable scripts.

* Add gitattributes
  • Loading branch information
dereuromark authored Nov 23, 2023
1 parent c6f1e97 commit b4814c6
Show file tree
Hide file tree
Showing 9 changed files with 169 additions and 6 deletions.
5 changes: 5 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,8 @@ phpstan-baseline.neon export-ignore
phpunit.xml.dist export-ignore
psalm.xml export-ignore
psalm-baseline.xml export-ignore

# Split package files
src/Validation/.gitattributes export-ignore
src/Validation/phpstan.neon.dist export-ignore
src/Validation/tests/ export-ignore
8 changes: 8 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,14 @@ jobs:
if: always()
run: php contrib/validate-deprecation-aliases.php

- name: Run composer.json validation for split packages
if: always()
run: php contrib/validate-split-packages.php

- name: Run PHPStan for split packages
if: always()
run: php contrib/validate-split-packages-phpstan.php

- name: Prefer lowest check
if: matrix.prefer-lowest == 'prefer-lowest'
run: composer require --dev dereuromark/composer-prefer-lowest && vendor/bin/validate-prefer-lowest -m
Expand Down
56 changes: 56 additions & 0 deletions contrib/validate-split-packages-phpstan.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/usr/bin/php -q
<?php
declare(strict_types=1);

/*
* Validate split packages through PHPStan.
*/

$options = [
__DIR__ . '/../vendor/autoload.php',
__DIR__ . '/vendor/autoload.php',
];
if (!empty($_SERVER['PWD'])) {
array_unshift($options, $_SERVER['PWD'] . '/vendor/autoload.php');
}

foreach ($options as $file) {
if (file_exists($file)) {
define('COMPOSER_INSTALL', $file);

break;
}
}
require COMPOSER_INSTALL;

$path = dirname(__DIR__) . DS . 'src' . DS;
$di = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS);
$iterator = new RecursiveIteratorIterator($di, RecursiveIteratorIterator::LEAVES_ONLY);
/** @var array<\SplFileInfo> $iterator */
$iterator = new RegexIterator($iterator, '~/src/\w+/composer.json$~');

$packages = [];
$code = 0;
foreach ($iterator as $file) {
$filePath = $file->getPath();
$package = substr($filePath, strrpos($filePath, '/') + 1);
$packages[$filePath . '/'] = $package;
}
ksort($packages);

$issues = [];
foreach ($packages as $path => $package) {
// For now, demo only
if (!file_exists($path . 'phpstan.neon.dist')) {
continue;
}

$exitCode = null;
exec('cd ' . $path . ' && composer install && vendor/bin/phpstan analyze ./', $output, $exitCode);
if ($exitCode !== 0) {
$code = $exitCode;
}
exec('cd ' . $path . ' && rm composer.lock && rm -rf vendor');
}

exit($code);
2 changes: 1 addition & 1 deletion contrib/validate-split-packages.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
$di = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS);
$iterator = new RecursiveIteratorIterator($di, RecursiveIteratorIterator::LEAVES_ONLY);
/** @var array<\SplFileInfo> $iterator */
$iterator = new RegexIterator($iterator, '~composer.json$~');
$iterator = new RegexIterator($iterator, '~/src/\w+/composer.json$~');

$packages = [];
$code = 0;
Expand Down
11 changes: 6 additions & 5 deletions psalm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@
errorBaseline="psalm-baseline.xml"
>
<projectFiles>
<directory name="src" />
<directory name="src/"/>
<ignoreFiles>
<directory name="vendor" />
<directory name="vendor/"/>
<directory name="src/Validation/tests/"/>
</ignoreFiles>
</projectFiles>

Expand All @@ -40,9 +41,9 @@
</UndefinedDocblockClass>
<UndefinedConstant>
<errorLevel type="suppress">
<file name="src/Cache/Engine/ApcuEngine.php" />
<file name="src/Database/Driver/Sqlserver.php" />
<file name="src/Database/Statement/SqlserverStatement.php" />
<file name="src/Cache/Engine/ApcuEngine.php"/>
<file name="src/Database/Driver/Sqlserver.php"/>
<file name="src/Database/Statement/SqlserverStatement.php"/>
</errorLevel>
</UndefinedConstant>
<RedundantPropertyInitializationCheck errorLevel="suppress"/>
Expand Down
10 changes: 10 additions & 0 deletions src/Validation/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Define the line ending behavior of the different file extensions
# Set default behavior, in case users don't have core.autocrlf set.
* text text=auto eol=lf

.php diff=php

# Remove files for archives generated using `git archive`
.gitattributes export-ignore
phpstan.neon.dist export-ignore
tests/ export-ignore
4 changes: 4 additions & 0 deletions src/Validation/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,9 @@
"psr-4": {
"Cake\\Validation\\": "."
}
},
"require-dev": {
"cakephp/i18n": "^5.0",
"phpstan/phpstan": "^1.10"
}
}
11 changes: 11 additions & 0 deletions src/Validation/phpstan.neon.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
parameters:
level: 8
checkMissingIterableValueType: false
checkGenericClassInNonGenericObjectType: false
treatPhpDocTypesAsCertain: false
bootstrapFiles:
- tests/phpstan-bootstrap.php
paths:
- ./
excludePaths:
- vendor/
68 changes: 68 additions & 0 deletions src/Validation/tests/phpstan-bootstrap.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php
declare(strict_types=1);

/**
* CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Cake Software Foundation, Inc. (https://cakefoundation.org)
* @link https://cakephp.org CakePHP(tm) Project
* @license https://opensource.org/licenses/mit-license.php MIT License
*/

use Cake\Core\Configure;

if (is_file('vendor/autoload.php')) {
require_once 'vendor/autoload.php';
} else {
require_once dirname(__DIR__) . '/vendor/autoload.php';
}

if (!defined('DS')) {
define('DS', DIRECTORY_SEPARATOR);
}
define('ROOT', dirname(__DIR__));
define('APP_DIR', 'TestApp');

define('TMP', sys_get_temp_dir() . DS);
define('LOGS', TMP . 'logs' . DS);
define('CACHE', TMP . 'cache' . DS);
define('SESSIONS', TMP . 'sessions' . DS);

define('CAKE_CORE_INCLUDE_PATH', ROOT);
define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS);
define('CAKE', CORE_PATH . 'src' . DS);
define('CORE_TESTS', CORE_PATH . 'tests' . DS);
define('CORE_TEST_CASES', CORE_TESTS . 'TestCase');
define('TEST_APP', CORE_TESTS . 'test_app' . DS);

// Point app constants to the test app.
define('APP', TEST_APP . 'TestApp' . DS);
define('WWW_ROOT', TEST_APP . 'webroot' . DS);
define('CONFIG', TEST_APP . 'config' . DS);

// phpcs:disable
@mkdir(LOGS);
@mkdir(SESSIONS);
@mkdir(CACHE);
@mkdir(CACHE . 'views');
@mkdir(CACHE . 'models');
// phpcs:enable

require_once ROOT . DS . 'vendor/cakephp/core/functions.php';

date_default_timezone_set('UTC');
mb_internal_encoding('UTF-8');

Configure::write('debug', true);
Configure::write('App', [
'namespace' => 'App',
'encoding' => 'UTF-8',
]);

ini_set('intl.default_locale', 'en_US');
ini_set('session.gc_divisor', '1');
ini_set('assert.exception', '1');

0 comments on commit b4814c6

Please sign in to comment.