Skip to content

Enforce PHP version at runtime to be same or higher as at "composer update" time #576

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 30, 2019
Merged

Enforce PHP version at runtime to be same or higher as at "composer update" time #576

merged 1 commit into from
Nov 30, 2019

Conversation

nicolas-grekas
Copy link
Member

@nicolas-grekas nicolas-grekas commented Nov 27, 2019

When e.g. PHP 7.3 is used to compute dependencies, here is the message that is now generated when running bin/console or symfony serve on PHP 7.1:

Fatal Error: composer.lock was created for PHP version 7.3 or higher but the current PHP version is 7.1.33.

We have too many reports on symfony/symfony about ppl that mess up with these.

It works by adding a simple static check in vendor/autoload.php.

Note that composer install already yells, so it's already covered.

Copy link

@Taluu Taluu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be on composer instead ?

@nicolas-grekas
Copy link
Member Author

Shouldn't this be on composer instead ?

I don't know, please open an issue on composer if you think so.
Flex can be more opinionated than composer, so here it is.

@nicolas-grekas nicolas-grekas changed the title Enforce PHP version at runtime to be same or higher as at "composer update" time Enforce PHP version at runtime to be same or higher at "composer update" time Nov 27, 2019
@nicolas-grekas
Copy link
Member Author

PR ready. I simplified the implementation a lot and the version og PHP is now dumped in symfony.lock (adding it to composer.lock doesn't work well).

@naderman
Copy link
Member

@nicolas-grekas Would be great if you could contribute this to Composer in a portable way (allow any php version acceptable by all packages in the lock file), rather than continue to add differences in flex that more or less turn it into a fork of Composer.

@nicolas-grekas
Copy link
Member Author

nicolas-grekas commented Nov 27, 2019

Would be great if you could contribute this to Composer in a portable way (allow any php version acceptable by all packages in the lock file)

You mean compiling the constraints of all packages into a single PHP inline expression?
I don't know how to do this. It looks like this would take way more time than what I can contribute here, thus the PR on Flex with a smaller scope.

continue to add differences in flex that more or less turn it into a fork of Composer.

I've been told by Jordi that the less composer-core has to maintain, the better it is for the project. That makes sense, moving things into plugins goes in this direction. I am not able to decide what might be needed for composer-core and what is not. Therefore, I contribute to flex, and the community can then migrate ideas (+code) to composer core.

That's the thermodynamics of OSS. Don't put more on my shoulders please :)

@Seldaek
Copy link
Member

Seldaek commented Nov 27, 2019

@nicolas-grekas I think this sounds like a great addition to Composer core, as it's a small patch and of use to most people, if you don't have time to do it that's fine.. But for the record I don't think I said that we don't want any contributions :) IMO some things are best done in plugins, if only as a more flexible testing ground. If things prove useful we can then add to core. But once things are in core it's very very hard to remove/change anything, so yeah I tend to be cautious.

Anyway if you want to keep this here for now feel free, or if you or someone else wants to submit it to composer with the changes suggested in https://twitter.com/naderman/status/1199725101542981634 that'd be even better. If nobody steps up I'll try to when I get a chance.

@nicolas-grekas
Copy link
Member Author

nicolas-grekas commented Nov 27, 2019

I don't think I said that we don't want any contributions :)

that's not what I said either ;)

The plan looks good:

  1. we merge this in flex so that this can be propagated to the community very fast - might trigger interesting feedbacks also,
  2. then composer adds this simple logic in core, no more,
  3. last step would be to generate a PHP expression for the set of constraints coming from packages.

I don't know if 3. is needed at all: it might give little benefits compared to the effort required to achieve it. That's my feeling at least. 2. would totally make sense, PR welcome on composer if anyone is reading :)

@naderman
Copy link
Member

@nicolas-grekas I don't think we necessarily need a full expression, I would just calculate the lowest version number acceptable for all packages, rather than rely on what was used to run the update, anyway I'll see if I can quickly put together the calculation for that.

@naderman
Copy link
Member

Having looked at this a bit more it does indeed seem like it's not easy even to just get a a lowest common denominator from the current semver lib, would need to expand the constraints/multi-constraints a bit to provide that. So entirely agree with your plan, I added an issue on the composer repo to implement this and can add any feedback you collect with flex there too then: composer/composer#8451 and on the semver lib: composer/semver#71 and composer/semver#72

I think especially the latter two would be an interesting challenge for a new contributor if someone wants to try working on those!

@pierrejoye
Copy link

If one builds on one php deploy to a target using different php? I think it is why it cannot be done by composer only.

@nicolas-grekas nicolas-grekas changed the title Enforce PHP version at runtime to be same or higher at "composer update" time Enforce PHP version at runtime to be same or higher as at "composer update" time Nov 28, 2019
@nicolas-grekas
Copy link
Member Author

If one builds on one php deploy to a target using different php? I think it is why it cannot be done by composer only.

that's supported only if config.platform.php sticks to a specific minor version. Otherwise, there will be a transitive deps mismatch (eg build on PHP 7.2 get SF5 components, deploy on 7.1 get a fatal error).

This takes config.platform.php into account and allows computing the deps on 7.1 and deploying on 7.2.

@beberlei
Copy link

Just realized that this approach is not bulletproof, since you can composer install with one version and then just composer dump:autoload with another version. This case is actually whats happening to me for our integration test suite of a PHP extension.

@nicolas-grekas
Copy link
Member Author

@beberlei WDYM? Where is the issue with this process? When the update is computed, the version of PHP used at the time is stored in symfony.lock. Then, the dump-autoload will preserve that version in the generated autoload file, so the safeguard will still be correct.

Or do you mean something else?

@beberlei
Copy link

@nicolas-grekas ah thats right then, i am not too deep into flex and symfony.lock, i assumed it was based on how Composer autoload generator works. Ignore my comment then please :)

@fabpot
Copy link
Member

fabpot commented Nov 30, 2019

Thank you @nicolas-grekas.

fabpot added a commit that referenced this pull request Nov 30, 2019
…t "composer update" time (nicolas-grekas)

This PR was merged into the 1.4-dev branch.

Discussion
----------

Enforce PHP version at runtime to be same or higher as at "composer update" time

When e.g. PHP 7.3 is used to compute dependencies, here is the message that is now generated when running `bin/console` or `symfony serve` *on PHP 7.1*:

```
Fatal Error: composer.lock was created for PHP version 7.3 or higher but the current PHP version is 7.1.33.
```

We have too many reports on symfony/symfony about ppl that mess up with these.

It works by adding a simple *static* check in `vendor/autoload.php`.

Note that `composer install` already yells, so it's already covered.

Commits
-------

e39f329 Enforce PHP version at runtime to be same or higher as at "composer update" time
@fabpot fabpot merged commit e39f329 into symfony:master Nov 30, 2019
@nicolas-grekas nicolas-grekas deleted the lock-php-version branch November 30, 2019 13:33
@@ -653,6 +662,36 @@ public function generateFlexId()
$this->updateComposerLock();
}

private function updateAutoloadFile()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't this be hooked into POST_AUTOLOAD_DUMP instead so that it is still applied when using dump-autoload ?

nicolas-grekas added a commit that referenced this pull request Dec 13, 2019
This PR was squashed before being merged into the 1.5-dev branch.

Discussion
----------

compare data before marking lock as changed

In #479 I tried to fix the issue #379 by introducing a _changed_ flag to the Lock.

This patch worked for a few months. However, introducing #576 broke the patch by [always calling](https://github.com/symfony/flex/pull/576/files#diff-46b78198ae7ea525f04268205dd782c3R273) `set` ending in the same situation as before.

Blame on me for not checking if anything differs before setting the _changed_ flag. This PR tries to do better.

Commits
-------

bc400be compare data before marking lock as changed
fabpot added a commit that referenced this pull request Jan 27, 2020
This PR was merged into the 1.5-dev branch.

Discussion
----------

Update autoload.php on POST_AUTOLOAD_DUMP

As reported by @stof in #576 (comment)

Commits
-------

7a9319a Update autoload.php on POST_AUTOLOAD_DUMP
@VincentLanglet
Copy link

@nicolas-grekas would it be possible to have an option/a way to disable this behaviour ?

Our team use a vagrant in php 7.4 to run composer and the application, but need to run some php hooks/scripts in local environment. Developers has different php versions (from 7.1 to 7.3) in local environnement so they can't run the hooks/scripts anymore.

config.platform.php: 7.1 can fix this issue but has impact since the library downloaded are sub-optimal and we prefer to keep using 7.4-php-library.

The same way there is an option :

"extra": {
        "symfony": {
            "allow-contrib": true
        }
    }

an option strict-php-version, default to true would be great.

@nicolas-grekas
Copy link
Member Author

@VincentLanglet then use config.platform.php: 7.4, this works on PHP 7.1 too.

@VincentLanglet
Copy link

VincentLanglet commented Feb 6, 2020

@VincentLanglet then use config.platform.php: 7.4, this works on PHP 7.1 too.

@nicolas-grekas I'm not sure to understand. Maybe I need to precise that we always run composer install in our vagrant and then the vendor are shared between our vagrant and our local.

So when I use config.platform.php: 7.4 in my composer.json
After a composer install in our vagrant we get

if (\PHP_VERSION_ID < 70400) {
    echo sprintf("Fatal Error: composer.lock was created for PHP version 7.4 or higher but the current PHP version is %d.%d.%d.\n", PHP_MAJOR_VERSION, PHP_MINOR_VERSION, PHP_RELEASE_VERSION);
    exit(1);
}

So we can't run the script in local

If I use config.platform.php: 7.1 in my composer.json
After a composer install in our vagrant we get

if (\PHP_VERSION_ID < 70100) {
    echo sprintf("Fatal Error: composer.lock was created for PHP version 7.1 or higher but the current PHP version is %d.%d.%d.\n", PHP_MAJOR_VERSION, PHP_MINOR_VERSION, PHP_RELEASE_VERSION);
    exit(1);
}

So we can run the script in local, but the library installed are sub-optimal for the vagrant and the production.

With the initial behaviour (no check for the php version in the autoloader) we could have library for 7.4 and running script in a local 7.1 environnement.

nicolas-grekas added a commit that referenced this pull request Sep 21, 2021
This PR was squashed before being merged into the 1.13-dev branch.

Discussion
----------

removed unnecessary code

Fixes #775

Removed code that was implemented in #576 as this is no longer needed as per the issue reported.

First PR in this repository. Hoping to contribute to more! If there are any issues, let me know.

Commits
-------

74117fb removed unnecessary code
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.