Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
172 views
in Technique[技术] by (71.8m points)

How does composer require resolve dependent packages already in the project?

When using composer require to add a new package to an existing project, how does composer reconcile versions of a package that is a dependency of both the existing project and of the newly required package?

Say I have a project consisting of package A and that package A depends on package B, with a version constraint of ~1.0. At the time of install, the current version of package B is 1.1, so that's what gets installed and written to the lock file.

Then a bit later I want to add package C to my project. Package C also depends on package B, but with a version constraint of >=1.0. At the time of adding package C, package B's latest release is 1.2.

When I do a composer require C/C, what will happen to package B? Will B remain at 1.1 as per the original installation and the lock file? Or will B be updated to the latest version (1.2)?

Consider the above again, but with the only difference that package C requires package B with a version constrain of >1.1.3. What will be the behaviour this time? Will composer refuse to install the new package C as the version constraint on the dependency B will conflict with the lock file? Or will composer update package B to the latest version (1.2)?

question from:https://stackoverflow.com/questions/65925686/how-does-composer-require-resolve-dependent-packages-already-in-the-project

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I've now managed to test both of the scenarios I've described above and composers behaviour is actually rather nice.

If you add a package to an existing project (with an existing lock file) using composer require <vendor>/<package> composer maintains the locked versions of any dependencies listed in the lock file even if newer version have been released. So in my example above, package B stays at version 1.1 as that is what is defined in the lock file.

If, when you require a new package, that package has a dependency constraint which cannot be satisfied by the currently installed versions of that dependency, even, if a newer version of that dependency would be compatible with the original composer.json, then composer gives the following error:

Your requirements could not be resolved to an installable set of packages.
Problem 1
Can only install one of: vendor/b[v1.2, v1.1].
vendor/c v1.1 requires vendor/b ~1.2 -> satisfiable by vendor/b[v1.2].
Installation request for vendor/c ^1.1 -> satisfiable by vendor/c[v1.1].
Installation request for vendor/b (locked at v1.1, required as ~1.0) -> satisfiable by vendor/b[v1.1].

Where I think the key bit is locked at v1.1.

Doing a composer require does seem to implicitly do an composer update as @Adam suggested, but this update seems to be constrained by the existing composer.lock file. There is a difference between doing just a composer require <vendor>/<package> and a composer require <vendor>/<package> --no-update followed by a composer update. In the case of a require --no-update followed by an update, the behaviour differs, with all packages being resolved from scratch (no reference of the lock file), and the latest versions of the packages installed.

All of the above was tested against composer 1.10. As the results seems sensible and thought out, I've no reason to think it would have changed for 2.x, but I've not tested that.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...