Update to current state and PHP 8.1
This commit is contained in:
parent
cece9d0d02
commit
ec94f51be0
8
.gitignore
vendored
8
.gitignore
vendored
@ -1,4 +1,8 @@
|
||||
/build/
|
||||
/coverage/
|
||||
/tmp/
|
||||
/vendor/
|
||||
*.phar
|
||||
cs-check.json
|
||||
|
||||
/*.cache
|
||||
/*.phar
|
||||
/cs-check.json
|
24
CONTRIBUTING.md
Normal file
24
CONTRIBUTING.md
Normal file
@ -0,0 +1,24 @@
|
||||
# Contributing
|
||||
|
||||
## Code Analysis
|
||||
To check the code quality, run
|
||||
```php
|
||||
composer check
|
||||
```
|
||||
|
||||
To fix any style issues, run
|
||||
```php
|
||||
composer fix
|
||||
```
|
||||
|
||||
## Tests
|
||||
To run the test suite, execute
|
||||
```php
|
||||
composer test
|
||||
```
|
||||
|
||||
## Build
|
||||
[Box](https://github.com/box-project/box) is used to create the phar archive. Run the following command to create the phar:
|
||||
```sh
|
||||
./box.phar compile
|
||||
```
|
@ -7,7 +7,7 @@ use Laminas\ServiceManager\ServiceManager;
|
||||
use Symfony\Component\Console\Application;
|
||||
use Symfony\Component\Console\Input\ArgvInput;
|
||||
|
||||
$serviceManager = new ServiceManager(require("config/serviceManager.php"));
|
||||
$serviceManager = new ServiceManager(require(__DIR__."/../config/serviceManager.php"));
|
||||
$application = new Application();
|
||||
|
||||
$command = $serviceManager->get(CheckCommand::class);
|
||||
|
5
box.json
5
box.json
@ -1,5 +1,8 @@
|
||||
{
|
||||
"base-path": null,
|
||||
"output": "build/extension-check.phar",
|
||||
"chmod": "0700"
|
||||
"chmod": "0700",
|
||||
"files": [
|
||||
"config/serviceManager.php"
|
||||
]
|
||||
}
|
@ -46,12 +46,18 @@
|
||||
},
|
||||
"scripts": {
|
||||
"check": [
|
||||
"./vendor/bin/phpcbf",
|
||||
"./vendor/bin/phpcs",
|
||||
"./vendor/bin/phpstan analyse"
|
||||
],
|
||||
"fix": [
|
||||
"./vendor/bin/phpcbf",
|
||||
"./vendor/bin/phpcs"
|
||||
],
|
||||
"test": [
|
||||
"./vendor/bin/phpunit tests"
|
||||
"./vendor/bin/phpunit --no-coverage"
|
||||
],
|
||||
"coverage": [
|
||||
"XDEBUG_MODE=coverage ./vendor/bin/phpunit"
|
||||
]
|
||||
},
|
||||
"scripts-descriptions": {
|
||||
|
870
composer.lock
generated
870
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -8,8 +8,8 @@ ENV COMPOSER_ALLOW_SUPERUSER 1
|
||||
|
||||
RUN echo "xdebug.start_with_request=yes" >> /usr/local/etc/php/conf.d/xdebug.ini \
|
||||
&& echo "xdebug.mode=debug" >> /usr/local/etc/php/conf.d/xdebug.ini \
|
||||
&& echo "xdebug.log_level = 0" >> /usr/local/etc/php/conf.d/xdebug.ini \
|
||||
&& echo "xdebug.log=/tmp/xdebug.log" >> /usr/local/etc/php/conf.d/xdebug.ini \
|
||||
&& echo "xdebug.discover_client_host=1" >> /usr/local/etc/php/conf.d/xdebug.ini \
|
||||
&& echo "xdebug.client_port=9000" >> /usr/local/etc/php/conf.d/xdebug.ini \
|
||||
&& echo "xdebug.client_host=host.docker.internal" >> /usr/local/etc/php/conf.d/xdebug.ini
|
||||
|
||||
|
@ -8,8 +8,8 @@ ENV COMPOSER_ALLOW_SUPERUSER 1
|
||||
|
||||
RUN echo "xdebug.start_with_request=yes" >> /usr/local/etc/php/conf.d/xdebug.ini \
|
||||
&& echo "xdebug.mode=debug" >> /usr/local/etc/php/conf.d/xdebug.ini \
|
||||
&& echo "xdebug.log_level = 0" >> /usr/local/etc/php/conf.d/xdebug.ini \
|
||||
&& echo "xdebug.log=/tmp/xdebug.log" >> /usr/local/etc/php/conf.d/xdebug.ini \
|
||||
&& echo "xdebug.discover_client_host=1" >> /usr/local/etc/php/conf.d/xdebug.ini \
|
||||
&& echo "xdebug.client_port=9000" >> /usr/local/etc/php/conf.d/xdebug.ini \
|
||||
&& echo "xdebug.client_host=host.docker.internal" >> /usr/local/etc/php/conf.d/xdebug.ini
|
||||
|
||||
|
@ -8,8 +8,8 @@ ENV COMPOSER_ALLOW_SUPERUSER 1
|
||||
|
||||
RUN echo "xdebug.start_with_request=yes" >> /usr/local/etc/php/conf.d/xdebug.ini \
|
||||
&& echo "xdebug.mode=debug" >> /usr/local/etc/php/conf.d/xdebug.ini \
|
||||
&& echo "xdebug.log_level = 0" >> /usr/local/etc/php/conf.d/xdebug.ini \
|
||||
&& echo "xdebug.log=/tmp/xdebug.log" >> /usr/local/etc/php/conf.d/xdebug.ini \
|
||||
&& echo "xdebug.discover_client_host=1" >> /usr/local/etc/php/conf.d/xdebug.ini \
|
||||
&& echo "xdebug.client_port=9000" >> /usr/local/etc/php/conf.d/xdebug.ini \
|
||||
&& echo "xdebug.client_host=host.docker.internal" >> /usr/local/etc/php/conf.d/xdebug.ini
|
||||
|
||||
|
25
phpunit.xml
Normal file
25
phpunit.xml
Normal file
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/8.5/phpunit.xsd"
|
||||
bootstrap="tests/bootstrap.php"
|
||||
colors="true"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite name="unit">
|
||||
<directory>./tests/Unit</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<php>
|
||||
<ini name="date.timezone" value="UTC"/>
|
||||
</php>
|
||||
<filter>
|
||||
<whitelist processUncoveredFilesFromWhitelist="true">
|
||||
<directory suffix=".php">src</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
<logging>
|
||||
<log type="coverage-html" target="./coverage"/>
|
||||
<log type="coverage-text" target="php://stdout" showUncoveredFiles="false"/>
|
||||
</logging>
|
||||
</phpunit>
|
@ -16,6 +16,7 @@ class ExtensionDetails
|
||||
public function __construct()
|
||||
{
|
||||
$this->loadedExtensions = array_map('strtolower', get_loaded_extensions());
|
||||
natcasesort($this->loadedExtensions);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -23,13 +24,12 @@ class ExtensionDetails
|
||||
*/
|
||||
public function getLoadedExtensions(): array
|
||||
{
|
||||
natcasesort($this->loadedExtensions);
|
||||
return $this->loadedExtensions;
|
||||
}
|
||||
|
||||
public function getLoadedExtensionsCount(): int
|
||||
{
|
||||
return count($this->loadedExtensions);
|
||||
return count($this->getLoadedExtensions());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -44,44 +44,47 @@ class ExtensionDetails
|
||||
return $this->extensionMap;
|
||||
}
|
||||
|
||||
public function getExtensionInfo(string $extensionInfo): ExtensionInfo
|
||||
{
|
||||
return new ExtensionInfo($extensionInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $excludedExtensions
|
||||
*/
|
||||
private function buildExtensionMaps(array $excludedExtensions): ExtensionMap
|
||||
{
|
||||
$extensionClasses = $extensionFunctions = $extensionConstants = $extensionDependencies = $uncheckedExtensions = [];
|
||||
foreach ($this->loadedExtensions as $loadedExtension) {
|
||||
|
||||
$loadedExtensions = $this->getLoadedExtensions();
|
||||
foreach ($loadedExtensions as $loadedExtension) {
|
||||
if (in_array($loadedExtension, $excludedExtensions, true)) {
|
||||
continue;
|
||||
}
|
||||
$extensionInfo = $this->getExtensionInfo($loadedExtension);
|
||||
|
||||
$extension = new ReflectionExtension($loadedExtension);
|
||||
|
||||
$classes = $extension->getClasses();
|
||||
$classes = $extensionInfo->getClasses();
|
||||
if (!empty($classes)) {
|
||||
natcasesort($classes);
|
||||
foreach ($classes as $class) {
|
||||
$extensionClasses[$class->getName()] = $loadedExtension;
|
||||
}
|
||||
$extensionClasses = array_merge($extensionClasses, array_map(function () use ($loadedExtension) {
|
||||
return $loadedExtension;
|
||||
}, array_flip($classes)));
|
||||
}
|
||||
|
||||
$functions = $extension->getFunctions();
|
||||
$functions = $extensionInfo->getFunctions();
|
||||
if (!empty($functions)) {
|
||||
natcasesort($functions);
|
||||
foreach ($functions as $function) {
|
||||
$extensionFunctions[$function->getName()] = $loadedExtension;
|
||||
}
|
||||
$extensionFunctions = array_merge($extensionFunctions, array_map(function () use ($loadedExtension) {
|
||||
return $loadedExtension;
|
||||
}, array_flip($functions)));
|
||||
}
|
||||
|
||||
$constants = $extension->getConstants();
|
||||
$constants = $extensionInfo->getConstants();
|
||||
if (!empty($constants)) {
|
||||
natcasesort($constants);
|
||||
foreach ($constants as $constant => $_) {
|
||||
$extensionConstants[$constant] = $loadedExtension;
|
||||
}
|
||||
$extensionConstants = array_merge($extensionConstants, array_map(function () use ($loadedExtension) {
|
||||
return $loadedExtension;
|
||||
}, array_flip($constants)));
|
||||
}
|
||||
|
||||
$dependencies = $extension->getDependencies();
|
||||
/*$dependencies = $extensionInfo->getRequiredDependencies();
|
||||
if (!empty($dependencies)) {
|
||||
natcasesort($dependencies);
|
||||
foreach ($dependencies as $dependency => $status) {
|
||||
@ -95,13 +98,10 @@ class ExtensionDetails
|
||||
|
||||
$extensionDependencies[$loadedExtension][strtolower($status)][] = $dependency;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
// $extension->getINIEntries()
|
||||
// should we check the ini for configured extensions?
|
||||
|
||||
if (empty($classes) && empty($functions)) {
|
||||
$uncheckedExtensions[] = $extension->getName();
|
||||
if (empty($classes) && empty($functions) && empty($constants) && empty($dependencies)) {
|
||||
$uncheckedExtensions[] = $loadedExtension;
|
||||
}
|
||||
}
|
||||
|
||||
|
77
src/Extension/ExtensionInfo.php
Normal file
77
src/Extension/ExtensionInfo.php
Normal file
@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Fbrinker\ExtensionCheck\Extension;
|
||||
|
||||
use ReflectionExtension;
|
||||
|
||||
class ExtensionInfo
|
||||
{
|
||||
/** @var ReflectionExtension */
|
||||
private $extensionReflection;
|
||||
|
||||
public function __construct(string $extension)
|
||||
{
|
||||
$this->extensionReflection = new ReflectionExtension($extension);
|
||||
}
|
||||
|
||||
public function getClasses(): array
|
||||
{
|
||||
$classes = $this->extensionReflection->getClassNames();
|
||||
|
||||
\natcasesort($classes);
|
||||
return $classes;
|
||||
}
|
||||
|
||||
public function getFunctions(): array
|
||||
{
|
||||
$functionReflections = $this->extensionReflection->getFunctions();
|
||||
|
||||
if (empty($functionReflections)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$functions = [];
|
||||
foreach ($functionReflections as $functionReflection) {
|
||||
$functions[] = $functionReflection->getName();
|
||||
}
|
||||
|
||||
\natcasesort($functions);
|
||||
return $functions;
|
||||
}
|
||||
|
||||
public function getConstants(): array
|
||||
{
|
||||
$constants = $this->extensionReflection->getConstants();
|
||||
|
||||
if (empty($constants)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$constants = array_keys($constants);
|
||||
\natcasesort($constants);
|
||||
return $constants;
|
||||
}
|
||||
|
||||
public function getRequiredDependencies(): array
|
||||
{
|
||||
$dependencies = $this->extensionReflection->getDependencies();
|
||||
|
||||
if (empty($dependencies)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$requiredDependencies = [];
|
||||
foreach ($dependencies as $dependency => $status) {
|
||||
if ($status !== 'required') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$requiredDependencies[] = $dependency;
|
||||
}
|
||||
|
||||
\natcasesort($requiredDependencies);
|
||||
return $requiredDependencies;
|
||||
}
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Fbrinker\ExtensionCheck\Extension;
|
||||
|
||||
class ExtensionMap
|
||||
|
@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Fbrinker\ExtensionCheck\Output;
|
||||
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
|
@ -9,7 +9,6 @@ use PhpParser\NodeVisitorAbstract;
|
||||
|
||||
class ClassCollector extends NodeVisitorAbstract implements CollectorInferface
|
||||
{
|
||||
|
||||
/**
|
||||
* @var array<string,bool> $classes
|
||||
*/
|
||||
|
77
tests/Unit/Command/CheckCommandTest.php
Normal file
77
tests/Unit/Command/CheckCommandTest.php
Normal file
@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Fbrinker\ExtensionCheck\Tests\Unit\Command;
|
||||
|
||||
use Fbrinker\ExtensionCheck\Command\CheckCommand;
|
||||
use Fbrinker\ExtensionCheck\Extension\ExtensionCheck;
|
||||
use Fbrinker\ExtensionCheck\Output\SymfonyStyleFactory;
|
||||
use Fbrinker\ExtensionCheck\Parser\FileParser;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Console\Tester\CommandTester;
|
||||
|
||||
class CheckCommandTest extends TestCase
|
||||
{
|
||||
public function testExecuteEmpty(): void
|
||||
{
|
||||
$sut = $this->createEmptySut();
|
||||
|
||||
$commandTester = new CommandTester($sut);
|
||||
$commandTester->execute([]);
|
||||
|
||||
$result = $commandTester->getDisplay();
|
||||
|
||||
$this->assertStringContainsStringIgnoringCase("Files: 0", $result);
|
||||
$this->assertStringContainsStringIgnoringCase("0 Classes, 0 Functions, 0 Constants", $result);
|
||||
$this->assertStringContainsStringIgnoringCase("Loaded Extensions: 0", $result);
|
||||
$this->assertStringContainsStringIgnoringCase("0 Used, 0 Unused", $result);
|
||||
}
|
||||
|
||||
public function testExecuteWithResults(): void
|
||||
{
|
||||
$sut = $this->createSutWithResult();
|
||||
|
||||
$commandTester = new CommandTester($sut);
|
||||
$commandTester->execute([]);
|
||||
|
||||
$result = $commandTester->getDisplay();
|
||||
|
||||
$this->assertStringContainsStringIgnoringCase("Files: 3", $result);
|
||||
$this->assertStringContainsStringIgnoringCase("3 Classes, 2 Functions, 1 Constants", $result);
|
||||
$this->assertStringContainsStringIgnoringCase("Loaded Extensions: 2", $result);
|
||||
$this->assertStringContainsStringIgnoringCase("1 Used, 1 Unused", $result);
|
||||
$this->assertStringContainsStringIgnoringCase("Used [Usage: class]", $result);
|
||||
}
|
||||
|
||||
private function createEmptySut(): CheckCommand
|
||||
{
|
||||
$symfonyStyleFactory = new SymfonyStyleFactory();
|
||||
$fileParserMock = $this->createMock(FileParser::class);
|
||||
$fileParserMock->method('parseFiles')->willReturn([
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
]);
|
||||
$extensionCheckMock = $this->createMock(ExtensionCheck::class);
|
||||
$extensionCheckMock->method('checkUsages')->willReturn([]);
|
||||
return new CheckCommand($symfonyStyleFactory, $fileParserMock, $extensionCheckMock);
|
||||
}
|
||||
|
||||
private function createSutWithResult(): CheckCommand
|
||||
{
|
||||
$symfonyStyleFactory = new SymfonyStyleFactory();
|
||||
$fileParserMock = $this->createMock(FileParser::class);
|
||||
$fileParserMock->method('getFileCount')->willReturn(3);
|
||||
$fileParserMock->method('parseFiles')->willReturn([
|
||||
['A', 'B', 'C'],
|
||||
['gotoA', 'gotoB'],
|
||||
['CONST_C'],
|
||||
]);
|
||||
$extensionCheckMock = $this->createMock(ExtensionCheck::class);
|
||||
$extensionCheckMock->method('getLoadedExtensionsCount')->willReturn(2);
|
||||
$extensionCheckMock->method('checkUsages')->willReturn(['Used' => ['class' => true]]);
|
||||
$extensionCheckMock->method('getUnused')->willReturn(['Unused']);
|
||||
return new CheckCommand($symfonyStyleFactory, $fileParserMock, $extensionCheckMock);
|
||||
}
|
||||
}
|
22
tests/Unit/ServiceManagerTest.php
Normal file
22
tests/Unit/ServiceManagerTest.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Fbrinker\ExtensionCheck\Tests\Unit;
|
||||
|
||||
use Laminas\ServiceManager\ServiceManager;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ServiceManagerTest extends TestCase
|
||||
{
|
||||
public function testServiceManagerConfig(): void
|
||||
{
|
||||
$config = require(__DIR__ . '/../../config/serviceManager.php');
|
||||
$sut = new ServiceManager($config);
|
||||
|
||||
foreach ($config['factories'] as $class => $factory) {
|
||||
$instance = $sut->get($class);
|
||||
$this->assertInstanceOf($class, $instance);
|
||||
}
|
||||
}
|
||||
}
|
5
tests/bootstrap.php
Normal file
5
tests/bootstrap.php
Normal file
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
Loading…
Reference in New Issue
Block a user