Create a PreApply validator that prevents Drupal projects from being removed if they are enabled

Created on 10 April 2023, almost 2 years ago
Updated 21 April 2023, almost 2 years ago

Problem/Motivation

Since Composer has no knowledge of what Drupal projects are and if they installed, in the Drupal sense, it may remove Drupal projects, modules, themes or profiles that are currently enabled.

This could have happen if you are updating a package. If ModuleA version 1.2.3 requires ModuleB but Module version 1.2.4 does not require ModuleB it may be removed when updating Module. This might act differently because most Drupal sites would composer/installers package which puts the modules in different paths but we should not rely on this behavior.

It might also happen if a custom or contrib module create a Stage that is meant to remove modules

\Drupal\automatic_updates\Validator\StagedProjectsValidator does prevent this from happening for core updates because no Drupal packages can be removed.

Proposed resolution

Check that all installed(in the Drupal meaning) projects are present in the stage on PreApply

  1. The module, theme, and profile extension list services use classes that extend \Drupal\Core\Extension\ExtensionList so that can be used to find the enabled projects. For example extension.list.module is the service for modules
  2. For each extension list we need to call \Drupal\Core\Extension\ExtensionList::getList()

    The tricky part here is if the site has duplicates of the same extension in multiple places. I think if there are 2 or more and 1 is enabled getList() will return the 1 that is enabled. If none are enabled it doesn't matter because we only care about enabled projects.

  3. The list will return Extension objects. There is not a isEnabled() method but I think this will be in $extension->info[status]. You may just have to use the debugger because these object are actually assigned properties dynamically(😢).
  4. If an extension is enabled then we need to call \Drupal\Core\Extension\Extension::getPathname to find its path
  5. Then we have to check if that same path existing in the stage directory
  6. The path does not exist in the stage directory then that means the extension is enable and was remove. So we need to flag an error

Remaining tasks

📌 Task
Status

Fixed

Version

3.0

Component

Code

Created by

🇺🇸United States tedbow Ithaca, NY, USA

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

Comments & Activities

Production build 0.71.5 2024