February 2006
[ vmassol ] 12:09, Thursday, 16 February 2006

I've been asking myself the following 2 questions for about 5 years now: am I good at managing an open source project and making it successful? How can I improve?

I guess it depends on the definiton of "successful". My definition of a successful OSS project is:

  1. A project that has a big user community and mindshare
  2. A project that has a big development community (i.e. committers and contributors). That is the development mailing list should be quite active with lots of contributions, improvements, ideas being discussed. All those submitted by a large number of different persons
  3. A project that lives on if the initial or main contributor leaves the project

If we go by point 1, I think that the main 2 projects I have started (Cactus and Cargo) are not doing too bad. Cargo is still new but it seems to be on track and its user base is growing very quickly.

However on points 2 and 3, I'm not so sure I'm doing well. Mind you, Cargo has quite a lot of committers (growing every week!) and they're all doing a great job. I'm just thinking about the level beyond (look at the activity on the Maven project, Spring or other projects as an example of what I mean). Cactus is a bit different as it's now a mature project, so let's focus on Cargo. Of course it could be that these project domains are narrow and thus do not interest lots of developers. This is probably true but I don't think this is the only issue. I have the feeling that some of the reasons could be:

  • Unconsciously I may be "driving" the project too much. For example if someone proposes something, I'm probably going to argue with this person in order that it fits Cargo's quality crtieria and direction. It's possible that by doing this, I'm cutting some creativity from this person and thus even if he implements the thing, maybe he'll feel it has not completely come from him and won't identify with it enough to maintain and improve it in the future. Or maybe by arguing I'm just making the life of that person harder and as this person is doing this in the little free time he has, he may not pursue it...
  • Maybe I'm answering emails asked on the list too fast, thus preventing any other contributor to answer. This is setting the tone and maybe as a consequence people are expecting me to answer all emails. Everyone "knows" that I'll answer them anyway...
  • The same could be said for applying patches and implementing things. I think this is less true though as I also have a day job and there are lots of JIRA issues accumulating in the Cargo project for example, so there's room for takers
  • Documentation of Cargo seems good at first glance (although I know there are lots of holes). I wonder if, as a consequence Cargo users who look at the web site think that Cargo is stable, mature, etc and thus may feel less inclined to participate. Who wants to participate to a project that is mostly "done"! (Note: For those reading this and interested in Cargo, it is far from true and there are tons of things to design and implement!)

On the other hand, I feel that not doing any one of these points will hamper Cargo's user adoption...

Or maybe I'm completely wrong on all points above and this is just me fantasizing!

I'm really interested to know what you think and if this is something other OSS committers/contributors have noticed too. I've given the example of Cargo but really this is a general discussion on how to best manage an OSS project.

[ vmassol ] 13:48, Sunday, 12 February 2006

I see 2 use cases where ensuring binary compatibility is a must:

  • When you're developing a framework, i.e. a piece of software meant to be used at an API level by other developers. In that case, breaking binary compatibility is not something to do lightly.
  • When working in a large team it's common to define "interface" projects that represent the contracts to be followed by the different teams. In that case breaking the binary compatibility in an "interface" project is something that has to be planned and organized.

Enforcing binary compatibility in the build

The automated build is a nice place to enforce binary compatibility as the build is something executed by the indiviudal developers before checking-in and it's also executed by the continuous integration build. Thus any binary incompatibility can be quickly discovered. Or course this doesn't replace tests which can also help discover breakages. However the problem is that with all the nice refactoring IDEs we have now, it's easy to refactor the tests at the same time as the code and thus introducing a binary incompatibility is not always noticed.

A good strategy to discover an incompatibility is to compare the current code with the latest released code. This is what Clirr is doing. Clirr currently sports an Ant and Maven1 integration. The good news is that there's a Maven2 plugin in the work (more on that when it's released). However using a tool is only good if there's a strategy behind it.

Strategy for using Clirr

Here is what I believe can be done to automate binary compatibility checks in the build:

  • Start by organizing your packages so that you clearly demarcate the user-public API from the SPI from the internal implementations. You'll probably want to fail the build only on the user-public API (and possibly on the SPI too but that's probably a lower severity).
  • Use Clirr to make your build fail upon violation on the user-public API.
  • After discussing with the team and possibly with users, decide whether you wish to allow the binary incompatibility. Always consider going for a deprecation cycle. If you choose to allow the incompatibility, register it in an exception file that you pass to Clirr so that it builds without choking on those errors (Note: I believe Clirr needs to be improved to better support exceptions not only at the file level but at the violation level).
  • When the release time comes, you'll have a nice file listing all the binary incompatibilities. Include it in the release notes so that your users know what to expect and even better, for each incompatibility add a description that explains how to modify the user code to use the new version of the API.

Note: On the Cargo project we've tried to do this, even though there's still room for lots of improvement. Actually our main issue on Cargo is not detecting binary incompatibilites but rather deciding to release a 1.0 version which would mean that from then forward we would aways look for a deprecation solution rather than break binary compatibility. We've always pushed back this 1.0 release because our API has been changing quite frequently but we're now nearing a 1.0 version. When that comes we'll turn Clirr on to fail the build upon breakage. I'll let you know how it goes...