The situation is simple:

  • we need to send messages to another system
  • the developers of the other system need documentation on the layout of these messages
  • this is a company-specific protocol (no JSON or anything standard, because we’re talking to old Fortran machines here)
  • naturally, the documentation is made in Word files

Taking an example from a session I saw at ngEurope, I decided we might be better off auto-generating this documentation. Keeping Word files in sync with the evolving code is a tedious, manual process, not to mention that the Word files are never in sync 10 years down the road.

And as the code is the single point of truth, I started on automating the process. I hate repeating manual things. It’s boring, allows for manual error (I remember updating a production SQL database instead of the beta database!), and needs to be taught to newcomers time and again.

So:

After having written code to generate the documentation (too specific to put here), I needed a way of having the build automatically add the new file to the pending changes, or if nothing had changed, undo the checkout (sadly, I’m on TFS; git would not have this problem).

So this is how you can compare a local file with the server version of the file:

private bool HasFileChanged(string file, TfsTeamProjectCollection server, Workspace workspace)
{
    string diff;
    var versionControlServer = server.GetService<VersionControlServer>();
    var serverPath = workspace.GetServerItemForLocalItem(file);
    var serverVersion = new DiffItemVersionedFile(versionControlServer, serverPath, VersionSpec.Latest);
    var localVersion = new DiffItemLocalFile(file, Encoding.UTF8.CodePage, DateTime.Now, false);
    using (var stream = new MemoryStream())
    using (var writer = new StreamWriter(stream))
    {
        var diffOptions = new DiffOptions
        {
            Flags = DiffOptionFlags.EnablePreambleHandling,
            OutputType = DiffOutputType.Unified,
            TargetEncoding = Encoding.UTF8,
            SourceEncoding = Encoding.UTF8,
            StreamWriter = writer
        };

        Difference.DiffFiles(versionControlServer, serverVersion, localVersion, diffOptions, serverPath, true);
        writer.Flush();

        diff = Encoding.UTF8.GetString(stream.ToArray());
    }

    return diff != "";
}

The server and workspace variables can be made like this:

var workspaceInfo = Workstation.Current.GetLocalWorkspaceInfo(file);
var server = new TfsTeamProjectCollection(workspaceInfo.ServerUri);
var workspace = workspaceInfo.GetWorkspace(server);

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

This site uses Akismet to reduce spam. Learn how your comment data is processed.