net comments edit

Greg pointed me to this pretty cool all-in-one API reference site. If you’re a developer, you’ll want to check this out: ~Got API?~

Update 2/1/17: The site has apparently gone out of business. Link removed because it turned into some weird porn spam thing.

I was sitting here, minding my own, when the alarm went off for a fire drill.

Normally fire drills take place on a nice sunny day, so it’s not a big deal - you quickly pack up your stuff (because who knows how long you’re going to be outside, plus you want to make sure if it’s a real fire that your iPod won’t be burning) and follow the herd to whatever arbitrary meeting spot you’re supposed to be at. That’s generally followed up by some milling about, laughing about the inconvenience of it all and wondering how much money is actually being spent on the drill due to lost productivity.

Today’s drill started out the same, packing everything up and following the crowd, but the wrench in the works is that it was pouring rain outside, so everyone was outside shivering and getting soaked through to the bone. In a word, it sucked. Plus the lost time. I’m totally wet now, sitting here trying to re-focus on what I was working on, and, frankly, it’s just not happening. Maybe I need to head into the bathroom and dry off with some paper towels.

gists, csharp, build comments edit

We use NAnt to automate our build process, and right now I’m working on refactoring the build that my group uses for continuous integration. One of the things I noticed is that when our product builds, the main build file “includes” a few other build files and executes targets from them. One of the build files that gets included only ever has one target called, and it does a bunch of internal work to get a lot of things done. It looks a lot like this:

Build script
flow

Notice how there’s only one entry point in the external build file and the tasks inside call other tasks, some of which are common, almost like NAnt “functions” that pass parameters by setting properties. Not only that, but part of the build output for the product is to include this build script so other products can include it and use it in the same way. I don’t know about you, but this says “custom NAnt task” to me.

In converting this to a custom NAnt task, I found that part of what the script was doing was calling other custom NAnt tasks. Not wanting to replicate all of the functionality of these other custom NAnt tasks, I figured I’d write my custom task to call the other tasks programmatically.

Interestingly enough, this isn’t as straightforward as you might think, and NAnt documentation on this is, well, light. You can’t just create the task object and call it, you actually have to give the created task some context about the environment it’s working in. You do this by calling the CopyTo method on the task object. By and large, the way it looks is this:

using System;

using NAnt.Core;
using NAnt.Core.Attributes;
using NAnt.Core.Tasks;

namespace MyCustomNAntTasks {
  [TaskName("customtask")]
  public class MyCustomTask : Task {
    protected override void ExecuteTask() {
      this.Log(Level.Info, "Starting custom task...");

      // Create and execute a <tstamp /> task
      this.Log(Level.Verbose, "Executing a tstamp task...");
      TStampTask tstamp = new TStampTask();
      this.CopyTo(tstamp);
      tstamp.Execute();

      // Create and execute a <sysinfo /> task
      this.Log(Level.Verbose, "Executing a sysinfo task...");
      SysInfoTask sysinfo = new SysInfoTask();
      this.CopyTo(sysinfo);
      sysinfo.Execute();

      this.Log(Level.Verbose, "Executing custom work...");
      // TODO: Insert your custom task's work here

      this.Log(Level.Info, "Custom task complete.");
    }
  }
}

That seems to work well for most tasks. Some tasks require more initialization than just CopyTo, like the setting of properties or what-have-you, so you’ll need to set that stuff up for things to work since you don’t get the validation benefits that you get when NAnt parses the build script and tells you when you’re missing required values.

One task I haven’t gotten to work like this is the <csc /> task - for some reason, I haven’t figured out how to properly add references to the task to get it to work. Instead of calling <csc />, I ended up writing a quick method using the Microsoft.CSharp.CSharpCodeProvider to compile things directly.

Minor update: I actually ended up having to use an <exec /> task to build the code rather than the Microsoft.CSharp.CSharpCodeProvider because I didn’t see a way with the code provider to specify a target framework, whereas you can call the framework-specific csc.exe based on NAnt project settings and the correct framework will be used.

Saturday was an errand day (running around to various stores, picking things up as needed, general taking-care-of-business) followed by a bit of evening gaming with Stu, but Sunday… Sunday almost all day was dedicated to Tomb Raider: Legend. I think I must have played for six hours. They really did an awesome job with it and I’m having a great time.

In other news… I should shortly have a new version of CR_Documentor out that will not only let you preview the XML doc but will also preview the member syntax box inline with the doc, just like the NDoc output. I’ve got some folks doing some testing for me to make sure it doesn’t break anything, but that should be done soon. I’ll keep you posted.