maglnet / ComposerRequireChecker

A CLI tool to check whether a specific composer package uses imported symbols that aren't part of its direct composer dependencies
MIT License
882 stars 71 forks source link

Report guess dependencies from installed modules #52

Open mindplay-dk opened 6 years ago

mindplay-dk commented 6 years ago

I got the following output:

+-----------------------------------------+--------------------+
| unknown symbol                          | guessed dependency |
+-----------------------------------------+--------------------+
| mindplay\implant\AssetPackage           |                    |
| trim                                    | ext-standard       |
| preg_replace                            | ext-pcre           |
| RuntimeException                        | ext-SPL            |
| implode                                 | ext-standard       |
| array_map                               | ext-standard       |
| array_keys                              | ext-standard       |
| Kodus\Session\SessionModel              |                    |
| count                                   | ext-standard       |
| Psr\Http\Message\ServerRequestInterface |                    |
| Psr\Http\Message\ResponseInterface      |                    |
| Zend\Diactoros\Response                 |                    |
| mindplay\kisstpl\SimpleViewFinder       |                    |
| call_user_func                          | ext-standard       |
| Zend\Diactoros\Stream                   |                    |
| Codeception\Module                      |                    |
| Codeception\Lib\ModuleContainer         |                    |
| Kodus\Test\FunctionalSupport            |                    |
| Codeception\TestInterface               |                    |
| array_merge                             | ext-standard       |
+-----------------------------------------+--------------------+

All of the dependencies with no guessed dependency, in this example, could have been guessed - they're all installed. Reporting them ought to be fairly easy?

Bonus points for reporting the suggested version constraint 😃

Extra bonus points and cookies 🍪 for an option to automatically update your composer.json with suggested version constraints! 👀

Ocramius commented 6 years ago

Reporting them ought to be fairly easy?

You mean figuring out the composer.json in a parent directory of any of these?

mindplay-dk commented 6 years ago

I'm not sure what you mean by that.

Ideally, I'd like a report that looks like the following:

+-----------------------------------------+-------------------------+
| unknown symbol                          | guessed dependency      |
+-----------------------------------------+-------------------------+
| mindplay\implant\AssetPackage           | mindplay/implant^2.0.2  |

This should be possible by resolving the location of mindplay\implant\AssetPackage using autoloader settings from composer.json, to see which target folder (e.g. vendor/x/t) it resolves to, then query Composer (or maybe composer-locator) to find the matching vendor path, and finally (optionally) look at composer-lock.json to figure out the installed version or the used constraint.

It's not even really a "guess", so much as calculating the missing composer.json entry, I think?

Ocramius commented 6 years ago

Ah yes, this should be feasible, but it requires switching to https://github.com/Roave/BetterReflection first, so that files can be located without being actually loaded.

mindplay-dk commented 6 years ago

it requires switching to https://github.com/Roave/BetterReflection first

ReflectionExtension is used here and the compatibility chart says it won't be supported.

I don't see any other usages of the Reflection API in this package? Everything is already based on AST traversal, it seems. Maybe you changed your strategy after posting this comment? :-)

Ocramius commented 6 years ago

Indeed, I think reflection is not used at all in here: probably outdated reasoning.

KayKursawe commented 3 years ago

Here's a little example of what I put together recently: https://gist.github.com/KayKursawe/524036c6c95fe4214a8759b9fc46704f I think it's pretty much what @mindplay-dk was asking for initially.

These are the steps that I did:

  1. run the composer require checker
  2. edit the output manually by search and replace to contain the class names only, one per line, surrounded by single quotes
  3. paste the edited output into ComposerCheckCommand, see function getClassesToResolve()
  4. run the ComposerCheckCommand command, it will produce an output like this:
    
    # Packages with version constraints (can be applied as is to composer.json)
    "guzzlehttp/guzzle": "^6.3"

Dev packages with version constraints (can be applied as is to composer.json)

"codeception/codeception": "^2.5"

Classes that couldn't be resolved to a package (needs manual checking)

CodeItNow\BarcodeBundle\Utils\BarcodeGenerator Composer\Script\Event Elastica\Query Elastica\Query\AbstractQuery Elastica\Query\BoolQuery Elastica\Query\FunctionScore Elastica\Query\Match Elastica\Query\MatchAll Elastica\Query\MultiMatch Elastica\Query\Term Elastica\ResultSet Elastica\Script\Script Elastica\Suggest Everon\Component\Collection\Collection GuzzleHttp\Promise\rejection_for



Ideally, steps 2. and 3. shouldn't be needed at all, once https://github.com/maglnet/ComposerRequireChecker/issues/294 will be resolved, hopefully.

Of course, this is a quick example only, based on Symfony. Should be good enough to discuss whether this approach might be feasible. Wdyt?