Skip to main content

Note: This post is part of a series and you can find the rest of the parts in the series index.

IServerPathTranslationService takes the path to your source control item and translates it into a platform neutral path and visa versa. An example for this is if you were moving files between Windows and Linux. On Windows your path may be c:\RangersCode\My Production\ while on Linux that path needs to become/src/RangersCode/My Production/ to handle the differences you need to change it to a neutral path first.

The amount of sleep that I lost on path translation is embarrassing because the concept is dead simple, applying it correctly is ridiculously hard. The de facto guide for how this should work can be found on Willy-Peter’s blog, however there is also an update based on a lot of question asking by me which you may want to read.

This is only needed for VC adapters so if you just want a WI adapter you can skip this.

Power Tip: The neutral path, or canonical path as it is correctly named, is a path that is “Unix like”, (I.e. /src/project/). However these do not follow all the same rules as true Unix paths. For example : is a valid character in the path.

The two methods you need to implement are:

TranslateToCanonicalPathCaseSensitive

This method requires you provide a neutral path for one of your paths. For me this is simply just putting a leading slash on the item’s URL:

public string TranslateToCanonicalPathCaseSensitive(string serverPath)
{
    TraceManager.TraceInformation("WSSVC:TranslationToCanonical - {0}", serverPath);
    string localPath = string.Format(CultureInfo.CurrentCulture, "/{0}", serverPath);
    
    TraceManager.TraceInformation("WSSVC:New:{0} -> {1}", serverPath, localPath);
    return localPath;
}

TranslateFromCanonicalPath

This method is the reverse from TranslateToCanonicalPathCaseSensitive it takes a neutral path and provides one that applies to your adapter. In my case it meant dropping the first character and making sure I had an absolute URI:

public string TranslateFromCanonicalPath(string canonicalPath, string canonicalFilterPath)
{
    TraceManager.TraceInformation("WSSVC:TranslationFromCanonical - {0} - {1}", canonicalPath, canonicalFilterPath);
    string result = new Uri(canonicalPath.Substring(1)).AbsoluteUri;
    TraceManager.TraceInformation("WSSVC:TranslationFromCanonical:Result {0}", result);
    return result;
}

First in the Platform’s Eyes

There is an interesting thing that the platform does when it comes to server path translation, it creates this class first. This is before anything else, like the configuration service, so you need to make sure this class relies on very little, if any ,outside information. During the creation it also takes the root path from the filter items in your configuration and passes it to TranslateToCanonicalPathCaseSensitive to get the root neutral path. It needs to know this because it will want to strip this information out when it passes it to the other adapter and add it back when other adapters pass their paths to you.