在软件开发过程中,跟踪和管理缺陷修复是一项重要的任务。为了满足这一需求,可能会需要生成一份报告,以识别缺陷是在哪个分支上被修复的,例如开发分支还是发布分支。仅通过创建TFS查询,无法获得每个变更集的详细信息以及与相应变更集相关联的源代码控制项的详细信息。因此,决定创建一个程序,使用Microsoft.TeamFoundation库来生成Excel报告。
首先,使用Visual Studio创建一个控制台应用程序,并在“引用管理器”对话框的“扩展”标签页中添加以下引用:
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Framework.Client;
using Microsoft.TeamFoundation.Framework.Common;
using Microsoft.TeamFoundation.VersionControl.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Configuration;
using System.Data;
using System.IO;
using System.Linq;
接下来,在app.config文件中添加一些键值对,用于指定TFS服务器、查询名称和正在查找的分支:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<appSettings>
<add key="TfsServer" value="http://tfs.yourServer.com:8080/tfs" />
<add key="TfsProjectName" value="YourTFSProject" />
<add key="TfsQueryGroup" value="My Queries" />
<add key="TfsQueryName" value="YourQuery" />
<add key="ExcelFile" value="C:\TfsReport.xls" />
<add key="DevBranchName" value="YourDevelopmentBranch" />
<add key="ReleaseBranchName" value="YourReleaseBranch" />
</appSettings>
</configuration>
现在,开始编写代码,首先连接到TFS服务器并获取关心的TFS项目:
TfsConfigurationServer configurationServer = TfsConfigurationServerFactory.GetConfigurationServer(
new Uri(ConfigurationManager.AppSettings["TfsServer"]));
CatalogNode catalogNode = configurationServer.CatalogNode;
ReadOnlyCollection<CatalogNode> tpcNodes = catalogNode.QueryChildren(
new Guid[] { CatalogResourceTypes.ProjectCollection }, false, CatalogQueryOptions.None);
Guid tpcId = Guid.Empty;
foreach (CatalogNode tpcNode in tpcNodes)
{
tpcId = new Guid(tpcNode.Resource.Properties["InstanceId"]);
break;
}
TfsTeamProjectCollection projectCollection = configurationServer.GetTeamProjectCollection(tpcId);
projectCollection.Authenticate();
接下来,需要从TFS查询中获取与选定TFS项目相关联的工作项:
WorkItemStore workItemStore = projectCollection.GetService<WorkItemStore>();
Project project = workItemStore.Projects[ConfigurationManager.AppSettings["TfsProjectName"]];
QueryFolder teamQueryFolder = project.QueryHierarchy[ConfigurationManager.AppSettings["TfsQueryGroup"]] as QueryFolder;
QueryItem queryItem = teamQueryFolder[ConfigurationManager.AppSettings["TfsQueryName"]];
QueryDefinition queryDefinition = workItemStore.GetQueryDefinition(queryItem.Id);
Dictionary<string, string> variables = new Dictionary<string, string> { { "project", queryItem.Project.Name } };
WorkItemCollection workItemCollection = workItemStore.Query(queryDefinition.QueryText, variables);
DataTable dt = CreateDataTable();
为了获取选定项目的工作项的版本控制工件,需要获取选定项目集合的源代码控制/版本控制存储库:
VersionControlServer versionControlServer = projectCollection.GetService<VersionControlServer>();
VersionControlArtifactProvider artifactProvider = versionControlServer.ArtifactProvider;
一旦获得了workItemCollection,需要使用linq查询来获取所有链接的变更集,并找到所需的信息。在这里,只寻找与变更集相关联的源文件路径:
foreach (WorkItem workItem in workItemCollection)
{
DataRow dr = dt.NewRow();
dr["ID"] = workItem.Id;
dr["Title"] = workItem.Title;
IEnumerable<Changeset> changesets = workItem.Links.OfType<ExternalLink>().Select(
link => artifactProvider.GetChangeset(new Uri(link.LinkedArtifactUri)));
foreach (Changeset changeset in changesets)
{
dr["ChangesetId"] = changeset.ChangesetId;
foreach (Change change in changeset.Changes)
{
if (change.Item.ServerItem.Contains(ConfigurationManager.AppSettings["DevBranchName"]))
{
dr["Fix in DevBranch"] = "Yes";
break;
}
else if (change.Item.ServerItem.Contains(ConfigurationManager.AppSettings["ReleaseBranchName"]))
{
dr["Fix in ReleaseBranch"] = "Yes";
break;
}
}
}
dt.Rows.Add(dr);
}
WriteToExcel(dt);
为了填充WorkItem和Changeset的详细信息,可以创建一个数据表,也可以使用其他方法。
public static DataTable CreateDataTable()
{
DataTable dt = new DataTable();
dt.Columns.Add("ID");
dt.Columns.Add("Title");
dt.Columns.Add("ChangesetId");
dt.Columns.Add("Fix in DevBranch");
dt.Columns.Add("Fix in ReleaseBranch");
return dt;
}
以下是使用StreamWriter将填充好的数据表写入Excel文件的函数:
public static void WriteToExcel(DataTable dataTable)
{
StreamWriter streamWriter = new StreamWriter(ConfigurationManager.AppSettings["ExcelFile"], false);
for (int i = 0; i < dataTable.Columns.Count; i++)
{
streamWriter.Write(dataTable.Columns[i].ToString().ToUpper() + "\t");
}
streamWriter.WriteLine();
for (int i = 0; i < dataTable.Rows.Count; i++)
{
for (int j = 0; j < dataTable.Columns.Count; j++)
{
if (dataTable.Rows[i][j] != null)
{
streamWriter.Write(Convert.ToString(dataTable.Rows[i][j]) + "\t");
}
else
{
streamWriter.Write("\t");
}
}
streamWriter.WriteLine();
}
streamWriter.Close();
}