After more than a year, with plenty of long pauses along the way, I've finally gotten round to replacing the old non-supported NHaml codebase with the shiny new TDD'd fully supported NHaml codebase. It's been a tough decision, for reasons I'll go into in a moment, but the new code is now up over at GitHub (http://github.com/NHaml/NHaml).
Alongside this release, I'm continuing work on Nancy integration (see http://github.com/NHaml/Nancy), resuming the NHaml TeamCity configuration over at teamcity.codebetter.com and using NHaml+Nancy-self-hosting to resurrect the FhemDotNet project.
A Tough Decision
It's always a tense time putting a project as big as NHaml out in the open. (currently just under 100 classes, and almost 400 tests!) When the release replaces an existing version that's established and arguably more feature rich, then I've got some explaining to do.
Also on an important side-note, I genuinely hope this post doesn't suggest any criticism of previous contributors to the project. All of the work that I've been able to do has only been possible because of the work and insights of previous contributors, and I'm indebted to these folks for giving me a running start on my own contributions.
So why have I released the new code? There are a number of reasons.
First, unit tests. The old code base was certainly tested, but I don't believe it was test driven, and I didn't feel like it had the coverage that allowed random changes to be made in confidence that tests would catch 99% of issues. The new code has been as purely test-driven as possible, and that seems to be paying dividends now that complex changes can be made quickly and safely.
Next up, there's less source code. The previous code base had several features that, after discussing with other contributors to the project, were underused and difficult to justify supporting. For example the ability to generate templates in multiple .Net languages, when 90% of users would have gone straight for the C# implementation. The new code base cuts these features out entirely - until I can drop NHaml into something like Nancy or an MVC app and it positively sings, I could never personally have commited to maintaining the dropped features. (Of course if someone else wants these features, they're more than welcome to fork the project and re-implement them! )
Third, the new template engine is written from the ground up to fully adopt the four-stage process started by Steve Wagner (http://github.com/lanwin). Templates go through a lexer phase to read the physical files, a parse phase to generate a syntax tree, a walk phase to generate C# source code and finally a compile phase to generate the template factory class. There's scope here to reuse the lexer and parse code in related projects such as a VS syntax highlighter.
And the last reason, which I kinda hinted at a moment ago, is the ground up rewrite. Now I'll admit I never set out to do a full rewrite, but as my changes became more and more intrusive, that's where things have ended up. This project has been around since June 2008, and contributors have drifted in and out of the project since that time. The heart of the rendering engine was still based on patterns introduced with that very first commit, it turned out to be impossible to rewrite that heart of the thing without rewriting the rest of it too.
But There's Stuff Missing!
This first re-release is something of a "minimum viable product". With no active contributors to the old codebase, anyone using it is investing in dead code. Now that I'm at a point where I can use the new codebase in my own websites, even though there are features missing (the partial and master page support is pretty woeful for example), I want to make sure that if anyone else wants to use Haml in a .Net product, they're going to find their experience with NHaml actively supported and they'll be able to contribute to the current development line.