rectorphp / rector

Instant Upgrades and Automated Refactoring of any PHP 5.3+ code
https://getrector.com
MIT License
8.63k stars 680 forks source link

Using Rector to downgrade Rector to PHP 7.1 #4421

Closed leoloso closed 3 years ago

leoloso commented 3 years ago

Feature Request

Make Rector be able to run on PHP 7.1, by applying the Rector downgrade rules on itself.

Objective

Rector's source code must not be modified, so the experimental PR (#4370) will not work, and is not meant to work. Instead, the downgrade must be applied on the CI process to produce an additional asset (maybe a .zip file?): "Rector on PHP 7.1"

Question: how will users access, install and execute this asset?

Status

I have Rector already working on PHP 7.1 in my computer:

Screenshot 2020-10-15 at 8 45 24 PM

I'll describe what I've done so far.

Running a PHP 7.1 environment

I'm using Lando to spin an environment running PHP 7.1 up, and install a sample project. I can access the project files from both the Lando environment on PHP 7.1, and from my terminal on PHP 7.4.

Steps

All dependencies for production must be downgraded to 7.1. Dependencies for development, we don't need to bother about them, because the new "Rector in PHP 7.1" asset is generated for production: even if the developers are, themselves, using Rector on the development mode, the installed dependency from Rector will be the production one. This simplifies the task of having to make sure that all 3rd party dependencies can be downgraded.

I checked what 3rd-party dependencies need PHP 7.2 or above, by going to vendor/rector/rector (installed as a dependency in my project), running composer install --no-dev on PHP 7.4, and then composer why php. The list of packages on PHP 7.2 or above is this one:

rector/rector                         dev-master  requires  php (^7.2.4|^8.0)
doctrine/inflector                    2.0.3       requires  php (^7.2 || ^8.0)
doctrine/lexer                        1.2.1       requires  php (^7.2 || ^8.0)
migrify/migrify-kernel                0.3.49      requires  php (>=7.2)
migrify/php-config-printer            0.3.49      requires  php (>=7.2)
psr/event-dispatcher                  1.0.0       requires  php (>=7.2.0)
sebastian/diff                        4.0.3       requires  php (>=7.3)
symfony/cache                         v5.1.7      requires  php (>=7.2.5)
symfony/cache-contracts               v2.2.0      requires  php (>=7.2.5)
symfony/config                        v5.1.7      requires  php (>=7.2.5)
symfony/console                       v5.1.7      requires  php (>=7.2.5)
symfony/dependency-injection          v5.1.7      requires  php (>=7.2.5)
symfony/error-handler                 v5.1.7      requires  php (>=7.2.5)
symfony/event-dispatcher              v5.1.7      requires  php (>=7.2.5)
symfony/event-dispatcher-contracts    v2.2.0      requires  php (>=7.2.5)
symfony/filesystem                    v5.1.7      requires  php (>=7.2.5)
symfony/finder                        v5.1.7      requires  php (>=7.2.5)
symfony/http-client-contracts         v2.3.1      requires  php (>=7.2.5)
symfony/http-foundation               v5.1.7      requires  php (>=7.2.5)
symfony/http-kernel                   v5.1.7      requires  php (>=7.2.5)
symfony/process                       v5.1.7      requires  php (>=7.2.5)
symfony/service-contracts             v2.2.0      requires  php (>=7.2.5)
symfony/string                        v5.1.7      requires  php (>=7.2.5)
symfony/var-dumper                    v5.1.7      requires  php (>=7.2.5)
symfony/var-exporter                  v5.1.7      requires  php (>=7.2.5)
symfony/yaml                          v5.1.7      requires  php (>=7.2.5)
symplify/autowire-array-parameter     8.3.35      requires  php (>=7.2)
symplify/composer-json-manipulator    8.3.35      requires  php (>=7.2)
symplify/console-color-diff           8.3.35      requires  php (>=7.2)
symplify/easy-testing                 8.3.35      requires  php (>=7.2)
symplify/package-builder              8.3.35      requires  php (>=7.2)
symplify/set-config-resolver          8.3.35      requires  php (>=7.2)
symplify/smart-file-system            8.3.35      requires  php (>=7.2)
symplify/symplify-kernel              8.3.35      requires  php (>=7.2)

So I downgraded all of them to 7.1, by running Rector on PHP 7.4 with rector.php:

<?php

declare(strict_types=1);

use Rector\Core\Configuration\Option;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Rector\Set\ValueObject\SetList;

return static function (ContainerConfigurator $containerConfigurator): void {
    // get parameters
    $parameters = $containerConfigurator->parameters();

    // paths to refactor; solid alternative to CLI arguments
    $parameters->set(Option::PATHS, [
        // Rector
        __DIR__ . '/vendor/rector/rector',
        // Rector's dependencies
        __DIR__ . '/vendor/doctrine/inflector',
        __DIR__ . '/vendor/doctrine/lexer',
        __DIR__ . '/vendor/migrify/migrify-kernel',
        __DIR__ . '/vendor/migrify/php-config-printer',
        __DIR__ . '/vendor/psr/event-dispatcher',
        __DIR__ . '/vendor/sebastian/diff',
        __DIR__ . '/vendor/symfony/cache',
        __DIR__ . '/vendor/symfony/cache-contracts',
        __DIR__ . '/vendor/symfony/config',
        __DIR__ . '/vendor/symfony/console',
        __DIR__ . '/vendor/symfony/dependency-injection',
        __DIR__ . '/vendor/symfony/error-handler',
        __DIR__ . '/vendor/symfony/event-dispatcher',
        __DIR__ . '/vendor/symfony/event-dispatcher-contracts',
        __DIR__ . '/vendor/symfony/filesystem',
        __DIR__ . '/vendor/symfony/finder',
        __DIR__ . '/vendor/symfony/http-client-contracts',
        __DIR__ . '/vendor/symfony/http-foundation',
        __DIR__ . '/vendor/symfony/http-kernel',
        __DIR__ . '/vendor/symfony/process',
        __DIR__ . '/vendor/symfony/service-contracts',
        __DIR__ . '/vendor/symfony/string',
        __DIR__ . '/vendor/symfony/var-dumper',
        __DIR__ . '/vendor/symfony/var-exporter',
        __DIR__ . '/vendor/symfony/yaml',
        __DIR__ . '/vendor/symplify/autowire-array-parameter',
        __DIR__ . '/vendor/symplify/composer-json-manipulator',
        __DIR__ . '/vendor/symplify/console-color-diff',
        __DIR__ . '/vendor/symplify/easy-testing',
        __DIR__ . '/vendor/symplify/package-builder',
        __DIR__ . '/vendor/symplify/set-config-resolver',
        __DIR__ . '/vendor/symplify/smart-file-system',
        __DIR__ . '/vendor/symplify/symplify-kernel',
    ]);

    // is there a file you need to skip?
    $parameters->set(Option::EXCLUDE_PATHS, [
        // Rector
        __DIR__ . '/vendor/rector/rector/.docker/*',
        __DIR__ . '/vendor/rector/rector/.github/*',
        __DIR__ . '/vendor/rector/rector/bin/*',
        __DIR__ . '/vendor/rector/rector/ci/*',
        __DIR__ . '/vendor/rector/rector/docs/*',
        __DIR__ . '/vendor/rector/rector/tests/*',
        __DIR__ . '/vendor/rector/rector/**/tests/*',
        __DIR__ . '/vendor/rector/rector/packages/rector-generator/templates/*',

        // Rector own dependencies
        __DIR__ . '/vendor/symplify/**/.docker/*',
        __DIR__ . '/vendor/symplify/**/.github/*',
        __DIR__ . '/vendor/symplify/**/bin/*',
        __DIR__ . '/vendor/symplify/**/ci/*',
        __DIR__ . '/vendor/symplify/**/docs/*',
        __DIR__ . '/vendor/symplify/**/tests/*',
        __DIR__ . '/vendor/migrify/**/.docker/*',
        __DIR__ . '/vendor/migrify/**/.github/*',
        __DIR__ . '/vendor/migrify/**/bin/*',
        __DIR__ . '/vendor/migrify/**/ci/*',
        __DIR__ . '/vendor/migrify/**/docs/*',
        __DIR__ . '/vendor/migrify/**/tests/*',
    ]);

    // here we can define, what sets of rules will be applied
    $parameters->set(Option::SETS, [
        // @todo Uncomment when PHP 8.0 released
        // SetList::DOWNGRADE_PHP80,
        SetList::DOWNGRADE_PHP74,
        SetList::DOWNGRADE_PHP73,
        SetList::DOWNGRADE_PHP72,
    ]);

    // // is your PHP version different from the one your refactor to? [default: your PHP version]
    $parameters->set(Option::PHP_VERSION_FEATURES, '7.1');
};

Can exclude the tests folders, since we don't care about them (this is only for prod), and also must exclude /vendor/rector/rector/packages/rector-generator/templates/* or it throws errors. The others are for enhancement.

The downgrade went well. I got 4 errors, which I've ignored for the time being and should be dealt with:

 [ERROR] Could not process "vendor/symfony/cache/DoctrineProvider.php" file, due to:                                    
         "Analyze error: "Class Doctrine\Common\Cache\CacheProvider not found.". Include your files in                  
         "$parameters->set(Option::AUTOLOAD_PATHS, [...]);" in "rector.php" config.                                     
         See https://github.com/rectorphp/rector#configuration".                                                        

 [ERROR] Could not process "vendor/symfony/http-kernel/Client.php" file, due to:                                        
         "Analyze error: "Class Symfony\Component\BrowserKit\AbstractBrowser not found.". Include your files in         
         "$parameters->set(Option::AUTOLOAD_PATHS, [...]);" in "rector.php" config.                                     
         See https://github.com/rectorphp/rector#configuration".                                                        

 [ERROR] Could not process "vendor/symfony/http-kernel/HttpKernelBrowser.php" file, due to:                             
         "Analyze error: "Class Symfony\Component\BrowserKit\AbstractBrowser not found.". Include your files in         
         "$parameters->set(Option::AUTOLOAD_PATHS, [...]);" in "rector.php" config.                                     
         See https://github.com/rectorphp/rector#configuration".                                                        

 [ERROR] Could not process "vendor/symfony/string/Slugger/AsciiSlugger.php" file, due to:                               
         "Analyze error: "LogicException (You cannot use the "Symfony\Component\String\Slugger\AsciiSlugger" as the     
         "symfony/translation-contracts" package is not installed. Try running "composer require                        
         symfony/translation-contracts".) thrown while looking for class                                                
         Symfony\Component\String\Slugger\AsciiSlugger.". Include your files in                                         
         "$parameters->set(Option::AUTOLOAD_PATHS, [...]);" in "rector.php" config.                                     
         See https://github.com/rectorphp/rector#configuration".                                                        

Having Rector downgraded to PHP 7.1, I switched to the Lando environment.

I modified the php constraint on Rector's composer.json to "^7.1 || ^8.0", or running Rector would throw an error.

I also fixed an issue with migrify (https://github.com/migrify/migrify/pull/194), or it would an error (that PR must still be merged... for the time being, I applied the change manually under vendor to test it)

After that, Rector executes well. I run it on my project with these sets:

<?php

declare(strict_types=1);

use Rector\Core\Configuration\Option;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Rector\Set\ValueObject\SetList;

return static function (ContainerConfigurator $containerConfigurator): void {
    // get parameters
    $parameters = $containerConfigurator->parameters();

    // paths to refactor; solid alternative to CLI arguments
    $parameters->set(Option::PATHS, [
        __DIR__ . '/src',
        __DIR__ . '/vendor/getpop/*/src',
    ]);

    // here we can define, what sets of rules will be applied
    $parameters->set(Option::SETS, [
        SetList::DEAD_CLASSES,
        SetList::DEAD_CODE,
        SetList::CODE_QUALITY,
        SetList::CODING_STYLE,
        SetList::ORDER,
        SetList::PERFORMANCE,
    ]);
};

It worked. Running my application works. I assume there's no leftover PHP 7.3/7.2 code (no dependency currently uses 7.4), for which we haven't created the Rector rule yet, because running Rector on PHP 7.1 didn't complain at all. But this is still a guess: to be sure, we'd need to check all code from all 3rd party dependencies and make sure no unsupported feature is there.

I also attempted set SetList::NAMING at the end of this list, but this one thows this error:

[ERROR] Could not process "vendor/getpop/component-model/src/Engine/Engine.php" file, due to:                          
        "There shouldn't be a property without AttributeKey::CLASS_NODE".

And then huge amount of erros with no message:

 [ERROR] Could not process "vendor/getpop/component-model/src/FieldResolvers/AbstractSchemaFieldResolver.php" file, due 
         to:                                                                                                            
         "".                                                                                                            

 [ERROR] Could not process "vendor/getpop/component-model/src/FieldResolvers/AliasSchemaFieldResolverTrait.php" file,   
         due to:                                                                                                        
         "".   

...

I assume this is not connected to the downgrading, but maybe with being applied after the previous list, or maybe this set is buggy. Must research on it.

Also, please not that no downgrade set can be run on PHP 7.1! For instance, to apply the DOWNGRADE_PHP72 set, the source code is expected to contain PHP 7.2. But then, running Rector on PHP 7.1, it fails to parse that file.

All other sets must also be tested on the downgraded code:

$parameters->set(Option::SETS, [
    SetList::DEFLUENT,
    SetList::ACTION_INJECTION_TO_CONSTRUCTOR_INJECTION,
    SetList::ARRAY_STR_FUNCTIONS_TO_STATIC_CALL,
    SetList::CAKEPHP_30,
    SetList::CAKEPHP_34,
    SetList::CAKEPHP_35,
    SetList::CAKEPHP_36,
    SetList::CAKEPHP_37,
    SetList::CAKEPHP_38,
    SetList::CAKEPHP_40,
    SetList::CAKEPHP_41,
    SetList::CAKEPHP_FLUENT_OPTIONS,
    SetList::CODEIGNITER_40,
    // SetList::CODE_QUALITY,
    // SetList::CODING_STYLE,
    SetList::CODING_STYLE_ADVANCED,
    SetList::CONTRIBUTTE_TO_SYMFONY,
    // SetList::DEAD_CLASSES,
    // SetList::DEAD_CODE,
    SetList::DOCTRINE_25,
    SetList::DOCTRINE_BEHAVIORS_20,
    SetList::DOCTRINE_CODE_QUALITY,
    SetList::DOCTRINE_COMMON_20,
    SetList::DOCTRINE_DBAL_210,
    SetList::DOCTRINE_DBAL_30,
    SetList::DOCTRINE_GEDMO_TO_KNPLABS,
    SetList::DOCTRINE_ID_TO_UUID_STEP_1,
    SetList::DOCTRINE_ID_TO_UUID_STEP_2,
    SetList::DOCTRINE_ID_TO_UUID_STEP_3,
    SetList::DOCTRINE_ID_TO_UUID_STEP_4,
    SetList::DOCTRINE_ID_TO_UUID_STEP_5,
    SetList::DOCTRINE_REPOSITORY_AS_SERVICE,
    SetList::DOCTRINE_SERVICES,
    // SetList::DOWNGRADE_PHP71,
    // SetList::DOWNGRADE_PHP72,
    // SetList::DOWNGRADE_PHP73,
    // SetList::DOWNGRADE_PHP74,
    // SetList::DOWNGRADE_PHP80,
    SetList::EASY_ADMIN_BUNDLE_20,
    SetList::FRAMEWORK_EXTRA_BUNDLE_40,
    SetList::FRAMEWORK_EXTRA_BUNDLE_50,
    SetList::GMAGICK_TO_IMAGICK,
    SetList::JMS_DECOUPLE,
    SetList::KDYBY_EVENTS_TO_CONTRIBUTTE_EVENT_DISPATCHER,
    SetList::KDYBY_TO_SYMFONY,
    SetList::KDYBY_TRANSLATOR_TO_CONTRIBUTTE_TRANSLATION,
    SetList::LARAVEL_50,
    SetList::LARAVEL_51,
    SetList::LARAVEL_52,
    SetList::LARAVEL_53,
    SetList::LARAVEL_54,
    SetList::LARAVEL_55,
    SetList::LARAVEL_56,
    SetList::LARAVEL_57,
    SetList::LARAVEL_58,
    SetList::LARAVEL_60,
    SetList::LARAVEL_STATIC_TO_INJECTION,
    SetList::MOCKISTA_TO_MOCKERY,
    SetList::MONOLOG_20,
    SetList::MYSQL_TO_MYSQLI,
    SetList::NAMING,
    SetList::NETTE_30,
    SetList::NETTE_30_PARAM_TYPES,
    SetList::NETTE_30_RETURN_TYPES,
    SetList::NETTE_30_DEPENDENCY_INJECTION,
    SetList::NETTE_CODE_QUALITY,
    SetList::NETTE_CONTROL_TO_SYMFONY_CONTROLLER,
    SetList::NETTE_FORMS_TO_SYMFONY,
    SetList::NETTE_PARAM_TYPES,
    SetList::NETTE_RETURN_TYPES,
    SetList::NETTE_TESTER_TO_PHPUNIT,
    SetList::NETTE_TO_SYMFONY,
    SetList::NETTE_UTILS_CODE_QUALITY,
    // SetList::ORDER,
    // SetList::PERFORMANCE,
    SetList::PHALCON_40,
    SetList::PHPEXCEL_TO_PHPSPREADSHEET,
    SetList::PHPSPEC_30,
    SetList::PHPSPEC_40,
    SetList::PHPSPEC_TO_PHPUNIT,
    SetList::PHPSTAN,
    SetList::PHPUNIT80_DMS,
    SetList::PHPUNIT_40,
    SetList::PHPUNIT_50,
    SetList::PHPUNIT_60,
    SetList::PHPUNIT_70,
    SetList::PHPUNIT_75,
    SetList::PHPUNIT_80,
    SetList::PHPUNIT_90,
    SetList::PHPUNIT_91,
    SetList::PHPUNIT_CODE_QUALITY,
    SetList::PHPUNIT_EXCEPTION,
    SetList::PHPUNIT_INJECTOR,
    SetList::PHPUNIT_MOCK,
    SetList::PHPUNIT_SPECIFIC_METHOD,
    SetList::PHPUNIT_YIELD_DATA_PROVIDER,
    SetList::PHP_52,
    SetList::PHP_53,
    SetList::PHP_54,
    SetList::PHP_55,
    SetList::PHP_56,
    SetList::PHP_70,
    SetList::PHP_71,
    SetList::PHP_72,
    SetList::PHP_73,
    SetList::PHP_74,
    SetList::PHP_80,
    SetList::PHP_CODE_SNIFFER_30,
    SetList::PHP_DI_DECOUPLE,
    SetList::PRIVATIZATION,
    SetList::PSR_4,
    SetList::SAFE_07,
    SetList::SOLID,
    SetList::SWIFTMAILER_60,
    SetList::SYMFONY_26,
    SetList::SYMFONY_28,
    SetList::SYMFONY_30,
    SetList::SYMFONY_31,
    SetList::SYMFONY_32,
    SetList::SYMFONY_33,
    SetList::SYMFONY_34,
    SetList::SYMFONY_40,
    SetList::SYMFONY_41,
    SetList::SYMFONY_42,
    SetList::SYMFONY_43,
    SetList::SYMFONY_44,
    SetList::SYMFONY_50,
    SetList::SYMFONY_50_TYPES,
    SetList::SYMFONY_CODE_QUALITY,
    SetList::SYMFONY_CONSTRUCTOR_INJECTION,
    SetList::SYMFONY_PHPUNIT,
    SetList::SYMFONY_AUTOWIRE,
    SetList::TWIG_112,
    SetList::TWIG_127,
    SetList::TWIG_134,
    SetList::TWIG_140,
    SetList::TWIG_20,
    SetList::TWIG_240,
    SetList::TWIG_UNDERSCORE_TO_NAMESPACE,
    SetList::TYPE_DECLARATION,
    SetList::UNWRAP_COMPAT,
]);

Next steps

TomasVotruba commented 3 years ago

tl;dr;

Just to clarify, the goal is to make https://github.com/rectorphp/rector/pull/4370 Whatever automated steps it takes.

The final PHP 7.1 version would be released in own tag or split repository, like rector-prefixed is

E.g. as rector-downgraded

leoloso commented 3 years ago

@TomasVotruba I had an idea

So far I said that we could either always run the downgrade on the whole vendor/ folder for convenience, or manually find out which packages require PHP 7.2+ and downgrade only those.

But there's a better option: we could have a CLI script find out which are the packages needing PHP 7.2, 7.3 and 7.4, and we then integrate it into the CI, so it only downgrades those folders and only with the required downgrade set.

Something similar to compose check-platform-reqs (source code here):

Screenshot 2020-10-20 at 12 31 33 PM

For instance, we could execute something like rector analyze-packages-to-downgrade vendor/ --php-version=7.2 and same for 7.3 and 7.4. Then we capture this output and feed it into the next process: rector process ${LIST_OF_PHP72_FOLDERS} --set=DOWNGRADE_PHP72.

Doing this, you can run DOWNGRADE_PHP74 only on those packages requiring PHP 7.4, but not the ones requiring 7.3 and 7.2, so it will take the minimum possible time. And the 2nd process can be a multitude of rector process commands, possibly 1 command per downgrade set per package, so you get a failure as soon as possible.

What do you think?

leoloso commented 3 years ago

Oh, actually we can use composer why-not!

$ composer why-not php 7.3
$ composer why-not php 7.2
$ composer why-not php 7.1

Then we grep the output to get those packages

leoloso commented 3 years ago

The PATCH version must also be included. Doing:

composer why-not php 7.2

includes result:

symfony/cache-contracts                       v2.2.0     requires  php (>=7.2.5)

So must do:

$ composer why-not php 7.3.23
$ composer why-not php 7.2.34
$ composer why-not php 7.1.33
leoloso commented 3 years ago

Or better, this also works:

$ composer why-not php 7.3.*
$ composer why-not php 7.2.*
$ composer why-not php 7.1.*

For instance, doing composer why-not php 7.2.*, I get:

Screenshot 2020-10-20 at 12 56 34 PM
graphql-api/graphql-api                       -          requires  php (~7.4)   
getpop/access-control                         1.0.x-dev  requires  php (~7.4)   
getpop/api                                    1.0.x-dev  requires  php (~7.4)   
getpop/api-clients                            1.0.x-dev  requires  php (~7.4)   
getpop/api-endpoints                          1.0.x-dev  requires  php (~7.4)   
getpop/api-endpoints-for-wp                   1.0.x-dev  requires  php (~7.4)   
getpop/api-graphql                            1.0.x-dev  requires  php (~7.4)   
getpop/api-mirrorquery                        1.0.x-dev  requires  php (~7.4)   
getpop/cache-control                          1.0.x-dev  requires  php (~7.4)   
getpop/component-model                        1.0.x-dev  requires  php (~7.4)   
getpop/definitions                            1.0.x-dev  requires  php (~7.4)   
getpop/engine                                 1.0.x-dev  requires  php (~7.4)   
getpop/engine-wp                              1.0.x-dev  requires  php (~7.4)   
getpop/field-query                            1.0.x-dev  requires  php (~7.4)   
getpop/guzzle-helpers                         1.0.x-dev  requires  php (~7.4)   
getpop/hooks                                  1.0.x-dev  requires  php (~7.4)   
getpop/hooks-wp                               1.0.x-dev  requires  php (~7.4)   
getpop/loosecontracts                         1.0.x-dev  requires  php (~7.4)   
getpop/mandatory-directives-by-configuration  1.0.x-dev  requires  php (~7.4)   
getpop/modulerouting                          1.0.x-dev  requires  php (~7.4)   
getpop/query-parsing                          1.0.x-dev  requires  php (~7.4)   
getpop/root                                   1.0.x-dev  requires  php (~7.4)   
getpop/routing                                1.0.x-dev  requires  php (~7.4)   
getpop/routing-wp                             1.0.x-dev  requires  php (~7.4)   
getpop/translation                            1.0.x-dev  requires  php (~7.4)   
getpop/translation-wp                         1.0.x-dev  requires  php (~7.4)   
graphql-by-pop/graphql-clients-for-wp         1.0.x-dev  requires  php (~7.4)   
graphql-by-pop/graphql-endpoint-for-wp        1.0.x-dev  requires  php (~7.4)   
graphql-by-pop/graphql-query                  1.0.x-dev  requires  php (~7.4)   
graphql-by-pop/graphql-request                1.0.x-dev  requires  php (~7.4)   
graphql-by-pop/graphql-server                 1.0.x-dev  requires  php (~7.4)   
phpunit/php-code-coverage                     9.2.0      requires  php (>=7.3)  
phpunit/php-file-iterator                     3.0.5      requires  php (>=7.3)  
phpunit/php-invoker                           3.1.1      requires  php (>=7.3)  
phpunit/php-text-template                     2.0.3      requires  php (>=7.3)  
phpunit/php-timer                             5.0.2      requires  php (>=7.3)  
phpunit/phpunit                               9.4.1      requires  php (>=7.3)  
pop-schema/basic-directives                   1.0.x-dev  requires  php (~7.4)   
pop-schema/commentmeta                        1.0.x-dev  requires  php (~7.4)   
pop-schema/commentmeta-wp                     1.0.x-dev  requires  php (~7.4)   
pop-schema/comments                           1.0.x-dev  requires  php (~7.4)   
pop-schema/comments-wp                        1.0.x-dev  requires  php (~7.4)   
pop-schema/custompostmedia                    1.0.x-dev  requires  php (~7.4)   
pop-schema/custompostmedia-wp                 1.0.x-dev  requires  php (~7.4)   
pop-schema/custompostmeta                     1.0.x-dev  requires  php (~7.4)   
pop-schema/custompostmeta-wp                  1.0.x-dev  requires  php (~7.4)   
pop-schema/customposts                        1.0.x-dev  requires  php (~7.4)   
pop-schema/customposts-wp                     1.0.x-dev  requires  php (~7.4)   
pop-schema/generic-customposts                1.0.x-dev  requires  php (~7.4)   
pop-schema/media                              1.0.x-dev  requires  php (~7.4)   
pop-schema/media-wp                           1.0.x-dev  requires  php (~7.4)   
pop-schema/meta                               1.0.x-dev  requires  php (~7.4)   
pop-schema/metaquery                          1.0.x-dev  requires  php (~7.4)   
pop-schema/metaquery-wp                       1.0.x-dev  requires  php (~7.4)   
pop-schema/pages                              1.0.x-dev  requires  php (~7.4)   
pop-schema/pages-wp                           1.0.x-dev  requires  php (~7.4)   
pop-schema/post-tags                          1.0.x-dev  requires  php (~7.4)   
pop-schema/post-tags-wp                       1.0.x-dev  requires  php (~7.4)   
pop-schema/posts                              1.0.x-dev  requires  php (~7.4)   
pop-schema/posts-wp                           1.0.x-dev  requires  php (~7.4)   
pop-schema/queriedobject                      1.0.x-dev  requires  php (~7.4)   
pop-schema/queriedobject-wp                   1.0.x-dev  requires  php (~7.4)   
pop-schema/schema-commons                     1.0.x-dev  requires  php (~7.4)   
pop-schema/tags                               1.0.x-dev  requires  php (~7.4)   
pop-schema/tags-wp                            1.0.x-dev  requires  php (~7.4)   
pop-schema/taxonomies                         1.0.x-dev  requires  php (~7.4)   
pop-schema/taxonomies-wp                      1.0.x-dev  requires  php (~7.4)   
pop-schema/taxonomymeta                       1.0.x-dev  requires  php (~7.4)   
pop-schema/taxonomymeta-wp                    1.0.x-dev  requires  php (~7.4)   
pop-schema/taxonomyquery                      1.0.x-dev  requires  php (~7.4)   
pop-schema/taxonomyquery-wp                   1.0.x-dev  requires  php (~7.4)   
pop-schema/user-roles                         1.0.x-dev  requires  php (~7.4)   
pop-schema/user-roles-access-control          1.0.x-dev  requires  php (~7.4)   
pop-schema/user-roles-wp                      1.0.x-dev  requires  php (~7.4)   
pop-schema/user-state                         1.0.x-dev  requires  php (~7.4)   
pop-schema/user-state-access-control          1.0.x-dev  requires  php (~7.4)   
pop-schema/user-state-wp                      1.0.x-dev  requires  php (~7.4)   
pop-schema/usermeta                           1.0.x-dev  requires  php (~7.4)   
pop-schema/usermeta-wp                        1.0.x-dev  requires  php (~7.4)   
pop-schema/users                              1.0.x-dev  requires  php (~7.4)   
pop-schema/users-wp                           1.0.x-dev  requires  php (~7.4)   
sebastian/cli-parser                          1.0.1      requires  php (>=7.3)  
sebastian/code-unit                           1.0.7      requires  php (>=7.3)  
sebastian/code-unit-reverse-lookup            2.0.3      requires  php (>=7.3)  
sebastian/comparator                          4.0.5      requires  php (>=7.3)  
sebastian/complexity                          2.0.1      requires  php (>=7.3)  
sebastian/diff                                4.0.3      requires  php (>=7.3)  
sebastian/environment                         5.1.3      requires  php (>=7.3)  
sebastian/exporter                            4.0.3      requires  php (>=7.3)  
sebastian/global-state                        5.0.1      requires  php (>=7.3)  
sebastian/lines-of-code                       1.0.1      requires  php (>=7.3)  
sebastian/object-enumerator                   4.0.3      requires  php (>=7.3)  
sebastian/object-reflector                    2.0.3      requires  php (>=7.3)  
sebastian/recursion-context                   4.0.3      requires  php (>=7.3)  
sebastian/resource-operations                 3.0.3      requires  php (>=7.3)  
sebastian/type                                2.3.0      requires  php (>=7.3)  
sebastian/version                             3.0.2      requires  php (>=7.3)
leoloso commented 3 years ago

Combined with grep -o on any word containing "/":

composer why-not php 7.2.* | grep -o "\S*\/\S*"

I get the packages!

graphql-api/graphql-api
getpop/access-control
getpop/api
getpop/api-clients
getpop/api-endpoints
getpop/api-endpoints-for-wp
getpop/api-graphql
getpop/api-mirrorquery
getpop/cache-control
getpop/component-model
getpop/definitions
getpop/engine
getpop/engine-wp
getpop/field-query
getpop/guzzle-helpers
getpop/hooks
getpop/hooks-wp
getpop/loosecontracts
getpop/mandatory-directives-by-configuration
getpop/modulerouting
getpop/query-parsing
getpop/root
getpop/routing
getpop/routing-wp
getpop/translation
getpop/translation-wp
graphql-by-pop/graphql-clients-for-wp
graphql-by-pop/graphql-endpoint-for-wp
graphql-by-pop/graphql-query
graphql-by-pop/graphql-request
graphql-by-pop/graphql-server
phpunit/php-code-coverage
phpunit/php-file-iterator
phpunit/php-invoker
phpunit/php-text-template
phpunit/php-timer
phpunit/phpunit
pop-schema/basic-directives
pop-schema/commentmeta
pop-schema/commentmeta-wp
pop-schema/comments
pop-schema/comments-wp
pop-schema/custompostmedia
pop-schema/custompostmedia-wp
pop-schema/custompostmeta
pop-schema/custompostmeta-wp
pop-schema/customposts
pop-schema/customposts-wp
pop-schema/generic-customposts
pop-schema/media
pop-schema/media-wp
pop-schema/meta
pop-schema/metaquery
pop-schema/metaquery-wp
pop-schema/pages
pop-schema/pages-wp
pop-schema/post-tags
pop-schema/post-tags-wp
pop-schema/posts
pop-schema/posts-wp
pop-schema/queriedobject
pop-schema/queriedobject-wp
pop-schema/schema-commons
pop-schema/tags
pop-schema/tags-wp
pop-schema/taxonomies
pop-schema/taxonomies-wp
pop-schema/taxonomymeta
pop-schema/taxonomymeta-wp
pop-schema/taxonomyquery
pop-schema/taxonomyquery-wp
pop-schema/user-roles
pop-schema/user-roles-access-control
pop-schema/user-roles-wp
pop-schema/user-state
pop-schema/user-state-access-control
pop-schema/user-state-wp
pop-schema/usermeta
pop-schema/usermeta-wp
pop-schema/users
pop-schema/users-wp
sebastian/cli-parser
sebastian/code-unit
sebastian/code-unit-reverse-lookup
sebastian/comparator
sebastian/complexity
sebastian/diff
sebastian/environment
sebastian/exporter
sebastian/global-state
sebastian/lines-of-code
sebastian/object-enumerator
sebastian/object-reflector
sebastian/recursion-context
sebastian/resource-operations
sebastian/type
sebastian/version
leoloso commented 3 years ago

The package can be installed under a custom folder, so that sebastian/version is not found under vendor/sebastian/version.

So then, we can run composer info package-name --path to find out where it's located:

composer info sebastian/version --path

This returns:

sebastian/version /user/Temporary/graphql-api-php71/vendor/sebastian/version

And we obtain the path like this:

composer info sebastian/version --path | sed "s/sebastian\/version //"

Which returns:

/user/Temporary/graphql-api-php71/vendor/sebastian/version

This approach takes a bit of time though! Each time we run composer info it takes a few seconds... Is there any way to speed it up?

TomasVotruba commented 3 years ago

Sounds good.

Please put that in the CI script.

TomasVotruba commented 3 years ago

Resolved in https://github.com/rectorphp/rector/pull/4447