Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Programmatically get TFS blame (annotation) data

I'm trying to implement a plugin for Team Foundation Server 2010 that will create reports about users in a team project. Conceptually, all I need in order to properly implement this plugin is access to the same data that you get when you use the "Annotate" feature in Visual Studio: I need to be able to tell who was the last person to author a given line of code.

I've scoured the Internet for documentation or code samples, but all that I can find are either suggestions such as using the TFS command-line tools or seemingly incomplete code samples.

I don't mind doing a lot of heavy lifting in the client code, but there doesn't seem to be an obvious way to get useful authorship data about the contents of the code in a Changeset, nor from the merge details return.

like image 463
MaxML Avatar asked Jul 21 '15 19:07

MaxML


1 Answers

Meanwhile I found a working solution that executes Team Foundation Power Tools process and parses its output:

private readonly Regex m_Regex = new Regex(@"^(?<changeset>\d+)(?<codeLine>.*)", RegexOptions.Compiled | RegexOptions.Multiline);

public List<Changeset> GetAnnotations(string filepath, string codeText)
    {
        var versionControlServer = CreateVersionControlServer();

        return m_Regex.Matches(ExecutePowerTools(filepath))
            .Cast<Match>()
            .Where(m => m.Groups["codeLine"].Value.Contains(codeText))
            .Select(v => versionControlServer.GetChangeset(int.Parse(v.Groups["changeset"].Value), false, false))
            .ToList();
    }

    private static VersionControlServer CreateVersionControlServer()
    {
        var projectCollection = new TfsTeamProjectCollection(new Uri(@"TFS URL"));
        var versionControlServer = projectCollection.GetService<VersionControlServer>();
        return versionControlServer;
    }

    private static string ExecutePowerTools(string filepath)
    {
        using (var process = Process.Start(TfptLocation, string.Format("annotate /noprompt {0}", filepath)))
        {
            process.WaitForExit();
            return process.StandardOutput.ReadToEnd();
        }
    }
like image 182
Boris Modylevsky Avatar answered Sep 28 '22 06:09

Boris Modylevsky