I was working on putting some finishing touches on FwDocGen yesterday, when I came across a subtle bug that took the help of Mike Woodring to figure out. FwDocGen is a fairly straightforward wrapper around an XSLT that takes in XML documentation and produces FlexWiki pages that document the classes, namespaces, etc. in your project. The idea is to produce the equivalent of MSDN docs for your class library, but on a wiki instead.
(Side note: FwDocGen is now released in a fairly usable form.)
Anyway, what I was seeing was that the last part of the documentation for a class would show up twice. That is, the docs would list all the methods, properties, etc., and then part of whatever came last would show up again: a little documentation fragment that was completely out of place.
Naturally my first instinct was that I had screwed up the transform and thrown in one too many <xsl:apply-templates /> calls. But everything checked out there, so I was stumped. I saw Mike was online, and since he's preternaturally smart, I pinged him. Within a few minutes, he had said the magic phrase that turned the light bulb on in my head. “Looks like a truncation problem,” he said. And it was.
The fundamental issue was that I was doing something like the following:
FileStream fs = File.OpenWrite(path);
which is a very handy convenience method for opening a file for write access. Unfortunately, as it says right in the docs, this is the equivalent of saying
FileStream fs = FileStream(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
which is most definitely not the same thing. Why not? Because OpenOrCreate, when accessing an existing file, does not nuke out the contents that are already there. So if you have a file whose contents are
and you do a File.OpenWrite() on it, and then write “123” into it, you get
instead of just “123”. In other words, the file is not truncated on open. Which is probably not what you want. It certainly explained my problem, though. I'd changed the transform so some of the files were shorter, and when I re-ran the program, it wrote the shorter version over the top of the longer version, leaving the extra garbage at the end.
The fix was dead easy. I just swapped out File.OpenWrite for
FileStream fs = FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None);
which works perfectly well. Somewhat confusingly (although it's well-documented), Create still works if the file is already there. But it truncates the file. Thanks Mike!