I have been putting together a new talk about Composer, and that means looking around the community, doing loads of research and trying to identify the items that need to be covered in a talk. Mostly I have been trying to identify things that people do on a regular basis that according to composer internals is either wrong or not ideal.

One such thing that I have found is the proper selection of versions, and that also led me to find a new feature in composer that makes everyone’s life so much easier. So let me break this down.

Version selection

First we need to define how to properly set the version of a library you need. I’ll consider you already know about semantical versioning and its dynamics.

vendor/package: *

So this is a NOPE right off the bat. As it turns out this has 2 flaws: first it will grab any version, meaning if the library breaks BC, your library will go along with it. Second it makes Composer turn into (even more) of a power hungry CPU and memory muncher, since it wides the “search scope” for the Version Resolver to work. Sounds bad right?

So this is a NOPE right off the bat. As it turns out this has 2 flaws: first it will grab any version, meaning if the library breaks BC, your library will go along with it. Second it makes Composer turn into (even more) of a power hungry CPU and memory muncher, since it wides the “search scope” for the Version Resolver to work. Sounds bad right? vendor/package: 1.2.*

This one is not bad, however a point release does not break BC, so you should be able to move to 1.3 without issues, this does not allow that. Fine in this case, but it gets complicated once you have two libraries with the same requirements you now blocked the download of v1.3, which the second library may need.

This one is not bad, however a point release does not break BC, so you should be able to move to 1.3 without issues, this does not allow that. Fine in this case, but it gets complicated once you have two libraries with the same requirements you now blocked the download of v1.3, which the second library may need. vendor/package: >= 1.2

Once more this bites the dust with semver since it leaves you wide open to get v2.0 which very likely will make you unit tests turn red.

Once more this bites the dust with semver since it leaves you wide open to get v2.0 which very likely will make you unit tests turn red. vendor/package: 1.0.0

This is the most restrictive of all, it will keep you locked on this version and will probably not play nice with any other library using this dependency.

This is the most restrictive of all, it will keep you locked on this version and will probably not play nice with any other library using this dependency. vendor/package: ~1.2

This is what you are looking for, its called the tilde, and it means “Next Significant Release”, its internally expanded to >=1.2.0,<2.0.0 meaning all the non-BC breaking releases before the next significant release, which will be 2.0.0. You can also be more specific with ~1.2.3 this will basically always be the lower end of the match.

Update: Keep in mind that the number of dots will define which level of release you wish to grab, i.e ~1.2.3 expands to >=1.2.3, <1.3, restricting you to patch updates. One option you have is to use ~1.2,>=1.2.3.

Using the tilde operator gives you the best chance to avoid conflicts with other libraries, which means you will play nice and also avoids you having to update your composer.json file everytime another library releases a new version.

Adding new dependencies and Install instructions

With Composer gaining more and more traction we seem loads of libraries out there using and supporting it. However since not everyone is familiar with composer (yet!) we often end up with loads of install instructions on how to install libraries via composer.

The most common of those unfortunately goes something like:

Install this library using Composer, please add this to your composer.json file { "require": { "vendor/package": "*" } }

Now, this is a problem for 2 reasons. One, you have to edit the composer.json file, and two: to avoid editing this all the time developers usually pick “*” which we already learnt was a no-no. Also people don’t seem to agree on these instructions to no two are the same.

It just so happens there is a better, faster way to do this, which even comes with a few perks. And it fits in a single line you can copy/paste to your console and run:

composer require vendor/package

That’s it, simple as, well this. This will obviously done one thing, it will open your composer.json file and add this requirement in there for you, now messing with the file. Now some of you will be telling me i did not add the version to it, like so:

composer require vendor/package:~1.2

And this is where Composer blew me away a few weeks ago. I did not, and i should not. Turns out composer figures that part out for you (meaning it identifies the latest version available) and also binds it properly using the proper tilde operator. How awesome is that?

composer require vendor/package Using version ~1.0 for vendor/package

Disclaimer: if you know you need a version and its not the latest, then yeah, stick to the previous option.

Campaign: PRs for a better Composer Ecosystem

So this month we are in the middle of #hacktoberfest, promoted by Digital Ocean, so you all want to stack up those Open Source contributions right? Here is my idea, let’s send a PR to every package that has the old composer.json instructions and send them an updated version with the new recommended install method. It would look something like:

To install this library, run the command below and you will get the latest version composer require vendor/package

Feel free to add composer.phar if you feel the need. If you want to hear more, come see me talk at php[world].

How about it? Let’s fix the internet and revolutionize composer installs! Add links to your PRs in the comments!

Share this: Reddit

Pocket

Facebook

Twitter

LinkedIn

