[PP-1] core.extension should be validatable

Created on 20 March 2024, about 1 year ago

Problem/Motivation

Over at 🐛 Install profile is disabled for lots of different reasons and core doesn't allow for that Fixed , the schema for core.extension:profile is being refined.

Once that lands, we'll be able to make it validatable too, and make the entire config object validatable!

Conversation that triggered this issue to be created:

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

📌 Task
Status

Postponed

Version

11.0 🔥

Component
Base 

Last updated about 9 hours ago

Created by

🇧🇪Belgium wim leers Ghent 🇧🇪🇪🇺

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @wim leers
  • Merge request !7107Outline what needs to happen here. → (Closed) created by wim leers
  • Issue was unassigned.
  • 🇧🇪Belgium wim leers Ghent 🇧🇪🇪🇺

    Draft MR created.

  • 🇧🇪Belgium wim leers Ghent 🇧🇪🇪🇺
  • Pipeline finished with Failed
    about 1 year ago
    Total: 177s
    #124087
  • 🇬🇧United Kingdom alexpott 🇪🇺🌍
  • 🇧🇪Belgium wim leers Ghent 🇧🇪🇪🇺

    Closed 📌 Improve core.extension:profile validation Postponed as a duplicate. Crediting @alexpott.

  • Status changed to Active about 1 year ago
  • Pipeline finished with Failed
    about 1 year ago
    Total: 165s
    #125256
  • Pipeline finished with Failed
    about 1 year ago
    Total: 487s
    #125262
  • Status changed to Needs review about 1 year ago
  • 🇧🇪Belgium wim leers Ghent 🇧🇪🇪🇺
  • Pipeline finished with Failed
    about 1 year ago
    Total: 184s
    #125286
  • Status changed to Needs work about 1 year ago
  • The Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".

    This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

    Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

  • 🇮🇳India kunal.sachdev

    kunal.sachdev made their first commit to this issue’s fork.

  • Pipeline finished with Failed
    12 months ago
    Total: 179s
    #184758
  • Pipeline finished with Failed
    12 months ago
    Total: 266s
    #184796
  • Pipeline finished with Failed
    11 months ago
    Total: 263s
    #191502
  • Pipeline finished with Failed
    11 months ago
    Total: 574s
    #191509
  • 🇮🇳India kunal.sachdev

    Most tests are failing because in TestBase setup() we do

    $this->container->get('theme_installer')->install(['stark']);
    

    and in ThemeInstaller we have

    $extension_config
            ->set("theme.$key", 0)
            ->save(TRUE);
    

    which also tries to validate the config and it breaks for ExtensionExistsContraint with error message 'Theme stark is not installed', which is true. I think we could add a check in ThemeInstaller before saving the key in the config, something like this-

    if (!isset($installed_themes[$key])) {
            $extension_config
            ->set("theme.$key", 0)
            ->save(TRUE);
     }
    

    , but I am not really sure about this.

  • 🇮🇳India kunal.sachdev
    • @phenaproxima thinks that ExtensionExists constraint doesn't make a ton of sense for core.extension see ( 3441503-#18 📌 Add validation constraints to system.theme Needs work ) for more details.
    • Also discussed this with @phenaproxima in slack and concluded that if we want to use ExtensionExists constraint for core.extension then ExtensionExistsConstraintValidator should be completely refactored and use the ModuleExtensionList and ThemeExtensionList, which can report on existing-but-not-yet-installed things.
  • Pipeline finished with Failed
    11 months ago
    Total: 602s
    #202678
  • Pipeline finished with Failed
    11 months ago
    #203544
  • Pipeline finished with Failed
    11 months ago
    Total: 571s
    #203550
  • Pipeline finished with Failed
    11 months ago
    Total: 597s
    #203574
  • Pipeline finished with Failed
    11 months ago
    Total: 476s
    #208437
  • Pipeline finished with Failed
    11 months ago
    Total: 566s
    #210465
  • Pipeline finished with Failed
    11 months ago
    Total: 483s
    #210505
  • 🇮🇳India yash.rode pune

    yash.rode made their first commit to this issue’s fork.

  • Pipeline finished with Success
    10 months ago
    Total: 540s
    #221448
  • Status changed to Needs review 10 months ago
  • 🇮🇳India yash.rode pune

    Tests are passing now

  • Pipeline finished with Success
    10 months ago
    Total: 1171s
    #224663
  • 🇧🇪Belgium borisson_ Mechelen, 🇧🇪

    I feel that ExtensionExists should be whether the extension exists and we should have a separate constraints - the other constraint should be called ExtensionInstalled. However this is unfortunate because we already have ExtensionExists and it's current meaning is that it is installed.

    Not sure what to do.

    This is a difficult question. In my opinion ExtensionExists/ExtensionInstalled makes sense, but renaming this and after that reusing the name for the other meaning is difficult. Can we use ExtensionPresent to indicate that should be present on the file system?

  • Status changed to Needs work 8 months ago
  • 🇺🇸United States smustgrave

    Believe this needs work for the feedback mentioned in #16? Also is MR 7107 needed anymore?

  • 🇳🇱Netherlands bbrala Netherlands

    ModuleHandler already uses exists to check for installed. So the naming is kinda consistend.

    If we need to seperate why now;

    ExtentionAvailable, which would be consistent with things like; 'update available' or perhaps 'moduel available to install'. Doesn't feel that weird to me.

  • 🇧🇪Belgium borisson_ Mechelen, 🇧🇪

    ExtentionAvailable makes a lot of sense to me.

  • Pipeline finished with Canceled
    about 1 month ago
    Total: 64s
    #465338
  • 🇳🇱Netherlands bbrala Netherlands

    Extracted the validator so naming makes sense. Split tests also and did a rebase so we run the right tests.

  • Pipeline finished with Failed
    about 1 month ago
    Total: 287s
    #465340
  • Pipeline finished with Failed
    about 1 month ago
    Total: 222s
    #465347
  • 🇺🇸United States smustgrave

    Latest MR appears to have pipeline issues. Can 1 MR be closed or hidden also to make it super clear what should be reviewed

  • 🇳🇱Netherlands bbrala Netherlands

    Oops, thanks, juggling a lot of issues, will cycle back.

  • 🇳🇱Netherlands bbrala Netherlands

    Closed MR, and fixed phpstan issue.

  • Pipeline finished with Success
    about 1 month ago
    Total: 383s
    #465612
  • 🇺🇸United States smustgrave

    Left 1 question and 1 comment on the MR.

  • 🇳🇱Netherlands bbrala Netherlands

    Did all the promotions, time to go home :)

  • Pipeline finished with Failed
    about 1 month ago
    Total: 127s
    #465732
  • 🇳🇱Netherlands bbrala Netherlands

    all failures unrelated.

  • 🇺🇸United States smustgrave

    Using config inspector I see we are at 100% now.

    Believe all feedback has been addressed

  • Pipeline finished with Failed
    about 1 month ago
    Total: 3205s
    #465739
  • 🇳🇱Netherlands bbrala Netherlands

    rebased, only to see if the unrelated failures have been fixed.

  • Pipeline finished with Success
    about 1 month ago
    Total: 885s
    #468590
  • Pipeline finished with Success
    about 1 month ago
    Total: 672s
    #468955
  • 🇬🇧United Kingdom alexpott 🇪🇺🌍

    The big issue left is the new constraint - left a big comment on the MR.

  • Pipeline finished with Failed
    about 1 month ago
    #469181
  • Pipeline finished with Success
    about 1 month ago
    #469187
  • 🇳🇱Netherlands bbrala Netherlands

    Struggling with the datadefiniotion to test. Giving up for now. :)

  • Pipeline finished with Failed
    about 1 month ago
    Total: 534s
    #470421
  • 🇳🇱Netherlands bbrala Netherlands

    That took a while, this typed data is a rollercoaster :x

    Think i have working tests now prooving stuff works. Yay!

  • 🇳🇱Netherlands bbrala Netherlands
  • 🇳🇱Netherlands bbrala Netherlands

    Next up, see if it can be rewritten to use the Composite constraint.

  • Pipeline finished with Success
    about 1 month ago
    Total: 6126s
    #470488
  • 🇳🇱Netherlands bbrala Netherlands

    Not sure who made ExtensionNameConstraint but that message is useless. "The value is not valid.". That could easily be something more sane :x

  • Pipeline finished with Failed
    about 1 month ago
    Total: 151s
    #470593
  • Pipeline finished with Failed
    about 1 month ago
    Total: 420s
    #470594
  • 🇳🇱Netherlands bbrala Netherlands

    Test are running, but im quite confident they will end up green.

    Added __clone to ExecutionContext since that makes it possible to collect messages and then combine them in the original context (see 📌 Remove the restriction from RecursiveContextualValidator that prevents using custom groups. Needs review where that is also used for AtLeastOneOf)

  • Pipeline finished with Success
    about 1 month ago
    Total: 501s
    #470601
  • Pipeline finished with Failed
    about 1 month ago
    Total: 273s
    #470832
  • Build has PHPCS issue. Also added some comments to the MR.

  • 🇳🇱Netherlands bbrala Netherlands

    Than you so much for the review :)

  • Pipeline finished with Failed
    about 1 month ago
    Total: 189s
    #471780
  • Pipeline finished with Failed
    about 1 month ago
    Total: 113s
    #471781
  • Pipeline finished with Canceled
    about 1 month ago
    Total: 114s
    #471783
  • Pipeline finished with Canceled
    about 1 month ago
    Total: 92s
    #471784
  • Pipeline finished with Failed
    about 1 month ago
    Total: 133s
    #471785
  • Pipeline finished with Failed
    about 1 month ago
    Total: 462s
    #471787
  • Pipeline finished with Failed
    about 1 month ago
    Total: 338s
    #471796
  • Pipeline finished with Success
    about 1 month ago
    Total: 843s
    #471800
  • 🇳🇱Netherlands bbrala Netherlands

    Went through your (thorough) review, this made the a few things way better. I have a response to two of your suggestions which i think might have issues if we do that.

  • Pipeline finished with Failed
    27 days ago
    Total: 191s
    #476489
  • 🇳🇱Netherlands bbrala Netherlands

    I think i adressed the last comment and made it quite a bit simpler code.

  • 🇳🇱Netherlands bbrala Netherlands
  • Pipeline finished with Success
    27 days ago
    Total: 625s
    #476493
  • The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".

    This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

    Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

  • Pipeline finished with Success
    26 days ago
    Total: 687s
    #477142
  • 🇳🇱Netherlands bbrala Netherlands
  • 🇧🇪Belgium borisson_ Mechelen, 🇧🇪

    2 additional remarks.

  • Pipeline finished with Failed
    19 days ago
    Total: 124s
    #482239
  • 🇳🇱Netherlands bbrala Netherlands

    Think i addressed all feedback

  • 🇳🇱Netherlands bbrala Netherlands
  • 🇧🇪Belgium borisson_ Mechelen, 🇧🇪

    Looks great!

  • Pipeline finished with Success
    17 days ago
    Total: 598s
    #483672
  • 🇬🇧United Kingdom alexpott 🇪🇺🌍

    We need to address the comment I've just added to the MR... there's a very very awkward thing with profiles. In fact the comment does not quite cover the complexity here. I think we need to detect if the profile is changing and if it is we need to rebuild the module and theme validators as this alters what modules and themes can be discovered.

  • 🇬🇧United Kingdom alexpott 🇪🇺🌍

    Changing the install profile on an existing site is a little fraught. Things have change so that you can uninstall an install profile if you are not using any themes or modules that only exist in the install profile - see \Drupal\Core\Extension\InstallProfileUninstallValidator.

    We could consider changing an install profile to another install profile to be an invalid change and only allow it to be cleared. Hmmm. Not sure.

  • 🇧🇪Belgium borisson_ Mechelen, 🇧🇪

    Asked for more clarification in the MR comment (and now posted here as well, so that this issue goes back to unread).

  • 🇳🇱Netherlands bbrala Netherlands

    Lets start by saying, i dont know much about the systems in play here ;)

    Hmm, so my first thought would be that it should do discovery without any cache, but ending up at that not being really a thing. Lets see if i understand correctly.

    We need to validate the extention, BUT, since profile is also changed it might have different modules available. So even if we say; when the profile changes, we reload the list or rescan for available modules. BUT this validation is before the changes have persisted. So it gets worse, in the fact that it needs to scan for the future situation.

    In my head i have a few options;

    1. Make an extended version of this validator that also checks for value of profile, use that to check if the value has changed, if so, do a clean discovery of the available modules and use that for validation.
    2. Use your suggestion that allows for modules that are also profile to be installed. But that could lead to trying to install a module that is name as a profile efven though it doesnt exist?
    3. Don't allow profile changes, but that seems kinda hard.
  • 🇬🇧United Kingdom alexpott 🇪🇺🌍

    Re profile changes - we already only really allow the profile to be set by the installer and unset though module uninstallation after checking the modules - see \Drupal\Core\Extension\InstallProfileUninstallValidator. In any real way we don't actually support making changes to core.extension directly via config tools. So the test that I've commented on is pretty funky. I do think that 1 is probably the best solution for module and theme validation. I.e if the profile has changed use a fresh discovery object. Wrt. to enforcing install profile change rules... I'm not sure. I guess we can leave it alone until it causes us problems.

  • 🇳🇱Netherlands bbrala Netherlands

    "I'm not sure. I guess we can leave it alone until it causes us problems."

    Not sure what you mean with leaving it alone. Ignore the weird test case where profile is changed and module is changed?

  • 🇬🇧United Kingdom alexpott 🇪🇺🌍

    Re

    "I'm not sure. I guess we can leave it alone until it causes us problems."

    What I mean is we can ignore trying to validate profile beyond a profiles existence for now. I think we should not be changing that test in this issue. The fact we are shows we've got stuff to fix.

  • 🇳🇱Netherlands bbrala Netherlands

    Think i might've found a way by adding special case for core.extension. Lets see how tests go.

  • Pipeline finished with Failed
    16 days ago
    Total: 727s
    #483953
  • 🇳🇱Netherlands bbrala Netherlands

    Form slack

    alexpott
      16 minutes ago
    Yeah but it doesn’t work
    
    
    
    
    4:53
    The problem is profile supplied modules
    4:53
    Changing a profile changes which directories module and theme discovery looks in (edited) 
    
    
    bbrala
      15 minutes ago
    Oh yeah
    
    
    alexpott
      15 minutes ago
    The install profile setting is a fundemental setting that is extremely powerful.
    
    
    bbrala
      14 minutes ago
    Grmbl, ok back to the drawing board.
    This wouls fail when there is an eztention that would only become available when the profile is loaded. Right?
    
    
    alexpott
      14 minutes ago
    Yes
    4:56
    We need to detect profile change and then use fresh extension discovery objects with the correct profile directory in the constructor.  In this case we can not use the discovery from the container because we need to look at what will happen when the install profile is changing.
    4:57
    Also just for fun you’ll have to cope with the case when the install profile value is being unset. Because this is actually the only change possible via the UI or API.
    4:58
    And by API I mean the module install API - the direct config API should not really be used for core.extension.
    
    
    bbrala
      10 minutes ago
    Guess i'll start designing 2 tests for that then. Should be able to reuse some other profile for that.
    
    
    alexpott
      7 minutes ago
    Well this test is a test of sorts…  testing is hard because we also allow stuff in test land that’s not normally allowed… see \Drupal\Tests\drupal_system_listing_compatible_test\Kernel\SystemListingCrossProfileCompatibleTest
    
    
    bbrala
      6 minutes ago
    Hmm ok
    5:05
    Ok, then i'll just go back to my first idea, and indeed find out how to reload/reinstantiate the *ExtentionList with the changed profile if applicable and validate against that.
    5:06
    New root, and no cache i'd assume.
    5:08
    and install profile it seems
    
    
    alexpott
      1 minute ago
    I think that that is way to go. I don’t think relaod/reinstantiate… just instantiate… see \Drupal\Core\Extension\InstallProfileUninstallValidator::getExtensionDiscovery
    5:08
    I think using file cache / info parser is fine tbh.
    
    
    bbrala
      Just now
    thanks, that helps. Feels like it is possible :slightly_smiling_face:
    
  • 🇳🇱Netherlands bbrala Netherlands

    Lets see how this works when we forcefully reinstantiate the discovery mechanisms.

  • Pipeline finished with Failed
    16 days ago
    Total: 145s
    #483999
  • Pipeline finished with Failed
    16 days ago
    Total: 145s
    #484003
  • 🇳🇱Netherlands bbrala Netherlands

    If this works, i think i will split it into a seperate constraint maybe. Since then we could just instantiate the new ExtentionList classes every time instead of doing the check. Which would also mean i can just inject the services in the create method with having loads of extra services in the ExtensionAvailableValidator

  • Pipeline finished with Failed
    16 days ago
    Total: 718s
    #484008
  • Pipeline finished with Canceled
    16 days ago
    Total: 194s
    #484106
  • Pipeline finished with Success
    16 days ago
    Total: 1174s
    #484108
  • Pipeline finished with Canceled
    16 days ago
    Total: 131s
    #484139
  • Pipeline finished with Canceled
    16 days ago
    Total: 191s
    #484142
  • Pipeline finished with Failed
    16 days ago
    Total: 619s
    #484143
  • Pipeline finished with Failed
    16 days ago
    Total: 838s
    #484154
  • Pipeline finished with Failed
    16 days ago
    Total: 696s
    #484166
  • 🇳🇱Netherlands bbrala Netherlands

    Those services were a little involved to instantiate. Pulling in a lot of stuff from the container. I could then remove the test changes, but i did need to update a theme test that was loading a module from a profile that is not installed.

    Think this is working as expected now thanks to the guidance of alex.

  • 🇧🇪Belgium borisson_ Mechelen, 🇧🇪

    but i did need to update a theme test that was loading a module from a profile that is not installed.

    Does this signal the need for an upgrade path, or is this because we do weird things with the testing profile?

  • 🇳🇱Netherlands bbrala Netherlands

    This signals the test is trying to set a module from outside its installed profile. Should be a weirdness with the teatsetup as talked about with alex

  • 🇧🇪Belgium borisson_ Mechelen, 🇧🇪
  • 🇬🇧United Kingdom alexpott 🇪🇺🌍

    The current approach is not going to work unfortunately. Because the ExtensionList objects interact with state and cache so we're in danger of affected the live running of a site if we validate a core.extension object prior to it being changed. I think we have to follow InstallProfileUninstallValidator's example and use a lower level ExtensionDiscovery object to determine if modules and themes exist if the profile has changed.

  • 🇳🇱Netherlands bbrala Netherlands

    Ok fair enough.

  • Pipeline finished with Failed
    15 days ago
    Total: 133s
    #485428
  • Pipeline finished with Failed
    15 days ago
    Total: 524s
    #485436
  • Pipeline finished with Failed
    15 days ago
    Total: 702s
    #485513
  • Pipeline finished with Canceled
    15 days ago
    Total: 241s
    #485530
  • Pipeline finished with Failed
    15 days ago
    Total: 161s
    #485533
  • Pipeline finished with Failed
    15 days ago
    Total: 405s
    #485552
  • Pipeline finished with Failed
    14 days ago
    Total: 129s
    #485813
  • Pipeline finished with Success
    14 days ago
    Total: 494s
    #485819
  • 🇳🇱Netherlands bbrala Netherlands

    Updated to propere extension discovery.

    Had to add a testing env check because there are different rules there what modules you can install :(

    All good now i think (and green tests)

  • Pipeline finished with Canceled
    14 days ago
    Total: 323s
    #486536
  • Pipeline finished with Canceled
    14 days ago
    Total: 262s
    #486540
  • 🇬🇧United Kingdom alexpott 🇪🇺🌍

    There's a little bit more we need to cope with.

    We need to test what happens when the profile is NULL - that’s the starting state. And when it is complete removed - that’s what happens when the install profile is uninstalled.

    In the case that the profile is not set I think we'll need to set the directories to something that cannot exist - like we do in \Drupal\Core\Extension\InstallProfileUninstallValidator::getExtensionDiscovery

    Also I think that \Drupal\Core\Extension\Plugin\Validation\Constraint\ExtensionAvailableConstraintValidator::$extensionDiscovery should be an array of extension discoveries keyed by profile as this is easy to reason about. !in_array($profile, $this->extensionDiscovery->getProfileDirectories()) looks interesting and fragile.

  • Pipeline finished with Failed
    14 days ago
    Total: 590s
    #486543
  • Pipeline finished with Failed
    13 days ago
    Total: 254s
    #486876
  • Pipeline finished with Canceled
    13 days ago
    Total: 80s
    #486877
  • Pipeline finished with Failed
    13 days ago
    Total: 176s
    #486880
  • Pipeline finished with Success
    13 days ago
    Total: 5708s
    #486886
  • 🇳🇱Netherlands bbrala Netherlands
  • 🇳🇱Netherlands bbrala Netherlands

    Added tests for different situations and verfied install_proffile parameter is all types we discussed. Unfortunately i couldnt get unit tests working, so ended up added an extra method to disable the fact it is inside a test.

Production build 0.71.5 2024