Skip to content

[Composer2] Downgrade transitive dependency to satisfy deps on "require" #8910

@weaverryan

Description

@weaverryan
Contributor

Hi!

Apologies if an issue exists or if this has been discussed - I couldn't find an issue immediately.

Suppose there are 2 packages:

  • A) acme/foo, which requires transitive/dependency: "^1 | ^2
  • B) acme/bar, which requires transitive/dependency: "^1

The problem:

# this WORKS - transitive/dependency 1 is downloaded
composer require acme/bar
composer require acme/foo
# this BREAKS. The first command installs and locks transitive/dependency at v2
# then, the second command fails because transitive/dependency v2 is locked and
# acme/bar only works with v1
composer require acme/foo
composer require acme/bar

In theory (because transitive/dependency is not a root requirement), Composer could notice that, while acme/bar doesn't work with v2, that dependency could be downgraded to v1 to satisfy all packages. That "should" (with huge air-quotes) be safe, as it's just a transitive dependency. However, if we're worried that users might be inadvertently using the dependency directly, and this could break things, we could (instead) issue a clear warning on how to fix this:

acme/bar requires transitive/dependency ^1, but version 2.0.0 is locked. However,
your project is compatible with transitive/dependency ^1 and it could be downgraded.
Re-run the command with --allow-major-downgrades to allow this dependency to
be downgraded.

(This invents a new --allow-major-downgrades flag).

I'm sure this shouldn't be done in v1, but is it possible for v2?

Activity

added a commit that references this issue on May 15, 2020
Seldaek

Seldaek commented on May 19, 2020

@Seldaek
Member

The error reporting in v2 handles this better to suggest you a way out. I tweaked things so it covers more cases. So now you'd see this in your case:

$ composer require acme/bar
Using version ^1.0 for acme/bar
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Root composer.json requires acme/bar ^1.0 -> satisfiable by acme/bar[1.0.0].
    - acme/bar 1.0.0 requires transitive/dependency ^1.0 -> found transitive/dependency[1.0.0]
but the package is fixed to 2.0.0 (lock file version) by a partial update and that version does
not match. Make sure you list it as an argument for the update command.

Use the option --with-all-dependencies to allow upgrades, downgrades and removals for
packages currently locked to specific versions.

I think/hope that's clear enough :)

added this to the 2.0-core milestone on May 19, 2020
naderman

naderman commented on May 19, 2020

@naderman
Member

@Seldaek In that error message I find it confusing that it says "is fixed to 2.0.0 (lock file version) by a partial update", what partial update? Should we change the message if it's the require command?

We could generally improve this a little bit by changing the require output to:

$ composer require acme/bar
Adding acme/bar with constraint ^1.0 to composer.json
./composer.json has been updated [can this be removed too?]

Running composer update acme/bar:

Loading composer repositories ....
Seldaek

Seldaek commented on May 19, 2020

@Seldaek
Member

I like the last suggestion, because special casing the error message based on it being a require/remove command sounds horrible :) I'll try and implement that.

weaverryan

weaverryan commented on May 19, 2020

@weaverryan
ContributorAuthor

This looks much better - thank you!

stof

stof commented on May 19, 2020

@stof
Contributor

@Seldaek should composer install without a lock file also include some output saying it will actually run an update ?

naderman

naderman commented on May 19, 2020

@naderman
Member

@stof Doesn't it already in v2?

Seldaek

Seldaek commented on May 19, 2020

@Seldaek
Member

image

yes it does

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @weaverryan@naderman@Seldaek@stof

        Issue actions

          [Composer2] Downgrade transitive dependency to satisfy deps on "require" · Issue #8910 · composer/composer