Tuesday, September 25, 2012

Clean Project Checklist

Some projects are harder than others. On a few of my projects, everything just feels harder than it should be. I can't find the classes I need to change; the tests on a clean checkout fail; configuration is manual and fiddly; getting set up to try your code is slow and unwieldy. They're just painful all around. Other projects are smooth and easy. There's a solid README for setting it up - and the README is short. Tests run well on clean checkout. Classes and methods are in the first place you look. The only hard part of these projects is any difficulty in actually solving the technical problem.

The main difference, I've discovered, is in the tooling around the projects. Some of the smooth projects are huge and involve different services and technologies. Some of the difficult projects are actually quite small and simple. When the tooling is clean and works, then the project is much more likely to be smooth. Over time I've come to look for a set of things that tend to indicate a clean project.

This is my clean project checklist:

  • Deployment and environment setup is automated using an actual automation tool. I don't care if it's Capistrano, Chef, Puppet, RightScale scripts or whatever. It just has to be something beyond a human and/or an SSH script. This includes creating a new box, whether it's a cloud box or a local machine in a data center somewhere. If it's scripted then I don't have to fiddle a lot manually, and it also tends to mean there's good isolation of configuration.
  • Uses Git. This makes the next item possible. It's also an indicator that the developers are using a toolchain that I happen to enjoy using and to understand.
  • Developers are branch-happy. Feature branches, "I might mess this up" branches, "just in case" branches - developers who are branch happy tend to think smaller. With that many branches, most don't survive for long! Smaller changes means smaller merging, and that makes me happy. It fits nicely with the way I work. I should note that I don't care how merging happens, either by merge or by pull request.
  • Has a CI system that runs all the automated tests. It might not run them all in one batch, and it might not run them all before it spits out a build, but it runs them. The key here is that automated tests run regularly on a system that is created cleanly regularly. This cuts down on tests that fail because they weren't updated, or issues that relate to data not getting properly put in the database (or other data stores).
  • Cares about the red bar. The build shouldn't be broken for long, and failing tests should be diagnosed quickly. In policing, it's called the broken windows problem: if you get used to small bad things then bigger bad things will happen. Don't let your project windows break.

I'm sure there's more, but what else am I missing?


  1. I have a hard time disagreeing, but I can try! :-)

    Actually, the only issue that I have a slightly different perspective on is branching. I have certainly seen too much branch happiness! I think the key here is 'short-lived'. If you think in terms of the next small step, that's good. If you use branching to go off into your own alternate reality, that's not so great for the general direction.

  2. "short-lived" is a very good point. Having 45 branches and not quite remembering what each of them does is definitely NOT clean.