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
901 stars 73 forks source link

Add config-file for PHP-symbols #7

Open heiglandreas opened 9 years ago

heiglandreas commented 9 years ago

Currently the internal symbol-table of the running PHP-binary is used to check for PHP-symbols that might be required. What happens when you required f.e. ext-ldap and run the checker using a PHP-binary that hasn't ext-ldap available? It will surely result in a false-positive.

I still need to check what happens but I'll report back.

Solution would be to have a config-file that contains all symbols that might be available in a PHP-build. This file could be created from the PHP-source code. That file would only contain the PHP-src and ex folders. PECL should not be included!

maglnet commented 9 years ago

Currently it throws an exception, we should find another solution than failing for this point :) https://github.com/maglnet/ComposerRequireChecker/blob/faf96659320dc0ec3b7d2c8619732988d7ca063b/src/ComposerRequireChecker/DefinedSymbolsLocator/LocateDefinedSymbolsFromExtensions.php#L29

maglnet commented 8 years ago

I just realized, if you already require ext-ldap and it is not installed, a composer install should already fail.

But nevertheless, do you have any idea on how one could best create such a file from php-src?

heiglandreas commented 8 years ago

Well, you can always use composer install/update --ignore-platform-reqs.

Excerpt from the composer-page:

 ignore php, hhvm, lib-* and ext-* requirements and force the installation 
 even if the local machine does not fulfill these. See also the platform config option.

So it might happen.

The symbols can be filtered using something like

git clone https://github.com/php/php-src.git
cd php-src
grep -r PHP_FUNCTION ext | awk -F "/" '{print $2 ":" $3}' | awk -F ":" '{print $1 " " $3}' | sed "s/PHP_FUNCTION//" | sed "s/static //"

Looks then something like this:

ldap (ldap_start_tls)
ldap (ldap_set_rebind_proc)
ldap (ldap_escape)
ldap (ldap_t61_to_8859)
ldap (ldap_8859_to_t61)
ldap (ldap_control_paged_result)
ldap (ldap_control_paged_result_response)
libxml (libxml_set_streams_context);
libxml (libxml_use_internal_errors);
libxml (libxml_get_last_error);
libxml (libxml_clear_errors);
libxml (libxml_get_errors);
libxml (libxml_set_external_entity_loader);
libxml (libxml_disable_entity_loader);
libxml (libxml_set_streams_context)
libxml (libxml_use_internal_errors)
libxml (libxml_get_last_error)
libxml (libxml_get_errors)
libxml (libxml_clear_errors)
libxml (libxml_disable_entity_loader)
libxml (libxml_set_external_entity_loader)
mbstring (mb_language)
mbstring (mb_internal_encoding)
mbstring (mb_http_input)
mbstring (mb_http_output)
mbstring (mb_detect_order)
mbstring (mb_substitute_character)
mbstring (mb_preferred_mime_name)

First part is the extension, second one is the function name

I'm pretty sure that the grep-line can be optimized beyond my wildest dreams but it's a start!

maglnet commented 8 years ago

Right, didn't think about --ignore-platform-reqs.

The grep is a good start, I'll see if I can adjust it to fetch constants, classes and interfaces, too.

heiglandreas commented 8 years ago

clang might also be a possibility to extract the informations. But I'm not deep enough into it at the moment. I need a bit more time for that. Might be the easiest to use the grep and a bit of manual adaption and then use clang for the next PHP-version.

heiglandreas commented 8 years ago

I've set up a rudimentary parser for the sources.

https://github.com/maglnet/ComposerRequireChecker/compare/master...heiglandreas:feature/addSourceParser?expand=1

pavarnos commented 5 years ago

on a related note. My production servers have newrelic installed. Development servers do not. composer.json does not have it listed for this reason. Calls to newrelic are wrapped so we don't get errors in development eg

    public static function newrelicNameTransaction(string $url)
    {
        if (function_exists('newrelic_name_transaction') && !empty($url)) {
            // @codeCoverageIgnoreStart
            newrelic_name_transaction($url);
            // @codeCoverageIgnoreEnd
        }
    }

It would be helpful to have a way to add some symbols to ignore to a text file (eg newrelic_name_transaction) so that when #98 is merged we can have a 0 exit code.

In my project I also have maybe 20 define()d constants which hold system / environment configuration. It would be handy to exclude those too.

maglnet commented 5 years ago

@pavarnos I think your problem can already be solved by using an additional config file as described here: https://github.com/maglnet/ComposerRequireChecker#configuration

You may copy this file, add the symbols (function names and constant names) to the symbol-whitelist and then call comoposer-require-checker with the --config-file=path/to/config.json argument.

pavarnos commented 5 years ago

thanks. i did see that but wondered about overriding all these defaults with my own. Is there a way to add to the defaults (in case they change in future)?

maglnet commented 5 years ago

There's #72 addressing exactly your issue. For now only overriding is possible.