This post is the first in a series of posts talking about the ingredients that have gone into the project so far. I'm still acutely aware that there's no public code yet, but as a sort of stalling tactic, let me talk about some of the things that have gone into the project so far. This first part is a look back at the first few days of the project, way back in November last year.
If we use a bread-baking analagy (a crummy analagy, I know), these ingredients are the standard essentials whether you're making .Net web-bread or Java app-bread - things like a bread tin (source control), an oven (continuous integration tools), a rolling pin (build tools), etc. My next few posts will look at some of the later ingredients in the process, such as the tools I'm using for testing, exception handling and event logging, isolation frameworks , dependency injection, etc.
No matter what I'm doing with code, these are my 3 minimum ingredients for me to feel safe and happy. Every project I work on will have these tools or something very similar involved.
First off, before I do anything, I need somewhere to keep my code safe. There used to be a time when my idea of "safe code" was having a copy on a floppy disk at a mate's house, or every couple of days making a copy of my code in a backup folder, just in case I did something stupid and screwed my app up. This was back in my C++ days, where a single dodgy pointer would trigger "odd" behaviour throughout an entire app (really obscure things, like drop-down boxes not painting their lists correctly).
Then along comes versioned source control software - suddenly I can take snapshots of my code base and store them in a database, where I can then see what changes were made to which files, and when. Using Subversion for example, I can ask for what changes were made to all or parts of my codebase between two dates, or I can take an individual file and see who last changed which lines of code when, it's pretty ninja stuff.
Anytime between about 5 years ago and about 4 weeks ago, I would automatically go to Subversion for this stuff. It's tried, I trust it (I'm 99.999% sure noone has EVER lost work to Subversion without clicking a button labelled "Use repository"), and there's good 3rd party tool support for it. I use AnkhSVN for Visual Studio integration, I use TortoiseSVN for Windows Explorer integration, WinMerge for looking at diffs, everything's good.
But what happened 4 weeks ago? First off, for this project rest assured I'm sticking with Subversion for now. But recently somebody at work asked me what I knew about Git, and not being one to say "nothing", I did some digging. I'm pretty impressed, DEFINITELY for open source work, maybe in the future I'll look at this more, and I'd welcome any comments on this one.
Now my code's safe (love you, Subversion), I need some assurances that my code is correct, I need some build and integration.
99% of the time when I'm working with code, I'm using some sort of IDE - Visual Studio for example. Of course my IDE will give me access to build tools, so when I'm building my project I can be sure that on my computer, the copy of the code that I have checked out is of a minimum quality. My compiler will tell me if it can't compile my code, and I'll get warnings for a lot of things that I would need to fix.
But what else can I do to check the quality of my code? There are a few more things I can do:
- I can write unit tests - little blocks of code that trigger parts of my app and check that they do what they should
- I can use code quality tools such as FxCop
- There are other tools that look at my unit test coverage - how much of my real app is exercised by unit tests - for example NCover or PartCover
- Tools such as NDepend can steer me away from some architectural problems in my app
- I can deploy my app and run UI tests, perhaps automated using tools such as Selenium
- I'm sure there's a whole ton of other potential things I could do
So we can see quite an extensive list of things that I could do to check up my app and my code quality. Am I likely to manually do many of these things on a regular basis? Hell no, if I wanted to do all of the above a couple of times a day, we'd be talking hours of work. So what's my alternative? Automation of course. And this is where automated build comes in.
The automated build tool that I personally use is NAnt, so even though NAnt may be pretty olde-worlde stuff (2 months shy of a decade), I'm sticking with it. Nant gives me the ability to write XML files that automatically run all of the above processes and collate the results, so that I can just run a single command line and get back either a pass, or a fail. In the case of a failure, I can then dig in to see why my build has failed, it could be that unit tests have failed, or my code coverage has fallen below a certain threshold, for example.
A Continous Integration (CI) system is a tool that constantly monitors the code in your source control system, and when it sees something's changed, it loads up the newly changed code and runs some automated processes to verify it's still good. In my case, I get my CI tool to simply run my automated build scripts, which will try to build my app, run my unit tests and integration tests, run some metrics on it to make sure that enough of the code is tested, and that the naming conventions are still consistent, etc. The purpose of a CI tool is to give confidence that there's a minimum quality to your code in your code repository and that your app is at least not-broken, or with the right automated code tests, your app can be proven to be almost bug free.
My integration tool of choice is currently Jenkins CI (hopefully the spin from this dude involved in the new Jenkins project is correct, and I won't be moving back to Hudson anytime soon). I've had some experience of CruiseControl where I work, and while it does the job, I am loving the ease-of-configuration that Jenkins offers, and the plugins are pretty darn good too. It's about the easiest server I've ever setup, and it does the job. The only wrinkle I found with it, it seems a bit of a kludge the way I've currently got a system-tray RSS tool installed (FeedNotifier) to receive and pop-up build notifications.
So to summarise, we've not gotten as far as actually writing any code, and so far we've had to spin up and configure at least the following tools:
- Apache Subversion (http://subversion.apache.org/) version control system, cost = 1 or 2 hours to get my home server correctly setup + 1 or 2 hours to work around Windows Home Server's funky fake-RAID
- TortoiseSVN (http://tortoisesvn.tigris.org/) Windows Explorer integration, cost = minutes to download and configure, job done.
- WinMerge (http://winmerge.org/) differencing and merging tool, cost = free, it's already installed on every machine I've ever touched.
- AnkhSVN (http://ankhsvn.open.collab.net/) Visual Studio integration, cost = minutes to download and configure, job done
- Jenkins CI (http://jenkins-ci.org/) for continuous integration, cost = minutes to download and configure + few hours playing to get the FHEMDotNet project building successfully
- FeedNotified (http://www.feednotifier.com) for Jenkins build notifications = 1 hour to find the right tool, minutes to download and configure
- NAnt (http://nant.sourceforge.net/) for automated builds, cost = 1 hour to install command line tools, few hours to write a working build script that runs on local and CI server