Skip to content

Commit

Permalink
This is a combination of 195 commits.
Browse files Browse the repository at this point in the history
new Application version strategy - see GH-267
make compatibility analyser compatible with Sniff architecture - see GH-268
removes old phpunit result printer system
fix DeclareSniff following code reorganization applied to solve issue GH-186
fix AnonymousClassSniff following code reorganization applied to solve issue GH-186
fix ReturnTypeDeclarationSniff following code reorganization applied to solve issue GH-186
migrate old documentation from AsciiDoc to Markdown format
add FilterVisitor and DataCollector(s) component in new architecture 5.4
add contract for ReferenceCollection
add Profiler component in new architecture 5.4
includes part of PHP_Reflect code to decouple CompatInfo from Reflect runner
better identification of anonymous classes, closures, generators
reorganize sniffs by sub folders
use rename ExponantiationSniff to PowOperatorSniff (with ParamTypeDeclarationSniff) to fully fix issue GH-142
use ShortTernaryOperatorSniff to detect elvis syntax
renamed AnonymousFunctionSniff to ClosureSniff
add UseTraitSniff to solve issue gh-227
add CombinedComparisonOperatorSniff to detect Spaceship syntax since PHP 7.0
rename ClassMemberAccessOnInstantiationSniff to ClassMemberAccessSniff and add onCloning PHP 7 feature
add MagicClassConstantSniff to detect ::class syntax since PHP 5.5
add GeneratorSniff to solve issue gh-226; Return expression is not yet handle
add TypedPropertySniff for PHP 7.4 new feature
add phpunit group not_implemented to solve situation of generator return expression (test case exists but not yet implementation)
use ClassExprSyntaxSniff to detect Class::{'expr'} syntax since PHP 5.4
add BinaryNumberFormatSniff to detect bin number format syntax introduced in PHP 5.4
switch from internal api v3 to v5 with a lite analyser:run command with only source path (no more json config file required)
introduces ErrorHandler compatible with nikic/php-parser handled by --stop-on-failure option
introduces logger with --debug option to replace old plugin system
refactor event dispatcher/subscriber features and add container with symfony/dependency-injection component
allow to use the new config option to load dynamically php external configuration via symfony/dependency-injection
add MagicMethodsSniff to detect magic methods since PHP 5.1
replace hard-coded sniffs by a dynamic collection (see dependency-injection/container)
introduces ApplicationInterface to be able to replace instance of console application easily
remove display of php.all info in compatibility analyser
analyser V5 never used anymore the Reflect common v3 component
add CryptStringSniff to solve issue gh-220 (refactor for v5.4)
add new ConditionalCodeSniff
speed-up analysis process by removing priority file queue that is no more necessary
  • Loading branch information
llaville committed Oct 1, 2020
1 parent 5b58fb5 commit 2236e00
Show file tree
Hide file tree
Showing 489 changed files with 12,459 additions and 22,722 deletions.
35 changes: 35 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,41 @@ using the [Keep a CHANGELOG](http://keepachangelog.com) principles.

## [Unreleased]

### Added

- introduces new `DeclareSniff` to enhance PHP 7 declare control structure detection - (see also [GH-268](https://github.com/llaville/php-compat-info/issues/268))
- new `AnonymousClassSniff` to detect anonymous class - (see also [GH-269](https://github.com/llaville/php-compat-info/issues/269))
- new `ReturnTypeDeclarationSniff` to enhance PHP 7 detection - (see also [GH-233](https://github.com/llaville/php-compat-info/issues/233). Thanks to @CybotTM)
- new `ParamTypeDeclarationSniff` to detect type hint on function signatures - (see also [GH-273](https://github.com/llaville/php-compat-info/issues/273))
- new `ReservedSniff` to enhance PHP 7 detection - (see also [GH-186](https://github.com/llaville/php-compat-info/issues/186). Thanks to @fabiang)
- uses new `NullCoalesceOperatorSniff` instead of internal compatibility analyser code - (see also [GH-260](https://github.com/llaville/php-compat-info/issues/260))
- new `PowOperatorSniff` to solve issues [GH-142](https://github.com/llaville/php-compat-info/issues/142) and [GH-211](https://github.com/llaville/php-compat-info/issues/211)
- new `UseTraitSniff` to solve issue [GH-227](https://github.com/llaville/php-compat-info/issues/227)
- new `ClassMemberAccessSniff` to solve issue [GH-154](https://github.com/llaville/php-compat-info/issues/154)
- new `GeneratorSniff` to solve issue [GH-226](https://github.com/llaville/php-compat-info/issues/226)
- new `GotoSniff` to solve issue [GH-200](https://github.com/llaville/php-compat-info/issues/200)
- new `EmptySniff` to solve issues [GH-207](https://github.com/llaville/php-compat-info/pull/207) and [GH-238](https://github.com/llaville/php-compat-info/issues/238)
- new `PropertyDeclarationSniff` to solve issue [GH-119](https://github.com/llaville/php-compat-info/issues/119)
- new `MagicClassConstantSniff` to solve issue [GH-218](https://github.com/llaville/php-compat-info/issues/218)
- new `CryptStringSniff` to solve issue [GH-220](https://github.com/llaville/php-compat-info/issues/220)
- new `ConditionalCodeSniff` to detection conditional code
- replaces metrics structure by an OOP mechanism (Profiler/Profile/DataCollector)

### Changed

- [Application version strategy](https://github.com/llaville/php-compat-info/issues/267) : `composer/package-versions-deprecated` is used to handle version in Composer/Git strategy
- speed-up analysis process by removing priority file queue that is no more necessary

### Removed

- Removes usage of `jean85/pretty-package-versions` package to handle Composer/Git version strategy
- column `matches` in compatibility analyser output
- `php.all` information that was confusing for lot of users

### Fixed

- issue [GH-275](https://github.com/llaville/php-compat-info/issues/275) Missing extension when class name FQN is resolved under user namespace

## [5.3.0] - 2020-07-08

### Changed
Expand Down
30 changes: 23 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
[![Latest Stable Version](https://img.shields.io/packagist/v/bartlett/php-compatinfo)](https://packagist.org/packages/bartlett/php-compatinfo)
[![Minimum PHP Version)](https://img.shields.io/packagist/php-v/bartlett/php-compatinfo)](https://php.net/)

# PHP CompatInfo

| Stable | Upcoming |
|:------:|:--------:|
| [![Latest Stable Version](https://img.shields.io/packagist/v/bartlett/php-compatinfo)](https://packagist.org/packages/bartlett/php-compatinfo) | [![Unstable Version](https://img.shields.io/packagist/vpre/bartlett/php-compatinfo)](https://packagist.org/packages/bartlett/php-compatinfo) |
| [![Minimum PHP Version)](https://img.shields.io/packagist/php-v/bartlett/php-compatinfo)](https://php.net/) | [![Minimum PHP Version)](https://img.shields.io/packagist/php-v/bartlett/php-compatinfo/5.4.x-dev?color=orange)](https://php.net/) |

**PHP CompatInfo** is a library that
can find the minimum version and the extensions required for a piece of code to run.

Expand Down Expand Up @@ -73,16 +76,29 @@ No warning found.

## Documentation

The documentation for PHP CompatInfo 5.0
in [English](http://php5.laurent-laville.org/compatinfo/manual/5.0/en/)
is available online or downloadable offline to read it later (multiple formats available).
Full documentation is written in MarkDown format, and HTML export is possible with [Daux.io](https://github.com/dauxio/daux.io).
See output results at http://bartlett.laurent-laville.org/php-compatinfo/ or raw `*.md` files in `docs` folder.

**Table of Contents**

* **Features**
- Parse source code in format PHP 5.2 to PHP 7.4
- Detect PHP features for each Major/minor versions
- Detect versions of all directives, constants, functions, classes, interfaces of 100 extensions and more
- Display/Inspect list of extensions, and their versions supported

* **Components**
- PHP-Parser [Node Visitors](docs/01_Components/01_PHP-Parser/Visitors.md)
- [Profiler](docs/01_Components/02_Profiler/Collectors.md)
- Collection of [Sniffs](docs/01_Components/03_Sniffs/Features.md)

AsciiDoc source code are available on `docs` folder of the repository.
* **Configurations**
- Use of PSR11 containers to [configure](docs/02_Configs/README.md) application services.

## Contributors

* Laurent Laville (Lead Dev)
* Thanks to Nikita Popov who wrote a marvellous [PHP Parser](https://github.com/nikic/PHP-Parser) and simplify the job of PHP Reflect.
* Thanks to Nikita Popov who wrote a marvellous [PHP Parser](https://github.com/nikic/PHP-Parser).
* Thanks also to Remi Collet, a contributor of first hours.

[![](https://sourcerer.io/fame/llaville/llaville/php-compat-info/images/0)](https://sourcerer.io/fame/llaville/llaville/php-compat-info/links/0)
Expand Down
29 changes: 12 additions & 17 deletions bin/phpcompatinfo
Original file line number Diff line number Diff line change
@@ -1,32 +1,27 @@
#!/usr/bin/env php
<?php
$appName = 'phpcompatinfo';

if (PHP_SAPI !== 'cli') {
return;
}

if (\Phar::running()) {
$vendorDir = 'phar://' . $appName . '.phar/vendor';
$vendorDir = 'phar://phpcompatinfo.phar/vendor';
} else {
$baseDir = dirname(__DIR__);
$vendorDir = $baseDir . '/vendor';

if (!file_exists($vendorDir . '/autoload.php')) {
$vendorDir = dirname(dirname($baseDir));
}

if (!getenv("BARTLETTRC")) {
putenv("BARTLETTRC=" . $appName . '.json');
}
}
$loader = require_once $vendorDir . '/autoload.php';
$loader->setUseIncludePath(true);

if (PHP_SAPI !== 'cli') {
return;
}
require_once $vendorDir . '/autoload.php';

use Bartlett\Reflect\Environment;
use Bartlett\CompatInfo\Console\Application;
use Bartlett\CompatInfo\Console\ApplicationInterface;

Environment::setScanDir();
/** @var \Symfony\Component\DependencyInjection\ContainerBuilder $container */
$container = require dirname(__DIR__) . '/config/container.php';

$application = new Application();
$application->run();
$app = $container->get(ApplicationInterface::class);
$app->setContainer($container);
exit($app->run());
14 changes: 0 additions & 14 deletions bin/phpcompatinfo.json.dist

This file was deleted.

35 changes: 14 additions & 21 deletions box.json.dist
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
{
"directories": ["src"],
"directories": ["src", "config"],
"compression": "GZ",
"dump-autoload": false,
"files": [
"bin/phpcompatinfo.json.dist",
"manifest.txt",
"LICENSE",
"vendor/bartlett/php-compatinfo-db/LICENSE",
Expand All @@ -12,37 +11,35 @@
"vendor/bartlett/php-reflect/bin/phpreflect.json-schema",
"vendor/composer/package-versions-deprecated/LICENSE",
"vendor/composer/semver/LICENSE",
"vendor/doctrine/cache/LICENSE",
"vendor/doctrine/collections/LICENSE",
"vendor/jean85/pretty-package-versions/LICENSE",
"vendor/justinrainbow/json-schema/LICENSE",
"vendor/laminas/laminas-diagnostics/LICENSE.md",
"vendor/laminas/laminas-zendframework-bridge/LICENSE.md",
"vendor/monolog/monolog/LICENSE",
"vendor/nikic/php-parser/LICENSE",
"vendor/paragonie/random_compat/LICENSE",
"vendor/phpdocumentor/reflection-common/LICENSE",
"vendor/phpdocumentor/reflection-docblock/LICENSE",
"vendor/phpdocumentor/type-resolver/LICENSE",
"vendor/psr/container/LICENSE",
"vendor/psr/event-dispatcher/LICENSE",
"vendor/psr/log/LICENSE",
"vendor/ramsey/uuid/LICENSE",
"vendor/sebastian/version/LICENSE",
"vendor/seld/jsonlint/LICENSE",
"vendor/symfony/config/LICENSE",
"vendor/symfony/console/LICENSE",
"vendor/symfony/dependency-injection/LICENSE",
"vendor/symfony/deprecation-contracts/LICENSE",
"vendor/symfony/event-dispatcher/LICENSE",
"vendor/symfony/event-dispatcher-contracts/LICENSE",
"vendor/symfony/filesystem/LICENSE",
"vendor/symfony/finder/LICENSE",
"vendor/symfony/polyfill-ctype/LICENSE",
"vendor/symfony/polyfill-intl-grapheme/LICENSE",
"vendor/symfony/polyfill-intl-normalizer/LICENSE",
"vendor/symfony/polyfill-mbstring/LICENSE",
"vendor/symfony/polyfill-php73/LICENSE",
"vendor/symfony/polyfill-php80/LICENSE",
"vendor/symfony/serializer/LICENSE",
"vendor/symfony/service-contracts/LICENSE",
"vendor/symfony/stopwatch/LICENSE",
"vendor/symfony/string/LICENSE",
"vendor/webmozart/assert/LICENSE",
"vendor/autoload.php"
],
Expand All @@ -51,10 +48,6 @@
"name": "*.php",
"in": "vendor/composer"
},
{
"name": "*.php",
"in": "vendor/jean85/pretty-package-versions/src"
},
{
"name": "*.php",
"in": "vendor/laminas/laminas-diagnostics/src"
Expand All @@ -71,6 +64,14 @@
"name": "*.php",
"in": "vendor/nikic/php-parser/lib"
},
{
"name": "*.php",
"in": "vendor/paragonie/random_compat/lib"
},
{
"name": "*.php",
"in": "vendor/ramsey/uuid/src"
},
{
"name": "Version.php",
"in": "vendor/sebastian/version/src"
Expand Down Expand Up @@ -104,10 +105,6 @@
"name": "*.php",
"in": "vendor/webmozart/assert/src"
},
{
"name": "*.php",
"in": "vendor/doctrine/cache/lib"
},
{
"name": "*.php",
"in": "vendor/doctrine/collections/lib"
Expand All @@ -116,10 +113,6 @@
"name": "*.php",
"in": "vendor/psr/container/src"
},
{
"name": "*.php",
"in": "vendor/psr/event-dispatcher/src"
},
{
"name": "*.php",
"in": "vendor/psr/log/Psr"
Expand Down
7 changes: 5 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@
"ext-pdo_sqlite": "*",
"bartlett/php-reflect": "^4.4",
"bartlett/php-compatinfo-db": "^2.0",
"jean85/pretty-package-versions": "^1.5",
"psr/log": "^1.0"
"composer/package-versions-deprecated": "^1.8",
"ramsey/uuid": "^3.9|^4.0",
"symfony/serializer": "^4.4|^5.0",
"symfony/config": "^4.4|^5.0",
"symfony/dependency-injection": "^4.4|^5.0"
},
"require-dev": {
"monolog/monolog": "^1.10"
Expand Down
12 changes: 12 additions & 0 deletions config/container.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php declare(strict_types=1);

use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;

$containerBuilder = new ContainerBuilder();
$loader = new PhpFileLoader($containerBuilder, new FileLocator(__DIR__ . '/set'));
$loader->load('default.php');

$containerBuilder->compile(); // mandatory or the sniffCollection won't be populated
return $containerBuilder;
45 changes: 45 additions & 0 deletions config/set/common.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php declare(strict_types=1);

use Bartlett\CompatInfo\Collection\SniffCollection;
use Bartlett\CompatInfo\Console\Application;
use Bartlett\CompatInfo\Console\ApplicationInterface;
use Bartlett\CompatInfo\Sniffs\SniffInterface;

use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use function Symfony\Component\DependencyInjection\Loader\Configurator\tagged_iterator;

/**
* Build the Container with common parameters and services
*
* @link https://symfony.com/doc/current/components/dependency_injection.html#avoiding-your-code-becoming-dependent-on-the-container
*
* @param ContainerConfigurator $containerConfigurator
* @return void
*/
return static function (ContainerConfigurator $containerConfigurator): void {

$services = $containerConfigurator->services();

$services->defaults()
->autowire()
->public()
;

$services->set(ApplicationInterface::class, Application::class)
// for bin file
->public()
;

// @link https://symfony.com/doc/current/service_container/tags.html#autoconfiguring-tags
$services->instanceof(SniffInterface::class)
->tag('phpcompatinfo.compatibility_sniff')
;

$services->load('Bartlett\CompatInfo\Sniffs\\', __DIR__ . '/../../src/Bartlett/CompatInfo/Sniffs')
;

// @link https://symfony.com/doc/current/service_container/tags.html#reference-tagged-services
$services->set(SniffCollection::class, SniffCollection::class)
->args([tagged_iterator('phpcompatinfo.compatibility_sniff')])
;
};
68 changes: 68 additions & 0 deletions config/set/default.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php declare(strict_types=1);

use Bartlett\CompatInfo\Console\Input\Input;
use Bartlett\CompatInfo\Console\Output\Output;
use Bartlett\CompatInfo\Event\Dispatcher\EventDispatcher;
use Bartlett\CompatInfo\Event\Subscriber\LogEventSubscriber;
use Bartlett\CompatInfo\Event\Subscriber\ProfileEventSubscriber;
use Bartlett\CompatInfo\Logger\DefaultLogger;

use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Stopwatch\Stopwatch;
use function Symfony\Component\DependencyInjection\Loader\Configurator\ref;

/**
* Build the Container with default parameters and services
*
* @link https://symfony.com/doc/current/components/dependency_injection.html#avoiding-your-code-becoming-dependent-on-the-container
*
* @param ContainerConfigurator $containerConfigurator
* @return void
*/
return static function (ContainerConfigurator $containerConfigurator): void {
$containerConfigurator->import(__DIR__ . '/common.php');

$parameters = $containerConfigurator->parameters();

$parameters->set('app.log_stream_path', sprintf('/tmp/compatinfo-%s.log', date('YmdHi')));
$parameters->set('app.log_channel', 'App');
$parameters->set('app.log_level', LogLevel::DEBUG);

$services = $containerConfigurator->services();

$services->defaults()
->autowire()
->public()
;

$services->set(InputInterface::class, Input::class);
$services->set(OutputInterface::class, Output::class);

$services->set(Stopwatch::class, Stopwatch::class);

$services->set(LoggerInterface::class, DefaultLogger::class)
->args(['%app.log_stream_path%', '%app.log_channel%', '%app.log_level%'])
;

$services->set(ProfileEventSubscriber::class, ProfileEventSubscriber::class)
->args([ref(Stopwatch::class)])
;

$services->set(LogEventSubscriber::class, LogEventSubscriber::class)
->args([ref(LoggerInterface::class)])
;

$services->set(EventDispatcherInterface::class, EventDispatcher::class)
->args([
ref(InputInterface::class),
ref(ProfileEventSubscriber::class),
ref(LogEventSubscriber::class)
])
;
};
Loading

0 comments on commit 2236e00

Please sign in to comment.