I’ve been working on integrating a set of code scanning tools into our build system. Test code needs to be trustworthy – when test code fails, it should indicate a product failure. More importantly, when tests pass, they better indicate that the functionality under test works. One part of increasing quality is getting rid of the coding errors that are most prone to causing test failures. This includes a basic set of fxcop rules for managed code, similar rules for native code, and specific checks for hard coded paths, hardcoded passwords, and other easy to spot things that will eventually cause false positives.
The framework we use requires “hints” to find the reference libraries at compile time (basically, we run fxcop against every managed assembly at build time and track a full list of errors). The hints are just a pointer to the library in the project xml file. It’s a bit of a pain, but completely worth it in the end. I spent a few hours last week building a portion of the tree, reviewing the errors for the references the framework couldn’t find, adding them, then verifying the additions. Lather, rinse, repeat.
I made a ton of progress in those few hours, but stopped because it just didn’t seem efficient. I was doing other work during the builds, so I felt productive, but it just didn’t seem right. So, I stopped and did other work. As I look back on it, it wasn’t really even a conscious decision – I just sort of mentally reprioritized that task.
Today, for some reason, I decided to take another look. I thought about it for about two minutes and had a solution. It was so dirt simple that I’m embarrassed it wasn’t my first choice. Rather than build part of the source code, review the errors, find the binary, and add the hint, I took care of it all at once. When the framework couldn’t find a reference, it put an error in the log file something like this:
Could not find reference – Microsoft.Internal.Foo
It printed one of these for every reference it couldn’t find, so I just built everything – and while it was building, I wrote a script that would parse out the reference name, look for the binary on disk, normalize the paths, remove the duplicates (multiple projects will share references), then add the appropriate xml to the project file. Total time on task was about 20 minutes and it worked perfectly.
The point of all this is that I realize that I do stuff like this all the time. I often dig into a problem, pause (or leave), and then come up with an optimal solution. Part of me thinks that I should recognize the optimal solutions the first time, but another part of me wonders if I’d be able to come up with good solutions if I didn’t get my hands dirty first. I’ll pay more attention and let you know how it goes.