Composer, the dependency manager for php is awesome. Incredibly awesome, and gaining more awesomeness by the day. There used to be many glitches, edge cases that made me grinch from time to time to time about it, but almost anything I’ve had to complain about is now working wonderful.
However not everything regarding dependency management is in control of composer, and much is left to the creators of those dependencies.
What causes me pain recently is versions. Library versions are completely in the hands of the library creators. And for this I found people have a variety of behavior regarding tagging versions that makes my use of composer quite inconsistent. Here’s the main 3 of them and why I think they are good / bad.
Update: Seems I’m not the only one thinking about this. Check @igorwesome’s opinion here: https://gist.github.com/4475804 too.
Dev-master is thy master
This maintainer has no tagged versions at all. Examples include (sadly all symfony bundles):
This is a horrible idea. You should tag versions. Even if you feel like your library is still under heavy development, clearly not finished yet etc… As soon as some other people are using your code, they need to be able to afford a bit of stability.
Countless times I’ve had the issue that when running a composer update, half of my code got broken because one or two libraries made changes on their development branch and didn’t worry that it would break things down for people who were using it previously.
One more advantage of having tagged versions is that composer caches them locally when you install them. Now I know all of you have internet connections of 8TrilloBytes/PictoSecond, but there’s still some of us for whom it’s not the case.
Time / feature based versions
Versions are tagged when maintainer “feels like it”. Seems to be the most common case. The maintainer has a deadline in mind, or a certain set of features he’d like to put in before creating a new version. So sometimes, many weeks / months go by before a feature actually makes it to a tagged version. I don’t have a definitive opinion on this strategy, I think it fits some libraries, but not all of them. It fits a framework, or a library with a massive user base I think.
My rant against this strategy is that often, bug fixes are also only tagged in a new version “at a later time”.
An example of this I recently had is with DoctrineExtensions (this is just one example because it’s the most recent one in my case). After an update to the latest version, the Sluggable behavior wasn’t working for me anymore. I went on to fix what for me was a bug, wrote tests for it, submitted a pull request which got merged.
Awesome you would think. Well yes but … no. Not completely. Now that I’ve fixed my bug, how do I start using the version that has the fix?
I can start using dev-master instead of the 2.3.* or 2.* version tag I previously had. But then, I’m back on the dev-master trainwreck. It’s called “dev” for a good reason, and it means that things are gonna break. Possibly a lot.
Or I could … well I don’t know!
The version tag freak
That would be me! If you look at https://github.com/khepin/KhepinYamlFixturesBundle/tags, it has 12 tags for about 96 commits in the repository. That’s one tag every 8 commits on average.
Whenever I update the code, or receive a pull request on it, I ensure the minimum to be confident that the code still works the way it should. Ask people to add tests when they submit new code. Run the tests before each PR. Try it on a spare project, whatever is needed.
But then as soon as I am confident that code doesn’t break things, I tag a new version immediately. X.Y+1.0 if I added some new feature or X.Y.Z+1 if it’s more of a bug fix.
I don’t think it’s a good thing to do for libraries that don’t have good testing in place as this would be like being on dev-master but with more work to be done. But for the other ones, doing something different feels like a relic of the past to me. A relic of times when it did cost money to release a new version. You had to print CD-ROMs, send them to your customers, go through an expensive upgrade process. So it made sense to only release when there was a truckload of new features / improvements.
But nowadays, what’s preventing us from having 5 versions a day if we’re confident they’re not breaking anything for existing users?
So maybe we could…
If you’re not confident, then the alpha and beta channels are here for that. I think these names are “misleading”. People have in mind that you work 5 months, then have alpha versions for one month and then beta versions for 2 weeks, and then a final version.
I’d like to propose that alpha and beta are used in a different way. Much like the “channels” on firefox and chrome.
In alpha, you can tag things as they come. Tag often. Not all the time (that would be dev-master), but often. As soon as a small feature is developed and tested => tag.
In beta, you give yourself room for a bit more feedback time.
And real versions are for when you feel comfortable that you’ve reached a new point in your library’s development.
What do you think? How do you do it?
I’m gonna say it again but you should at the very least start tagging versions of your code. This makes life easier for all the users of your code. This gives you the ability to develop new features freely without breaking everybody’s stuff.
I gave some ideas on how we could all achieve this better. I’m open to different opinions. Let me know what you think.