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.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…