Problem/Motivation

We updated MINIMUM_PHP to 8.1.0 but left MINIMUM_SUPPORTED_PHP at 8.0.2. That makes no sense.

This is a Drupal 10 issue only.

Proposed resolution

Update MINIMUM_SUPPORTED_PHP to 8.1.0 and add a test to ensure it is greater than MINIMUM_PHP

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

alexpott created an issue. See original summary.

alexpott’s picture

Status: Active » Needs review
FileSize
952 bytes
3.86 KB
alexpott’s picture

Oops #2's patch had another one as well... fixing that.

longwave’s picture

Status: Needs review » Reviewed & tested by the community
+++ b/core/tests/Drupal/Tests/Core/DrupalTest.php
@@ -433,6 +433,14 @@ public function testAccessManager() {
+    $this->assertTrue((bool) version_compare(\Drupal::RECOMMENDED_PHP . '.0', \Drupal::MINIMUM_SUPPORTED_PHP, '>='), "\Drupal::RECOMMENDED_PHP should be greater or equal to \Drupal::MINIMUM_SUPPORTED_PHP");

This might not work if e.g. we recommend 8.1, but we need a minimum of 8.1.1 for a PHP bug fix. Still that's a hypothetical for now I guess, we can address that if it happens.

Otherwise +1 to the test for this to avoid getting it wrong again.

The last submitted patch, 2: 3266525-2.test-only.patch, failed testing. View results

alexpott’s picture

@longwave - good point. I made \Drupal::RECOMMENDED_PHP equal to 8.1.21 and \Drupal::MINIMUM_SUPPORTED_PHP equal to 8.1.43 and the patch attached failed as we'd hope. So let's fix that #4.

xjm’s picture

Priority: Normal » Major
Status: Reviewed & tested by the community » Needs review
+++ b/core/tests/Drupal/Tests/Core/DrupalTest.php
@@ -433,6 +433,16 @@ public function testAccessManager() {
+    // Recommended is often just MAJOR.MINOR so add a very high patch version in
+    // order to test that it is consistent with \Drupal::MINIMUM_SUPPORTED_PHP.
+    $this->assertTrue((bool) version_compare(\Drupal::RECOMMENDED_PHP . '.99', \Drupal::MINIMUM_SUPPORTED_PHP, '>='), "\Drupal::RECOMMENDED_PHP should be greater or equal to \Drupal::MINIMUM_SUPPORTED_PHP");

Not that I actually expect PHP to ever have a patch version of 99, but isn't this test technically only valid so long as the recommended PHP version is MAJOR.MINOR.98 or less?

Also, what if RECOMMENDED_PHP does contain a patch version? Then this becomes a four-part version like 8.1.0.99. version_compare() doesn't seem to fatal or anything for that, and Composer supports versions like that, but it's certainly not the expected behavior.

alexpott’s picture

If we do recommend a specific patch version is works as expected. I documented the fact I tested that in my previous comment.

And yeah I just chose a number they PHP will never reach as a patch version. I think it is safe to assume they won’t reach 99 patch releases.

xjm’s picture

If we do recommend a specific patch version is works as expected. I documented the fact I tested that in my previous comment.

Can we put this in the code comments though? (I still don't see where the issue says this. Edit: I'm pretty sure it doesn't.)

Also, I think the test could probably use .9999999999999 or something just to make it far less likely that the test will break? IIRC Composer or someone does similarly already. Still not ideal, but as a reminder Drupal 7 is on 80-something now so 99 is not outside the realm of possibility.

xjm’s picture

(Also there is an NPM package with a version of 1.0.30001271 in our dependency tree.)

xjm’s picture

Also it's possible for MINIMUM_SUPPORTED_PHP to only be two parts as well. See #3261447: Add an API for dynamically setting recommended and supported PHP versions based on known and predicted PHP release schedules which explicitly adds and tests that.

xjm’s picture

alexpott’s picture

Unfortunately there's nothing simple in Composer/Semver for us to use. So I've added an inline function to normalise the versions the way we'd like. I've also added a tiny test of that functionality just to be sure given a regex is involved.

Re testing what happens if RECOMMENDED_PHP has a patch version - I wrote in #6

I made \Drupal::RECOMMENDED_PHP equal to 8.1.21 and \Drupal::MINIMUM_SUPPORTED_PHP equal to 8.1.43 and the patch attached failed as we'd hope.

I guess I could have also noted that I swapped these around and it passed as expected.

I've used the number of 9's that composer seems to use everywhere. Note though that I'm pretty certain we'll never set the minimum, minimum_supported or recommend PHP version to 8.4.99 - given PHP's current release cadence that is inconceivable and given our own release cadence even if PHP was releasing at such a cadence we'd be struggling. The current one PHP minor per year is challenging enough for us :) Also even if PHP did release a .10000000 it would not affect the test. The tests would only be affected if we make a change to one of the constants being tested here and presently that requires a code change.

If/when #3261447: Add an API for dynamically setting recommended and supported PHP versions based on known and predicted PHP release schedules lands then that change will need to ensure the minimum, minimum_supported or recommend PHP versions can't ever be inconsistent.

daffie’s picture

Status: Needs review » Needs work

Patch looks good.

  1. +++ b/core/tests/Drupal/Tests/Core/DrupalTest.php
    @@ -433,6 +433,30 @@ public function testAccessManager() {
    +    $this->assertTrue((bool) version_compare($minimum_supported_php, \Drupal::MINIMUM_PHP, '>='), "\Drupal::MINIMUM_SUPPORTED_PHP should be greater or equal to \Drupal::MINIMUM_PHP");
    +    $this->assertTrue((bool) version_compare($recommended_php, \Drupal::MINIMUM_SUPPORTED_PHP, '>='), "\Drupal::RECOMMENDED_PHP should be greater or equal to \Drupal::MINIMUM_SUPPORTED_PHP");
    

    version_compare() return a boolean value when the $operator parameter is used, which we are doing here. Therefor "(bool)" can be removed.

  2. +++ b/core/tests/Drupal/Tests/Core/DrupalTest.php
    @@ -433,6 +433,30 @@ public function testAccessManager() {
    +    // RECOMMENDED_PHP and MINIMUM_SUPPORTED_PHP can be just MAJOR.MINOR so
    +    // normalize them so that version_compare() can be used.
    

    I cannot find where it is saying that MINIMUM_PHP must be of the type "Major.Minor.Patch". Can we add documentation for it and add a test that it is of the type "Major.Minor.Patch".

alexpott’s picture

Status: Needs work » Needs review
FileSize
1.29 KB
2.17 KB

Thanks for the review @daffie.

1. Fixed.
2. I think this is both out-of-scope and does not matter. If we set the minimum PHP to 9.1 and >=9.1 in composer.json this test would still work because https://3v4l.org/qLANS

daffie’s picture

Status: Needs review » Reviewed & tested by the community

My points have been addressed.
For me it is RTBC.

xjm’s picture

Status: Reviewed & tested by the community » Needs review
+++ b/core/tests/Drupal/Tests/Core/DrupalTest.php
@@ -433,6 +433,30 @@ public function testAccessManager() {
+      preg_match('{^(\d{1,5})(\.\d++)?(\.\d++)?$}i', $version, $matches);

Is there any specific reason we're constraining the major version to be between 1 and 5 digits? Because six nines is what Composer uses, or a different reason?

I mean, having PHP version 100,000 is even less likely than having version 8.0.99. :P But as-is the 1-5 digits seems like a magic number. It might be good for the inline comments to explain where the 5-digit limit comes from (and that the normalization pattern with its six nines are from Composer's own internal comparisons).

Outside that, the improved test looks great to me. (The interdiff in #13 is an inter-interdiff but I figured it out after only momentary confusion.) Thanks!

alexpott’s picture

I borrowed the regex from Composer - \Composer\Semver\VersionParser::normalize()

Specifically:

        // match classical versioning
        if (preg_match('{^v?(\d{1,5})(\.\d++)?(\.\d++)?(\.\d++)?' . self::$modifierRegex . '$}i', $version, $matches)) {
            $version = $matches[1]
                . (!empty($matches[2]) ? $matches[2] : '.0')
                . (!empty($matches[3]) ? $matches[3] : '.0')
                . (!empty($matches[4]) ? $matches[4] : '.0');
            $index = 5;
        // match date(time) based versioning
        }

Also given that we maintain all of the constants this test will only fail if we change the constants to values that fail. At that point we can fix the tests or fix the constants... whatever is correct. For that reason I'm not sure it is worth a comment.

xjm’s picture

It's just an inline comment. It's free. Documenting hardcoded integers is never a bad thing. Explaining why a test provides the specific coverage it does is never a bad thing. All it has to say is:
// The regex below is borrowed from \Composer\Semver\VersionParser::normalize().

...And we never have to wonder about it again.

(I'd add it myself but I'd prefer to be able to commit the patch.)

quietone’s picture

I could use a simple task today and saw this. Shortened the suggestion to be under 80 chars.

Status: Needs review » Needs work

The last submitted patch, 20: 3266525-20.patch, failed testing. View results

quietone’s picture

Status: Needs work » Needs review

Random failures. Setting to NR.

daffie’s picture

Status: Needs review » Reviewed & tested by the community

The point of the regex string has been addressed.
Back to RTBC.

catch’s picture

Status: Reviewed & tested by the community » Fixed

For me this is very much at the edge of things I would add a test for - we change these constants at most once or twice per year, usually a long time before tagging a release for the branch that changes them, and although we managed to get into a wrong state, it was picked up very quickly and easy to fix.

However, the test is already written and should stop this happening again, so..

Committed c2495d1 and pushed to 10.0.x. Thanks!

  • catch committed c2495d1 on 10.0.x
    Issue #3266525 by alexpott, quietone, xjm, daffie, longwave:...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.