Some weeks ago now, I blogged that I've adopted the open source NHaml project over at GitHub, I'm now an administrator. I also mentioned that I was looking to get an initial release out sometime in December. Since then I've been beavering away at the thing, we're now most of the way through December, it feels like it's time for a status update.
In this post, I'll be talking a little about the project as I picked it up, lessons learned in my first baby steps adopting an established OSS proect, the decision to go with a (almost) rewrite, TDD and why I feel this is important stuff, and a few other odds and ends.
Incidentally, I in no way whatsoever mean to sound like I'm having a dig at previous contributors to the project, the stuff I'm putting into the project now owes massively to these earlier contributors, I'm trying to evolve as many of their existing ideas as I can.
How I Got Myself Into This
The early days - how did this whole thing get started.
Mid October, and I'm looking for some new geek porn to play with. I come across an intruiging looking lightweb OSS web framework, NancyFx, and I see that there's talk of a lightweight web markup language to go with it called "NHaml", surely this is a match made in heaven!
But then I find that NHaml is kinda dead, and I find that the NancyFx integration with NHaml was dropped because it was kinda dead. I resolve to do something about this, and a few tweets later, lo and behold, I'm now an NHaml administrator. (Incidentally, many thanks to Simon Cropp for making this a quick and painless process)
Lesson 1 - Expect To Leave Your Comfort Zone
I've never worked collaboratively on an open source project before, so I'm a little clueless where to start. I realise that I need to fork the repository, and then I can start playing around with the code, trying to get some failing tests to pass, trying to understand how the thing works. This is okay for a few days, but as I'm trying to learn the codebase, some things are a little painful. Some funky dependencies that I can't quite work out, some things that are new to me which I take a while to grok.
This ain't the code I'm used to in my day job - not better or worse, but certainly different! And then I see that I'm not the first person to come along and fork this thing.
Lesson 2 - Fold In Them Forks
It turns out there are two fully fledged forks of NHaml that have seen a fair bit of work, but were never pulled back in. The first fork was dead easy to adopt in - lots of small minor fixes that were all really worth having, courtesy of Darren Cauthon. Thanks dude!
The second fork was trickier, much trickier. You see, the original NHaml project was missing a distinct parser component. So someone (Steve Wagner) takes a fork, and proceeds with a semi-rewrite to incorporate a full blown syntax-tree based parser. Only when I come to pull the fork back in, I become a total arse, and decide that what I need is an excuse to rewrite the whole thing again. So we come to lesson 3.
Lesson 3 - Learn To Live With Stuff That's Not Your Style
I'm going to struggle with this lesson, I know it. The parser rewrite contributed by Steve was really an impressive feat. It solved the problem that needed solving very well, but there were two things that bothered me:
- It didn't look like it had been purely test-driven, a current obsession of mine
- It didn't solve all of the problems I suspected needed solving in NHaml
Here's what I probably should have done - I should have left the parser alone, and spent the last few weeks working on the problems around the parser. I could have gotten something stable and out the door, then if I still want to pick at the parser, I can do that in my own time.
Instead, I took Steve's work as inspiration, and started a pure TDD rewrite of the whole thing.
Lesson 4 - Run The Project Like a Business
So now that I'm fully committed to a TDD rewrite of the core parts of the project, and time's ticking away, the decision has been made to trim functionality back to basics. Out goes the IronRuby support, out with the Visual Basic support, I'm going to focus 100% of my effort on providing something that'll work for the 80% of interested devs who are C# users.
Similarly, I've focused on getting the simplest template possible working end-to-end before I start working on the full breadth of the Haml specs. This way I'm eliminating as much risk as possible as early as possible, and I can sooner get a release out the door that covers the 80% of the Haml spec that's used 99% of the time. The 20% of features that noone really uses, again these can wait.
NHaml4 = NHaml Lite + AST + BDD + TDD + ...
Of course there's no way I'll get anything out the door in December as originally suggested, and that feels pretty sucky. I've got the new TDD end-to-end infrastructure working for the simplest possible template, so the work now is to add the full NHaml grammar. Maybe February's looking more realistic for a re-release. And the new release will have some good things going for it.
First off, we've got the fore-mentioned spanking new AST (Abstract Syntax Tree) based parser, which gives us the ability to reuse the same code in related tools and plugins (a Visual Studio syntax highlighter, for example). We can also use standard algorithms like the walker or visitor pattern to generate different views of the tree, for example a plain text view vs a HTML view vs a C# code generator class view.
And then we've got all the BDD and TDD goodness, which should give a lot more room to grow and flex. It should also help other contributors quickly work out what's what.
Finally, I'm hoping the whole thing will come out a lot simpler than the current NHaml, purely because of the TDD focus and the associated architectural benefits, such as cleaner dependencies, improved single-responsibility, etc. Time will tell.
Finally finally, a very happy Christmas/holiday period to all reading this.