Sunday, April 26, 2009

Hudson, NDepend and OSS - The Good, The Bad, and The Useful

Patrick Smacchia was kind enough to give me a copy of NDepend so I could give it a good test drive. While we do use NDepend at work, we primarily use it for finding low hanging fruit for refactoring with our legacy software. I decided this would be a wonderful opportunity to see what NDepends story is with OSS and CI.

To facilitate this demo, I used my fresh new BDD Framework Specmaker and Hudson CI server. Normally for CI at work I'd include a copy of whatever software I need in the actual source tree to make it easy to deploy. Obviously, since NDepend is a commercial product and Specmaker is Apache 2.0 license and hosted on Google Code, this was not a viable approach.

So I did the following:

  1. Installed Ndepend on my CI Server
  2. Created a directory to store results
  3. Created a VisualNDepend project. To be able to find my dlls I had to edit the NDependProject.xml file by hand to point to the correct locations. I'd like some nant style Fileset matching instead here. Makes it feel very much like MSBuild.
  4. Setup 2 batch command steps in my build process to run AFTER my normal nant build (seen below, click to view closely) that called ndepend.console.exe and then copied the results to my build folder so they could be archived by Hudson.
  5. Setup the archival rules for my build to grab all of the results that I'd copied to "build\NDependOut" so I could easily reference them after a successful build.

This took quite a bit of fiddling to get working my primary issues were related to Hudson's NAnt plugin (if you reference two nant calls, the first one ends up overwriting your second one so you just do step 1 twice). However once, I got it working my reward was the scolding finger of NDepend. Apparently I have a class teetering on the verge of Cyclomatic Complexity limits (SpecDescription), looks like I have some review to work out some kinks.

Overall Review

  • The Good - Nice UI for Visual NDepend, GOBS of information, CQL is really well thoughtout dsl for finding what you want so far.
  • The Bad - Hard Referencing dlls in xml is bad, rule matching is badly needed here. Causes friction when setting up the project for automation. Custom Nant Task it comes with is very limited according to included documents.
  • The Useful - when combined with CI the comparitive analysis is brilliant. This lets you catch when codebases are declining in quality in an automated fashion. See here for one such example.
Final words, I have to be honest here, I had fallen out of love with NDepend largely, finding it mostly useful only when initially touching a codebase, or when I was first learning SOLID principles. This was of course amazingly useful to my growth, and refactoring efforts, but I was finding less and less need for it with new projects. Looking over Patrick's blog at some of the examples he's come up with using CQL I do not think I've come close to tapping the usefulness possible with this tool. I'll be working more and more towards bending the tool to keep existing codebases in check, and will definitely be using it at home on my OSS work.

Friday, April 10, 2009

Deployment automation and adventures in stupid

At work we currently do not have a ton of order to software releases and requests. I've worked hard to try to bring more there but it's just not part of the way things have been done in the past and that type of change in particular takes a lot of work and persuasion.
Summary we're better than we were but we're not perfect yet.

I have a confession to make...I was being a hypocrite yesterday. I've been preaching since shortly after I got there "you can automate deployment", "manual deployment is error prone and slow", "integrate regularly, release often". With my background as a sysadmin it didn't take me long to get every at least newer software release auto deployed in some fashion or another. The other push was towards not implementing software in chunks but slowly in front to back layers.

However, about a month and a half ago, me and my co-worker were making changes that would require us to change two products at once. I had stupidly gone off on an unecessarily bold refactoring to modularity of one of those I just let things fall behind and stopped pushing frequent releases.

Month and a half goes by and now the trunk has :
  1. a TON of changes to a variety of processes. Including fixes to things that were major current maintenance time sinks
  2. I had not yet successfully moved all my unit tests around to the different modules so I had managed to eliminate my hard won safety net.
  3. Several database changes that I haven't scripted.
  4. Worst of all code that was behind schedule that had been done for 4 weeks.
So yesterday I finally have had enough of excuses why I wasn't pushing this build out. I manually do everything I had not yet had time to automate, and without all my tests in the proper location!

Finding several stupid kinks, multiple bonehead "I forgot" things, and 15 hours later (with only two hours of sleep) with a process that was supposed to take 30 seconds I had both products released.

I'm quite happy to say now I have an in sync code base, and a big list of fixes to implement which I will release one at a time!

Release Frequently, do not push off things till later, and do things in small small layers.