Wednesday, May 9, 2012

TFS Queries: Searching in all files of the source control

For an intro on LinqPad and the TFS API please read this post
For the list of all the posts in this series please read this one

Context


Searching in all files of a solution inside Visual Studio is very useful. In TFS you can search for files of a collection but there is no built in functionality to search for text inside those files. Using the TFS API we can do this kind of thing.

Required references


Microsoft.TeamFoundation.Client.dll
Microsoft.TeamFoundation.Framework.Client.dll
Microsoft.TeamFoundation.VersionControl.Client.dll

Query (C# Program)

string[] textPatterns = new[] { "Main(string", "(this " };
string[] filePatterns = new[] { "*.cs", "*.xml", "*.config" };

void Main()
{
 var tfs = TfsTeamProjectCollectionFactory
  .GetTeamProjectCollection(new Uri("http://localhost:8088/tfs"));

 var versionControl = tfs.GetService<VersionControlServer>();
 
 var teamBranches = versionControl.QueryRootBranchObjects(RecursionType.Full)
  .Where (s => !s.Properties.RootItem.IsDeleted)
  .Select(s => s.Properties.RootItem.Item)
  .ToList()
  .Dump("Searching in the following branches");
 
 filePatterns.Dump("File patterns");
 textPatterns.Dump("Text patterns");

 foreach (var teamBranch in teamBranches)
  foreach (var filePattern in filePatterns)
   foreach (var item in versionControl.GetItems(teamBranch + "/" 
    + filePattern, RecursionType.Full).Items)
    SearchInFile(item);
}

// Define other methods and classes here
private void SearchInFile(Item file)
{
 var result = new List<string>();
 var stream = new StreamReader(file.DownloadFile(), Encoding.Default);
 
 var line = stream.ReadLine();
 var lineIndex = 0;
 
 while (!stream.EndOfStream)
 {
  if (textPatterns.Any(p => line.IndexOf(p, StringComparison.OrdinalIgnoreCase) >= 0))
   result.Add("Line " + lineIndex + ": " + line.Trim());
 
  line = stream.ReadLine();
  lineIndex++;
 }
 
 if (result.Count > 0) result.Dump(file.ServerItem);
}

Result


You will get all the lines and line numbers matching the text search patterns for all files matching the file search patterns. This may take a lot of time (30 minutes on some occurrence so be careful!). You might want to add more restrictions, especially the the branches to query around line 12.



5 comments:

TrayKarn said...

Hello, I am very happy to see this. Although I think that this is for tfs2010. Is there any way you could show what changes are required to perform this sort of querying in tfs2008??? I would find it very helpful.

Pascal Laurin said...

Hi TrayKarn,

You are right, I'm targeting TFS2010 and even TFS2012 for some of the latest queries. Unfortunately, I know that the API changed a bit since previous versions. Looking at the MSDN documentation I can only find information on TFS2005 http://msdn.microsoft.com/en-us/library/bb130334(v=vs.80) and I can see a lot of changes. I know that VersionControlServer doesn't have QueryRootBranchObjects on it and that you can't use TfsTeamProjectCollectionFactory but something else. The rest of the query should not change much but as I don't have access to a TFS2008 server I cannot test the changes required.

Sorry about that.

TrayKarn said...

No worries thanks for the reply.

Coepd BA Trainings said...

We at COEPD glad to announce that we have introduced Dot Net Technologies Internship Programs (Self sponsored) for professionals who want to have hands on experience. This program is available in COEPD Hyderabad premises which is accompanied by IT Companies. It is intelligently dedicated to our firm participants predominantly acknowledging and appreciating the fact that they are on the path of making a career in Dot Net Technologies discipline. We assume Object-Oriented Programming concepts and teaches C#.NET, ADO.NET which helps the interns to build database-driven Web applications and Web Sites successfully. This internship is designed to gain theoretical knowledge and also hands-on practice and practical know-how to master the nitty-gritty of the Dot Net developer profession. More than a training institute, COEPD today stands differentiated as a mission to help you "Build your dream career" - COEPD way.

http://www.coepd.com/DotNet-Internship.html

Pinnacle Web Solutions said...

Thanks a lot , it worked like a charm...

Just need to add following Nuget (Microsoft.TeamFoundationServer.ExtendedClient) to get the referenced Assemblies