<configuration>
<configSections>
<section name="LOCTargets"
type="ConsoleApplication2.TFSConfigSection, TFSChangeLOC" />
</configSections>
<appSettings>
<add key="OutputFilePath" value="C:\Users\xingy\Desktop\LOCdemo.html"/>
</appSettings>
<LOCTargets>
<add LocalPath="C:\SPA_5150\Apps\IntelligentRewards\dev\source"
StartChangeSetId="373171" EndChangeSetId="373173"/>
<add LocalPath="C:\SPA_5150\Apps\Framework\source"
StartChangeSetId="373165" EndChangeSetId="373170"/>
</LOCTargets>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>
class Program
{
static int addNumber = 0;
static int delNumber = 0;
static int editNumber = 0;
static int otherNumber = 0;
static int renameNumber = 0;
static Dictionary<int, int> changeSetDic = new Dictionary<int, int>();
static List<string> changedFiles = new List<string>();
static void Main(string[] args)
{
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
TFSConfigSection section = config.Sections["LOCTargets"] as TFSConfigSection;
foreach (Target locTarget in section.Instances)
{
TFS(locTarget.LocalPath,locTarget.StartChangeSetId,locTarget.EndChangeSetId);
}
ScanFiles();
OutputHtmlFile(changeSetDic);
Console.WriteLine("Press Any Key to Exit ... ...");
Console.Read();
}
private static void TFS(string localPath,string startId,string endId)
{
Uri tfsUri = new Uri("http://rnotfsat:8080/tfs");
string tfsPath = null;
try
{
TfsConfigurationServer configurationServer =
TfsConfigurationServerFactory.GetConfigurationServer(tfsUri);
// Get the catalog of team project collections
ReadOnlyCollection<CatalogNode> collectionNodes = configurationServer.CatalogNode.QueryChildren(
new[] {CatalogResourceTypes.ProjectCollection},
false, CatalogQueryOptions.None);
// List the team project collections
foreach (CatalogNode collectionNode in collectionNodes)
{
// Use the InstanceId property to get the team project collection
Guid collectionId = new Guid(collectionNode.Resource.Properties["InstanceId"]);
TfsTeamProjectCollection teamProjectCollection = configurationServer.GetTeamProjectCollection(collectionId);
if (!teamProjectCollection.Name.Equals(@"rnotfsat\rnotfsat"))
continue;
var vcs = teamProjectCollection.GetService<VersionControlServer>();
var workSpace = vcs.GetWorkspace(localPath);
tfsPath = workSpace.GetServerItemForLocalItem(localPath);
var changesetList = vcs.QueryHistory(
tfsPath,
VersionSpec.Latest,
0,
RecursionType.Full,
null,
VersionSpec.ParseSingleSpec(startId, null),
VersionSpec.ParseSingleSpec(endId, null),
Int32.MaxValue,
true,
false).Cast<Changeset>();
foreach (var cs in changesetList)
{
changeSetDic.Add(cs.ChangesetId, 0);
var changeList = cs.Changes;
foreach (var change in changeList)
{
if (change.Item != null)
{
var localFile = workSpace.GetLocalItemForServerItem(change.Item.ServerItem);
if (change.ChangeType.HasFlag(ChangeType.Edit))
{
if (!changedFiles.Contains(localFile))
{
changedFiles.Add(localFile);
}
editNumber++;
}
else if (change.ChangeType.HasFlag(ChangeType.Add))
{
if (File.Exists(localFile))
{
changeSetDic[cs.ChangesetId] += File.ReadLines(localFile).Count();
addNumber++;
}
}
else if (change.ChangeType.HasFlag(ChangeType.Rename) ||
change.ChangeType.HasFlag(ChangeType.SourceRename))
{
renameNumber++;
}
else if (change.ChangeType.HasFlag(ChangeType.Delete))
{
delNumber++;
}
else
{
otherNumber++;
}
}
}
}
}
}
catch (ChangesetNotFoundException)
{
Console.WriteLine("!! Please check the change set id inside your config file !!");
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
private static void ScanFiles()
{
Console.WriteLine("In total {0} files will be scanned !", changedFiles.Count);
Console.WriteLine();
Console.WriteLine();
int left = changedFiles.Count;
foreach (var csFile in changedFiles)
{
GetContent(changeSetDic, csFile);
Console.WriteLine(csFile + " is scanned and analyzed !");
left--;
Console.WriteLine("{0} files left.", left);
}
}
private static void GetContent(Dictionary<int, int>csDic, string filePath)
{
Process proc = new Process();
proc.StartInfo.FileName = "tfpt";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.Arguments = " annotate \"" + filePath + "\" /noprompt";
proc.Start();
StringBuilder sb = new StringBuilder();
while (!proc.HasExited)
{
sb.Append(proc.StandardOutput.ReadToEnd());
}
string allResult = sb.ToString();
String[] lines = allResult.Split(new [] {Environment.NewLine},Int32.MaxValue,StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
{
var csIdInStr = line.Split(default(string[]), StringSplitOptions.RemoveEmptyEntries);
int csId = Convert.ToInt32(csIdInStr[0]);
if (csDic.ContainsKey(csId))
{
csDic[csId]++;
}
}
}
private static void OutputHtmlFile(Dictionary<int, int> csDic)
{
string htmlSource = File.ReadAllText("HTMLTemplate.html");
int totalCount = 0;
StringBuilder sb = new StringBuilder();
foreach (KeyValuePair<int, int> kv in csDic)
{
sb.Append("<tr><td>").Append(kv.Key).Append("</td><td>").Append(kv.Value).Append("</td></tr>");
totalCount += kv.Value;
}
htmlSource = Regex.Replace(htmlSource, "yukunContent", sb.ToString());
htmlSource = Regex.Replace(htmlSource, "yukunTotal", totalCount.ToString());
htmlSource = Regex.Replace(htmlSource, "AddNumber", addNumber.ToString());
htmlSource = Regex.Replace(htmlSource, "EditNumber", editNumber.ToString());
htmlSource = Regex.Replace(htmlSource, "DeleteNumber", delNumber.ToString());
htmlSource = Regex.Replace(htmlSource, "OtherNumber", otherNumber.ToString());
htmlSource = Regex.Replace(htmlSource, "RenameNumber", renameNumber.ToString());
File.WriteAllText(ConfigurationManager.AppSettings["OutputFilePath"], htmlSource);
}
}