Skip to content

Use Composer PHP required version #1086

@BrianHenryIE

Description

@BrianHenryIE

Would it be a good idea to determine the Composer platform / minimum PHP version and use that for instantiating the parser?

    public function createFromComposer(): Parser {
        return $this->createForVersion(
            PhpVersion::fromString(
                $this->determineMinimumPhpVersion()
            )
        );
    }

    private function determineMinimumPhpVersion(): string {

        $phpParserNewestPhpVersion = PhpVersion::getNewestSupported();
        $phpParserNewestPhpVersionFiveDigitInt = $phpParserNewestPhpVersion->id;

        $major = intval($phpParserNewestPhpVersionFiveDigitInt / 10000);
        $minor = ($phpParserNewestPhpVersionFiveDigitInt - ($major * 10000)) / 100;

        $highestMinimumPhpVersion = "{$major}.{$minor}";

        // Try to determine the Composer minimum PHP version.
        if ( class_exists( InstalledVersions::class ) ) {

            $rootPackage = InstalledVersions::getRootPackage();

            // TODO: refactor to a real method
            $getMinimumPhpVersionFromString = function(string $versionsString) use ($highestMinimumPhpVersion): string {
                if(0 < preg_match_all('/\d+(?:\.\d+)?(?:\.\d+)?/', $versionsString, $minimumPhpVersions )) {

                    $minimumPhpVersion = array_reduce( $minimumPhpVersions[0], function ( $carry, $minimumPhpVersion ) {
                        return version_compare( $minimumPhpVersion, $carry, '<' )
                            ? $minimumPhpVersion
                            : $carry;
                    }, $highestMinimumPhpVersion );
                } else {
                    $minimumPhpVersion = $highestMinimumPhpVersion;
                }
                return $minimumPhpVersion;
            };

            /**
             * "config": {
             *   "platform": {
             *     "php": "7.3.0"
             *   }
             * }
             */
            if ( isset( $rootPackage['config'], $rootPackage['config']['platform'], $rootPackage['config']['platform']['php'] ) ) {
                $minimumPhpVersion = $rootPackage['config']['platform']['php'];
            } elseif ( isset( $rootPackage['require'], $rootPackage['require']['php'] ) ) {
                /**
                 * {
                 *   "require": {
                 *     "php": ">=7.4"
                 *   }
                 * }
                 */
                $minimumPhpVersion = $getMinimumPhpVersionFromString($rootPackage['require']['php']);
            } else {
                // Scan all required packages for their minimum PHP version.

                $reflectionClass       = new \ReflectionClass( InstalledVersions::class );
                $installedVersionsPath = $reflectionClass->getFileName();

                $minimumPhpVersionsString = '';

                $installedJsonPath = \dirname($installedVersionsPath) . '/installed.json';
                if (\file_exists($installedJsonPath)) {
                    $installedJson = \json_decode(\file_get_contents($installedJsonPath), true);
                    if (isset($installedJson['packages'])) {
                        foreach ($installedJson['packages'] as $package) {
                            if (isset($package['require']['php'])) {
                                $minimumPhpVersionsString .= ' ' . $package['require']['php'];
                            }
                        }
                    }
                }

                $minimumPhpVersion = $getMinimumPhpVersionFromString($minimumPhpVersionsString);
            }
        } else {
            // Fallback to the highest minimum PHP version supported by php-parser
            $minimumPhpVersion = $highestMinimumPhpVersion;
        }

        // Should be 7.4 or higher. Where can that be found in php-parser?
        return version_compare($minimumPhpVersion, '7.4', '<') ? '7.4' : $minimumPhpVersion;
    }

Composer doesn't seem to expose the value it uses in platform-check.php but also, I don't think that file is always created.

Image

I'm really just dipping my toes in php-parser so far. I'll open a PR if this is a good idea. And if it's not, I look forward to better understanding the tool.

I'm using it in brianhenryie/strauss which to-date has been doing namespace replacements with regex, but regex is hitting its limits.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions