Create a Composer plugin that records what packages are being updated, installed, or removed

Created on 20 May 2025, 2 days ago

Problem/Motivation

It is a long-standing issue with Package Manager (and its implementers, specifically Project Browser and Automatic Updates) that we don't really know precisely what Composer is going to do ahead of time, if asked to add or update or remove a package.

This is a large reason why we need to do sandboxing. Create the sandbox, do some Composer stuff in there, and compare it against the live site to be sure we're not about to do anything damaging.

Annoyingly, Composer has a --dry-run option for several of its subcommands (including install, update, require, and remove), but Package Manager can't really take advantage of that because its output is not machine-readable.

But if only we had some way to find out what Composer is going to do before it does it...we could feel much more confident about Package Manager making changes, regardless of whether or not those changes will be done directly on the live site (in direct-write mode β†’ ), or in a sandbox.

Proposed resolution

There's a way, but we need to create a new Composer plugin to do it.

Composer dispatches an event (\Composer\Installer\InstallerEvents::PRE_OPERATIONS_EXEC) before it actually does the install/update/remove operations it's got lined up. This event is dispatched regardless of whether the --dry-run flag is present.

Although it slightly touches on internal parts of Composer, this event gives us everything we need to determine what packages will be changed and how.

So what if we did this:

  1. Create a Composer plugin which listens to this event and uses it to generate a JSON file with the complete information about what is about to happen, and which packages will be affected, in which versions. This would be a normal core-maintained Composer plugin with its own subtree split, just like core-composer-scaffold or core-recipe-unpack.
  2. Add a validator to Package Manager which requires this plugin to be installed and enabled in your project. (As part of doing this, we would add the plugin to core's project templates.)
  3. Change Package Manager so that it always executes a dry-run of any require operations, giving PreRequireEvent subscribers a "before" and "after" state to compare against, regardless of whether sandboxing is in use.

Remaining tasks

Decide whether we want to take this approach, or something similar...then do it. Probably this will take multiple issues.

User interface changes

None anticipated.

Introduced terminology

None anticipated.

API changes

There might be some changes in Package Manager, but this is TBD.

Data model changes

None.

Release notes snippet

TBD.

✨ Feature request
Status

Active

Version

11.0 πŸ”₯

Component

package_manager.module

Created by

πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts

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

Merge Requests

Comments & Activities

  • Issue created by @phenaproxima
  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts

    To clarify one thing about the proposed event...

    Here's what Composer's documentation has to say about it:

    pre-operations-exec: occurs before the install/upgrade/.. operations are executed when installing a lock file. Plugins that need to hook into this event will need to be installed globally to be usable, as otherwise they would not be loaded yet when a fresh install of a project happens

    In my initial exploration, that thing about the plugin being globally installed is not strictly true. I think it would be true if you wanted to affect projects that haven't been created yet...but for Package Manager's purposes, we don't care about that. Package Manager only operates on and within existing projects with a lock file. As long as the plugin is locally installed in the project, this event should suffice for our purposes.

  • Merge request !12197Initial stab at a plugin β†’ (Open) created by phenaproxima
  • Pipeline finished with Canceled
    about 18 hours ago
    Total: 76s
    #503202
  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts

    Created an initial version of the plugin which does a very simple dump of installer operations before they happen, into either JSON or PHP format (PHP is the default since it's probably faster to parse).

    This would probably provide Package Manager with enough information to operate on.

  • Pipeline finished with Failed
    about 18 hours ago
    Total: 173s
    #503203
  • Pipeline finished with Failed
    about 18 hours ago
    Total: 115s
    #503208
  • Pipeline finished with Failed
    about 17 hours ago
    Total: 214s
    #503239
  • Pipeline finished with Failed
    about 15 hours ago
    Total: 824s
    #503302
Production build 0.71.5 2024