Andrew Cavanagh

Developer.  Project Architect.  Huge Nerd.

(not necessarily in that order)

I recently helped a colleague out with an issue he was having. He was working on a project that had a dependency which needed to be locked down to a particular commit in composer.json. Everything was fine until one day he ran composer update, and everything blew up in his face.

The line in the composer.json file was something like this:

"foo/bar": "dev-master#63698facf5d7cd29b3e69fa0df46c604e822dbbe"

It’s the dev-master bit that’s the killer here. There’s a pretty good argument for not tying your packages to dev-master in general, and this is one of the reasons why. When requiring a specific commit, composer will not honor that commit’s requirements (composer.json). Instead it computes the branch’s head requirement (in this case, dev-master). Someone had committed a change to composer.json in the master branch of the package, which resulted in an unresolvable set of dependencies for the project in question. In other words composer wasn’t using the composer.json file from 63698facf5d7cd29b3e69fa0df46c604e822dbbe to resolve the packages dependencies, it was using the composer.json file from dev-master’s, which had changed.

The solution here was to hang the commit on a particular release that would have stable requirements. That way you’re always getting both the commit you want and the set of dependencies that you expect. The line above becomes something like:

"foo/bar": "4.0.x-dev#63698facf5d7cd29b3e69fa0df46c604e822dbbe"

The composer.json file in 4.0 isn’t going to change, so as long as that release contains your commit and that release’s set of dependencies works for you this should be a stable solution.

comments powered by Disqus