Make Package Manager more friendly to local development by allowing stages to operate directly on the codebase in some situations

Created on 31 January 2025, 4 months ago

Problem/Motivation

There are some cases where we would like people to be able to use Package Manager in a more permissive way that it behaves out of the box. For the purposes of this issue, consider the use case of a simple local development setup (i.e., php -S) of Drupal CMS, being used by a marketer who is not technical and cannot be expected to ever look at a command line.

Package Manager requires Composer and rsync. Currently, those must be detectable in the PATH environment variable, or anything built on Package Manager will crap out with a nasty error. You can configure the paths to these executables in config, but you have to know how to do that (spoiler: it involves the command line, so we've already lost our theoretical non-technical user). That's being improved over in ✨ When it is installed, Package Manager should try to detect the paths of Composer and rsync Active .

What if you don't have rsync, though? What if you don't even know what that is? You are completely prevented from installing modules into your site in a local environment, in which you are the only user, with Project Browser. You are shut out of the ecosystem.

This is a mission-critical problem for Drupal CMS.

Proposed resolution

There are two possible paths here.

  1. Explore alternative methods for copying the Drupal code base to and from the sandbox directory. Are there any reasonable alternatives to rsync that are available on 99.9% of Mac, Windows, and Linux installations?
  2. Allow Package Manager to operate directly on the code base if and only if certain conditions are present. Package Manager would, by default, continue to sandbox everything. But, if a developer set a particular setting (say Settings::get('package_manager_allow_optional_sandboxing') or similar), and a given StageBase subclass declared, via an immutable constant, that it was willing to operate outside of the sandbox, Package Manager would allow it to do so. This means that Project Browser's StageBase subclass could declare that it is willing to operate on the un-sandboxed code base, but Automatic Updates could continue to be stringent.

Remaining tasks

TBD

API changes

TBD

Data model changes

None anticipated.

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
  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts
  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts
  • πŸ‡¬πŸ‡§United Kingdom catch
  • πŸ‡¬πŸ‡§United Kingdom catch

    So if I'm reading correctly this would be adding a direct-write mode when a flag is set, but only for project browser. The idea being you can composer require new dependencies and the simple act of doing so won't blow up your site, whereas update might.

    Overall that sounds great I think.

    Is there any situation where indirect dependencies might be updated as part of a composer require or does composer always just complain in that case?

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

    Is there any situation where indirect dependencies might be updated as part of a composer require or does composer always just complain in that case?

    Yes, Composer might update indirect dependencies as part of a require, depending on what the dependency solver spits out. So there is an element of risk to this, but I would say that:

    • This is why the direct-write mode would be accessible only to developers.
    • Project Browser could take steps to prevent indirect dependencies from being updated (Composer now accepts a --minimal-changes option, which tries to minimize changes to indirect dependencies; Package Manager could be changed to ensure that Project Browser can pass this option, or maybe Package Manager could just always pass the option regardless).
    • If packages are properly respecting semantic versioning, and using sensible constraints for their own dependencies, then the risk is probably low enough to not be of concern to the non-technical user.
  • Merge request !11076Resolve #3503699 "Make package manager" β†’ (Closed) created by phenaproxima
  • Pipeline finished with Failed
    4 months ago
    Total: 606s
    #411677
  • Pipeline finished with Failed
    4 months ago
    Total: 188s
    #411701
  • Pipeline finished with Failed
    4 months ago
    Total: 461s
    #411738
  • Pipeline finished with Failed
    4 months ago
    Total: 714s
    #411745
  • πŸ‡¬πŸ‡§United Kingdom catch

    If packages are properly respecting semantic versioning, and using sensible constraints for their own dependencies (which is true for core, and probably widely true enough for contrib),

    At least two fairly high usage contrib modules, maintained by different people, incremented hook_update_last_removed() in patch releases in the past month or so, preventing updates from e.g. 1.1.1 to 1.1.3.) Just the most recent example I can think of where a patch release led to a site that could not be updated.

    --mininal sounds great to avoid this though.

    Would it be possible to run --dry-run and detect if it includes updates? Would be annoyingly slow though, but maybe only when this mode is on?

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

    Would it be possible to run --dry-run and detect if it includes updates? Would be annoyingly slow though, but maybe only when this mode is on?

    Unfortunately, composer update doesn't give us any machine-readable output, with or without the --dry-run flag. The only way to detect what will happen, is to use the sandbox.

    So as I said, there's some risk involved here, which is why direct-write wouldn't be enabled by default. I think it also makes sense for Package Manager to always pass the --minimal-changes flag to Composer to minimize the possibility of breaking changes being introduced (regardless of whether direct-write is enabled), but we should probably do that in a separate, blocking issue.

    The reason Package Manager doesn't pass --minimal-changes is because I don't think it even existed when we were writing Package Manager. It was only introduced in Composer 2.7.0 (see https://getcomposer.org/changelog/2.7.0).

  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts
  • πŸ‡­πŸ‡ΊHungary GΓ‘bor Hojtsy Hungary

    @catch wrote this:

    So if I'm reading correctly this would be adding a direct-write mode when a flag is set, but only for project browser. The idea being you can composer require new dependencies and the simple act of doing so won't blow up your site, whereas update might.

    Overall that sounds great I think.

    I agree. There is already the package_manager_change_log entries that document what package manager requested and then separately logged what actually happened in composer, which helps providing a paper trail of what it did.

    I also think we can trust composer itself probably better to not leave your composer.json/lock and vendor files in a half applied state than our own code that copies that over from the composer staging, so I don't see added risk there.

  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts
  • Pipeline finished with Failed
    4 months ago
    Total: 395s
    #424268
  • πŸ‡¬πŸ‡§United Kingdom catch

    The MR looks good to me I think, --minimal-changes should reduce the amount of things that can go wrong.

  • Pipeline finished with Failed
    4 months ago
    Total: 195s
    #424320
  • Pipeline finished with Canceled
    4 months ago
    Total: 282s
    #424328
  • Pipeline finished with Failed
    4 months ago
    Total: 610s
    #424342
  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts
  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts
  • Pipeline finished with Success
    4 months ago
    Total: 873s
    #424363
  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts

    Draft change record written: https://www.drupal.org/node/3506770 β†’

  • Pipeline finished with Canceled
    4 months ago
    Total: 344s
    #424405
  • Pipeline finished with Success
    4 months ago
    Total: 383s
    #424414
  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    Appears to have a number of open threads, if those could be answered please.

    Thanks all

  • Pipeline finished with Failed
    2 months ago
    Total: 869s
    #458752
  • Pipeline finished with Canceled
    2 months ago
    Total: 238s
    #459042
  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts

    @tedbow and I discussed this at DrupalCon. We agreed that we should just not dispatch PreApplyEvent and PostApplyEvent at all, since they don't make any sense if you have effectively already "applied" changes to the site by requiring some dependencies.

    So we'll just document that, and test that those events are never dispatched in direct-write. But generally this is ready for review.

  • Pipeline finished with Success
    2 months ago
    Total: 603s
    #459050
  • Pipeline finished with Failed
    2 months ago
    Total: 196s
    #459072
  • πŸ‡ΊπŸ‡ΈUnited States tedbow Ithaca, NY, USA

    Some suggestions but think it looks pretty good!

  • Pipeline finished with Failed
    2 months ago
    Total: 221s
    #459301
  • Pipeline finished with Failed
    2 months ago
    Total: 237s
    #459312
  • Pipeline finished with Failed
    2 months ago
    Total: 170s
    #459313
  • πŸ‡¬πŸ‡§United Kingdom catch

    I'm not sure how to test this without committing it, but how sure are you that this will successfully work with core updates where the code of package_manager itself can change?

  • Pipeline finished with Failed
    2 months ago
    Total: 310s
    #461623
  • Pipeline finished with Failed
    2 months ago
    Total: 450s
    #461636
  • Pipeline finished with Success
    2 months ago
    Total: 453s
    #461674
  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts

    @tedbow and I had a nice, long Zoom chat about #21 and the implications of it.

    It is in the very nature of Package Manager to change the running code base. Right now, that only happens during the apply phase, and during that phase, Automatic Updates kicks the site into maintenance mode and tries to finish the current request as quickly as possible. This is precisely to mitigate the possibility of weird things happening while the running code base is changing itself.

    The crux of the problem is that, conceptually, direct-write moves that risk from the apply phase, to the require phase. In direct-write mode, the apply phase effectively doesn't exist.

    Ted and I felt that the right course of action, then, is for Package Manager to kick the site into maintenance mode when direct-write is happening. In other words -- when something is required in direct-write mode, go into maintenance mode, and emerge from it when the require has completed. The idea is to reduce the risk of weird things happening if the running code base is changed while, say, 1000 people are using the site. It can't completely eliminate the risk, but it would greatly reduce it.

    Additionally, direct-write mode should result in a warning being flagged during status checks. That warning should state that direct-write mode can be risky because it changes the running code base. That is always true, and site owners should be aware of it. Direct-write mode is meant to make local development easier (i.e., a site with only one person using it), and it's inherently riskier in a production environment. Flagging a warning seems like a completely reasonable thing to do.

    We think we could implement that change in a separate issue, after this one (which adds the direct-write API) is committed. That issue would be a stable blocker for Package Manager.

    The second tricky thing that came up is the validators which are trying to compare the live site with the sandbox, by subscribing to PreApplyEvent. Most of these validators are just useless in direct-write mode, and their validation -- which may be valuable -- is just skipped. (For example, SupportedReleaseValidator checks to ensure you didn't just install some insecure or unsupported project into the sandbox.) How can we ensure that this validation is not lost? Even if the validation has already happened to your site, you as the site owner should still be aware of it as a problem that you need to address.

    We're still not entirely sure what to do here, but Ted's idea is to shift a lot of that validation to StatusCheckEvent. Since there's no sandbox to compare the live site against, we'd have to record the state of the live site before anything else happened -- i.e., on or before PreCreateEvent is fired. Subscribers to StatusCheckEvent could then compare that recorded state to the current state of the site, to determine if anything untoward had happened during the require phase, regardless of whether it happened in a sandbox, or in the live site.

    We could probably also do that in a stable-blocking follow-up issue.

  • Pipeline finished with Failed
    18 days ago
    Total: 154s
    #497057
  • Status changed to Needs work 18 days ago
  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts

    Needs some additional test coverage for the maintenance mode and warning stuff I just added (based on what Ted and I talked about in #22), and I think this should definitely have manual testing before being committed.

  • Pipeline finished with Failed
    18 days ago
    Total: 159s
    #497081
  • Pipeline finished with Failed
    18 days ago
    Total: 152s
    #497089
  • Pipeline finished with Success
    18 days ago
    Total: 791s
    #497098
  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts

    OK - I've written tests for what was discussed in #22.

  • Pipeline finished with Failed
    18 days ago
    Total: 184s
    #497218
  • Pipeline finished with Failed
    18 days ago
    Total: 141s
    #497227
  • Pipeline finished with Success
    18 days ago
    Total: 531s
    #497228
  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts
  • Pipeline finished with Success
    17 days ago
    Total: 468s
    #497290
  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts
  • Pipeline finished with Success
    17 days ago
    Total: 438s
    #497301
  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts
  • πŸ‡¬πŸ‡§United Kingdom catch

    A few comments on the MR, I don't think there is anything too major in there.

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

    Tried to rephrase some comments for added clarity.

  • Pipeline finished with Success
    17 days ago
    Total: 745s
    #498117
  • Pipeline finished with Failed
    17 days ago
    Total: 425s
    #498189
  • Pipeline finished with Success
    13 days ago
    Total: 547s
    #501047
  • Pipeline finished with Canceled
    12 days ago
    Total: 211s
    #501195
  • πŸ‡ΊπŸ‡ΈUnited States tedbow Ithaca, NY, USA

    Just went over this again with @phenaproxima, looks good!

  • Pipeline finished with Success
    12 days ago
    Total: 561s
    #501201
  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts

    Opened πŸ“Œ Move some Package Manager validation into the pre-require and status check event listeners Active to move some validation around as needed to support direct-write mode.

  • πŸ‡¦πŸ‡ΊAustralia larowlan πŸ‡¦πŸ‡ΊπŸ.au GMT+10
  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts

    I feel pretty confident about this. Let's get the API in, then I'll test it against Drupal CMS and we can fix any glaring bugs. The addition of the API is harmless by itself, since it doesn't do anything unless extant sandbox managers actually opt into the capability. So the real test will come after contrib adopts this feature.

  • πŸ‡³πŸ‡ΏNew Zealand quietone

    I read the MR, CR and updated credit. I re-worked the change record so that the improvement is the first thing mentioned. And I changed wording to be plain English.

  • πŸ‡³πŸ‡ΏNew Zealand quietone
  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts
  • Pipeline finished with Success
    12 days ago
    Total: 526s
    #501731
  • πŸ‡³πŸ‡ΏNew Zealand quietone

    Yes, that make sense. The wee change is an improvement.

  • πŸ‡¬πŸ‡§United Kingdom catch

    Discussed πŸ“Œ Move some Package Manager validation into the pre-require and status check event listeners Active a bit with @phenaproxima in slack.

    I had a quick look for validators that would be affected by this change (e.g. not run at all if this is used). The three I could find were:

    EnabledExtensionsValidator
    DuplicateInfoFileValidator.php
    SandboxDatabaseUpdatesValidator

    EnabledExtensionsValidator seems like the main problem.

    https://www.drupal.org/project/pathauto/releases/8.x-1.11 β†’ removes a ctools dependency, and will remove it as a composer dependency in a major release. This means that when sites eventually update to pathauto 2.x, they'll need to either composer require drupal/ctools or uninstall it (unless they happen to have another module installed that depends on it).

    Automatic updates can't do any of that itself, so would need to rely on this validator to handle it (and then the site owner would be alerted they need to either install ctool explicitly or uninstall it before trying to update pathauto again, after which it would work), but that won't run in direct write mode. @phenaproxima pointed out that composer update --dry-run doesn't support machine readable output, so this might need a composer update --dry-run:json custom composer plugin in order to replace.

    However, neither that, nor SandboxDatabaseUpdatesValidator are relevant to project browser. After writing that I realised it might be relevant, because if you install a project that depends on pathauto 2.x, and you have pathauto 1.x installed, then composer might update you to pathauto 2.x even though the command in composer require which could also result in ctools removal.

    I think we need a follow-up to discuss this more, and maybe postpone implementing the API in project browser and especially automatic updates on that follow-up.

    • catch β†’ committed f3c0cda3 on 11.2.x
      Issue #3503699 by phenaproxima, catch, quietone, tedbow, smustgrave,...
    • catch β†’ committed 05b8266c on 11.x
      Issue #3503699 by phenaproxima, catch, quietone, tedbow, smustgrave,...
  • πŸ‡¬πŸ‡§United Kingdom catch

    Bumped πŸ“Œ Move some Package Manager validation into the pre-require and status check event listeners Active to critical so it doesn't get forgotten, also added to package manager stable blockers. I think the scope is too big to do in a single issue here.

    Committed/pushed to 11.x and cherry-picked to 11.2.x, thanks!

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

    Thanks @catch!

    For whatever it's worth, I am in complete agreement that implementing this API needs to be done very carefully and thoughtfully. Project Browser should have a dedicated issue to add support for this, to fully think through the implications.

    Automatic Updates implements at least three different sandbox managers, and each of them should get their own issue to discuss whether to support direct-write. The potential benefits are significant, but so are the risks.

  • πŸ‡¬πŸ‡§United Kingdom catch

    The build test change here made it the slowest core test at over 3m20s, opened πŸ“Œ Split PackageInstallTest into two Active .

Production build 0.71.5 2024