Why can’t people just make things simpler?

Previously I discussed how to automate a SQL Build. One of the things I mentioned was the inability to get a clean list of source code file changes from FinalBuilder (FB) without all the shelf set gibberish. I mean, who really wants to parse a huge set of text trying to find the nuggets of information you need if you don’t have to? Looks like I need to break out Visual Studio!

FinalBuilder comes with a set of API’s to customize ANYTHING so that it can be used with FinalBuilder. This is a two-step process (which I will over simplify):

  1. Write a .NET compliant DLL that:
    1. References the necessary VSoft API.
    2. Inherits from one of the core abstract classes.
  2. Create an Action Package in FinalBuilder Action Studio so that:
    1. FinalBuilder can call the custom DLL.
    2. The custom DLL can get parameters passed to it.

The first thing you need to know is that VSoft’s documentation on their API is less than stellar…way less…OK, it’s non-existent. It took me a couple of weeks, and several emails to the VSoft blokes Down-Under, to figure out how to get an action compiled, set it up in action studio, and deployed in a FB project. The API allows three basic actions, which come with matching abstract classes:

  • ExecuteProgramAction – Used to launch external processes from FB project.
  • StandardAction – Used to interact with a custom .NET DLL.
  • IteratorAction – Used to build a list to iterate through (similar to a For-Each loop) from .NET.

As far as my DLL is concerned, I needed an iterator that interfaced directly. This is how it’s done:

  1. Create a DLL project in Visual Studio.
  2. Add necessary references to the VSoft API.
  3. Create a new class by inheriting from the abstract IteratorAction class.
  4. Add necessary TFS API references.
  5. Inherit the abstract class and implement the required methods. In this case the constructor, InitializeIterator(), Validate(), and GetCurrentValue.
    1. I used Validate() to insert code necessary to validate the properties being sent to my DLL.
    2. InitializeIterator() housed the main logic used to gather the necessary source code files (TFS Items). It looked something like this (condensed for brevity)…
// Define TFS variables.
private TeamFoundationServer _tfs;
private VersionControlServer _vcs;
// Create a list to contain the source code file references.
List<Item> _itemSet = new List<Item>();
// Create objects for TFS and the client services.
_tfs = new TeamFoundationServer("tfs.humana.com");
_vcs = (VersionControlServer)_tfs.GetService(typeof(VersionControlServer));
// Pull required properties from FB.
_projectPath = ExpandProperty("ProjectPath", true);
bool bValid = DateTime.TryParse(ExpandProperty("SetFromDate", true), out _lastBuildDT);
// Given a path within TFS, find all source code files within that path.
localSet = _vcs.GetItems(_projectPath, RecursionType.Full);
// Loop through all the source code files
foreach (Item i in localSet.Items)
{
// finding all the source code files that have been altered after a given date
if ((i.ItemType != ItemType.Folder) && (i.CheckinDate.CompareTo(_lastBuildDT) > 0))
{
// and add them to the list container.
_itemSet.Add(i);
}
}
  1. Once initialized, FB will used the GetCurrentValue method to pull item based on position. The latest version of FB uses a 1 based (vs. 0 based) starting position of the iterator, so code the method appropriately:

    // Return the string (TFS path) of the TFS Server Item.

    return _itemSet[iteration-1].ServerItem.ToString();

     

  2. The only other thing we need is to get the parameters from FB when called, and that is accomplished through the protected property ExpandProperty from the base class BaseAction. This is probably the biggest gotcha and is not explain very well. In a nutshell, the properties you define in Action Studio are called via ExpandProperty to get a value from the FB interface to your DLL. ExpandProperty can be called anytime in the life of your object, even in the constructor. There are also ways to: SetProperty, SendMessage, GetFileSet, GetString,…..All of which are available from the base class BaseAction.
  3. Once I compiled the DLL, I had to move the following files to \\[machine/drive]\Program Files\FinalBuilder 7\ActionDefs\Assemblies\2.0:
    1. FBIntegration.DLL (My new DLL.)
    2. Supporting DLL’s (DLL’s that are being referenced by my DLL…In this case the TFS DLL’s.)

OK…So the DLL is built, now we have to use the DLL to create an action that a FB project can use.

  1. Open FB Action Studio and create a new action package.
  2. While in the new package, create a new action.
  3. Add all the properties that will be passed to the DLL via ExpandProperty, in this case I required:
    1. ProjectPath – TFS path to the set of files I want to check.
    2. SinceDate – A date that represents a cutoff point for changes to be included in the list.
  4. Create a property page (interface form). This will be the representation of your action while interacting with the FB project. I added three controls to the page:
    1. Last Date Time – Corresponds to the SinceDate property being sent to the DLL.
    2. TFS Path – Corresponds to the ProjectPath property being sent to the DLL.
    3. Iterator Variable – Variable that will be stuffed with the GetCurrentValue method’s return value.
  5. On the Action Details section, add two entries (found on the bottom of the page). These tell the action which DLL to use and which class is associated with the action.
    1. Namespace.Classname – In my case this was somthing like Company.Unit.FBIntegration.ChangedItemIterator.
    2. Assembly – Which is the name of the DLL or FBIntegration.dll
  6. Save the package, using an appropriate name for both the package and action.

Done! Now if I open FB can see a new category with a new action item in it (TFS Change Iterator). The best part is that this can be done with anything that can be coded in .NET, so the possibilities are pretty much endless. In fact, this might be a good candidate for a VSoft packaged component. If you do happen to go down this road, I would be happy to guide you and help out.

Leave a Reply