Problem/Motivation

If a module's hook_requirements() returns an error during the install phase, it is supposed to show an error message and return to the modules page.

When installing an experimental module, an extra confirmation form is added, warning about the fact that it's experimental.

When installing an experimental with a requirements error, you get both!

Thankfully the "Continue" button is a no-op, and you end back on the modules page.
But this is very confusing and scary.

Proposed resolution

Ensure the error takes precedence and the confirmation step doesn't happen.

Remaining tasks

User interface changes

API changes

Data model changes

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

tim.plunkett created an issue. See original summary.

alexpott’s picture

Version: 8.3.x-dev » 8.2.x-dev
Status: Active » Needs review
FileSize
2.55 KB
3.26 KB

Here's a test and a fix.

alexpott’s picture

tim.plunkett’s picture

Status: Needs review » Reviewed & tested by the community
  1. +++ b/core/modules/system/src/Form/ModulesListForm.php
    @@ -411,6 +411,7 @@ protected function buildModuleList(FormStateInterface $form_state) {
    +        unset($modules['experimental'][$module]);
    

    I came up with the same fix locally, +1!

  2. +++ b/core/modules/system/tests/modules/experimental_module_requirements_test/experimental_module_requirements_test.install
    @@ -0,0 +1,19 @@
    + * Experimental Test Requirements module to test the Core (Experimental)
    + * package.
    

    80 chars. Maybe just "Module to test..."?

  3. +++ b/core/modules/system/tests/modules/experimental_module_requirements_test/experimental_module_requirements_test.install
    @@ -0,0 +1,19 @@
    +    ]
    

    Missing trailing comma

Those could be fixed on commit. Ran the tests locally and failed/passed as expected.

alexpott’s picture

@tim.plunkett thanks for the review.

The last submitted patch, 2: 2833462-2.test-only.patch, failed testing.

The last submitted patch, 2: 2833462-2.patch, failed testing.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 5: 2833462-5.patch, failed testing.

alexpott’s picture

InstallUninstallTest you are a fun one :)

The last submitted patch, 9: 2833462-8.test-only.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 9: 2833462-8.patch, failed testing.

alexpott’s picture

Status: Needs work » Needs review
FileSize
3.89 KB
2.45 KB

Okay now for real. Just making the module hidden.

alexpott’s picture

Wrong .info.yml file... omg.

The last submitted patch, 12: 2833462-12.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 13: 2833462-13.patch, failed testing.

tim.plunkett’s picture

Experimental modules are denoted via the package
Testing modules are also denoted via the package

Therefore, you cannot have an experimental test module.

The solution was to use hidden: true to fake the testing part.

But then it's not in the UI to enable, making it untestable.

Berdir’s picture

Experimental modules are denoted via the package
Testing modules are also denoted via the package

I'd love to see an explicit experimental: true flag in info.yml, so that contrib can have experimental modules too.

Testing modules are usually identified by being in a /tests/.. path, I think that test is the only thing that does the package test, maybe we should change that? Testing modules used to be hidden before we added the logic about not parsing /tests/ for modules unless a certain flag is set. Which is obviously set while running tests.

tim.plunkett’s picture

Something else is hiding experimental test modules, because we already have one!
experimental_module_test is a module, and it certainly doesn't show up on the modules page.

Interdiff against #9

The only thing we needed is a hook_help, borrowed from experimental_module_test.

alexpott’s picture

Status: Needs work » Reviewed & tested by the community

\Drupal\Core\Extension\Discovery\RecursiveExtensionFilterIterator::acceptTests() is responsible for the experimental modules not being displayed. #18 looks good.

alexpott’s picture

@xjm noticed a few things on review.

  • xjm committed 37c07a7 on 8.3.x
    Issue #2833462 by alexpott, tim.plunkett, Berdir: hook_requirements($...
xjm’s picture

  1. I'd love to see an explicit experimental: true flag in info.yml, so that contrib can have experimental modules too.

    I'm also totally in favor of this; we discussed it for somewhere. I noticed that there is already a "Chaos Tools Suite (Experimental)" package to try to accomplish the same thing we do for core, but of course it does not provide the requirements warning and confirmation that core does.I thought there was an existing issue for it but it does not seem to be listed on #2649768: [meta] No definition of "Experimental" & not nearly enough warning at least. So let's explore that in a followup. (Using the package name alone was the minimum hack we could do to get it working in the last months before 8.0.0 without any API change/addition).

  2. Testing modules are usually identified by being in a /tests/.. path, I think that test is the only thing that does the package test, maybe we should change that? Testing modules used to be hidden before we added the logic about not parsing /tests/ for modules unless a certain flag is set. Which is obviously set while running tests.

    I also ran into this when adding the experimental module confirm form. At the time, I think I investigated why the test used the "Testing" package name instead of "test" in the path or another strategy . This dates back to #1871328: Modules in new Multilingual package are no longer tested by Module\EnableDisableTest. Before the issue that introduced that regression, there was only the core package and the testing package, and the testing profile and test module discovery had not been introduced yet.

    That said, though, when I was working on #2649768: [meta] No definition of "Experimental" & not nearly enough warning I did rely on on InstallUninstallTest to also provide test coverage for the experimental modules. So if we change InstallUninstallTest to skip them, we should also make sure that there is other coverage for the cases in that test.

    TLDR, also followup material.

  3. +++ b/core/modules/system/src/Tests/Module/ExperimentalModuleTest.php
    @@ -120,6 +120,14 @@ public function testExperimentalConfirmForm() {
    +    \Drupal::state()->set('experimental_module_requirements_test_requirements', TRUE);
    +    $edit = [];
    +    $edit["modules[Core (Experimental)][experimental_module_requirements_test][enable]"] = TRUE;
    +    $this->drupalPostForm('admin/modules', $edit, 'Install');
    +    $this->assertUrl('admin/modules', [], 'If the module can not be installed we are not taken to the confirm form.');
    +    $this->assertText('The Experimental Test Requirements module can not be installed.');
    
    +++ b/core/modules/system/tests/modules/experimental_module_requirements_test/experimental_module_requirements_test.install
    @@ -0,0 +1,20 @@
    +  if (\Drupal::state()->get('experimental_module_requirements_test_requirements', FALSE)) {
    

    I asked @tim.plunkett why we are using this state check when we only explicitly test the TRUE case. This is because of the above bit where InstallUninstallTest skips the testing package, but experimental test modules can't be in the testing package because they are in the experimental package.

    I thought of asking for an inline comment in case someone else had the same question, but it's not worth it for a test module IMO. After all, if someone tries to remove this, InstallUninstallTest will explain itself by failing. ;)

  4. I manually tested this patch both with an experimental module that failed requirements, with a "contrib" module that depended on said requirement-failing experimental module, and then both cases where the experimental module also met requirements. In each case, the patch worked as expected.

I committed this to 8.3.x, but we are in a commit freeze at the moment on 8.2.x, so leaving RTBC for backport tomorrow.

Thanks everyone!

  • xjm committed a386354 on 8.2.x
    Issue #2833462 by alexpott, tim.plunkett, Berdir: hook_requirements($...
xjm’s picture

Status: Reviewed & tested by the community » Fixed

Backported to 8.2.x. Thanks!

Status: Fixed » Closed (fixed)

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