Part 2: Time to change
In part #1 of the series I covered the problems that I had faced over the last few years in delivering software development projects on time and budget. I recognised that I wanted to change my approach to improve my rate of success and reduce the effort required when hurtling towards deadlines, the only question was where to start?
It was the start of a journey that's still very much in progress. I had no idea at that time whether it was an agile methodology or just improving upon existing processes that I needed. I just knew I wasn’t getting it right. I’ve made mistakes along the way and will no doubt continue to make them so I’ll try and highlight some in this series. The important thing for me though is that my team learned the same lessons as I did from those mistakes and from that collective experience we all benefitted as a result.
Step 1: Code quality
Unlike project quality, code quality should never be sacrificed for time and budget reasons in a project, doubly so for one that has on-going maintenance and development, it is FAR harder to maintain and extend poor quality code and it incurs a huge level of technical debt. I know because I had lots of it. Spaghetti code that was inconsistent and hard to maintain.
The only question was where to start?
I had some previous experience with using FxCop and StyleCop and valued the benefits and uniformity it brought to my code so I started with that. I wanted to bring some measure of consistency to the codebase in our projects and have a safety net to help spot common anti-patterns, promote best practice and highlight potential bugs in the code. The team wanted this too but they didn’t want it to be too onerous a process.
First I sat down with my team and got a consensus of the rules we would use so we were all starting from the same place. Some of these rules are like marmite, you either love them or hate them so it's important to include your team and get a consensus up front about which you will use. This shouldn’t mean that they can’t be reviewed by the team and changed over time though.
Having agreed the rules and gotten StyleCop and FxCop installed on all the dev machines, I set up the rules into a file on a shared folder we could all import them from. We all agreed that we should pay heed to the errors or warnings that these rules generated and fix them before we checked code into our repository.
Ultimately this approach failed as the voluntary nature of running StyleCop and FxCop manually became forgotten, or in frustration was avoided by changing the settings on their desktops. I ended up nagging the team each week about the number of error and warnings that the code generated and considered it a failed strategy.
The next small step was the addition of after build event as part of the project settings in Visual Studio 2008. Now when the developers ran a build FxCop would run automatically, so whilst the warnings it generated were largely ignored, the exceptions were fixed in order to get the solution to successfully build.
StyleCop was still optional and largely ignored. Again over time the settings were modified on each developers machine to turn off rules due to frustration or time. Every developer ended up with differing rules, the code quality suffered and despite the small victory in seamlessly getting the FxCop errors corrected as we went along, it was time to admit failure #2
This attempt coincided with a move away from MS SourceSafe to Subversion as our main form of Source Control. One of the reasons for the shift was pre-commit hooks, the other was I absolutely hated SourceSafe. Having moved the source code into VisualSVN server and adopted VisualSVN Client for Visual Studio I sat down to plan. I wanted to tackle the problem at source (or source control to be more exact). If code could not be committed without passing a fixed set of rules then complying with the rules was no longer optional. It is via the use of hooks that I started with.
First I got a copy of SVNStyleCop and tweaked the code till I had it running with a pre-commit hook on all our code repositories. The StyleCop rules were located on the server and not accessible to change for the developers so after a final discussion with the team and a code commit amnesty the pre-commit hooks were applied.
Rather than have to comply from day one requiring a large refactoring effort, every time a file is changed and committed it is updated to comply with the current rules agreed by the team.
At first there were some grumbles and extra time spent trying repeatedly to commit code changes but the number of StyleCop warnings decreased and code started to look a lot more consistent. It still wasn’t perfect and the maintenance of updating all the StyleCop setting and FxCop rules was error prone and often frustrating.
The team wasn’t unhappy, they all agreed that maintaining code that was consistently laid out was easier to comprehend, nicer to work with and the enforcement at the server was somewhat habit forming to their coding styles, but being truthful they weren’t exactly happy either, the process was still too onerous. It was the first sign of partial success though.
The main changes this time were easing the maintenance of getting consistent settings across the development machines. Until then, the developer’s FxCop and StyleCop settings were just imported from a file in a shared folder, each change would require the master copies to be updated and then all machines to be manually updated again. It was time consuming and unreliable which yet again involved nagging and grumbles.
To tackle this, first the settings files were copied into a repository with restricted write access which we called GlobalDependencies. This master files were then included as part of an svn:externals property in each repository (our repositories generally are organised by solution)
For StyleCop a link file was included in every project, because the link is a relative path, provided you do not nest projects (we use solution folders to organise our projects) the link files never change and became just part of the project file furniture. Below is a sample of each project’s settings file, pointing to the master copy
For FxCop (in Visual Studio 2008*) we modified the FxCop PostBuild event to pass in our settings file to the FxCopCmd.exe tool. Now each time the master settings files were changed and committed to the GlobalDependencies repository, they were updated from the svn:externals property in every solution. One change, updated everywhere.
This time we negated the grumbles about all the settings updates and “I don’t have that rule enabled” discussions which was another partial success; but now the team couldn’t tweak the rules and StyleCop was still manually run (once in a while) so they still weren’t satisfied that the process was invisible enough not to be a constant annoyance… so I went back to the drawing board once more.
* Visual Studio 2010 has since introduced CodeAnalysis as a first class citizen negating the need for an FxCop postbuild event, this will be covered later, as in this timeline, we haven’t yet arrived at VS2010.
Attempt #5 TBC
The next attempt was intrinsically linked to the adoption of two fairly large changes to our development process which in many ways were instrumental to THE epiphany I had on the road to code quality and agile development and as such is hard to separate from what comes next, so it provides a natural break in the story for now.
The summary bit
So far all I’d really done was annoy the team with lots of coding rules through a wonky process in a quest for code quality with the aim to improve code maintainability and reduce bugs. I didn’t realise it at the time but I’d barely scratched the surface of what Code Quality actually covers but as I said at the start of this series. it’s a learning process filled with mistakes and it’s learning from those mistakes that is important.
Part 3 – The epiphany >>