CODE - TFS 檔案異動報表產生器
| | 2 | | ![]() |
工作需求,上線前置作業想從 TFS 版控抓出指定期間異動過的檔案清單,懶得尋覓現成軟體或工具,寫幾行程式自幹搞定。
TF.EXE 有個 History 命令可列舉特定期間(/v:Dyyyy-MM-dd~Dyyyy-MM-dd)特定目錄下(/recursive)所有 Changeset,加上 /format:detailed 還會列出該 Changeset 所異動的檔案清單。參考
tf history /server:http://tfs:8080/tfs/collection-name "$/AP/DEV/src" /recursive /noprompt /format:detailed /v:D2018-10-1~D2018-10-31 > D:\TFS-History.txt
其輸出範例如下,其內容足以產生我所需的報表。(補充一個眉角,TF 執行結果導向 TFS-History.txt,其中文編碼為 BIG5,試過 chcp 65001 也無效,故 .NET 讀取時要加上 Encoding.GetEncoding(950),若有人知道其他解法歡迎留言 )
----------------------------------------------------------------------------------------------------------------
變更集: 10802
使用者: Jeffrey
日期: 2018年10月17日 下午 04:36:33
註解:
跑馬燈顯示調整
項目:
編輯 $/AP/DEV/src/Web/MyWeb/Content/css/website.css
編輯 $/AP/DEV/src/Web/MyWeb/Views/Home/Index.cshtml
----------------------------------------------------------------------------------------------------------------
變更集: 10801
使用者: Jeffrey
日期: 2018年10月12日 下午 04:09:10
註解:
版面加入右側廣告區塊
項目:
編輯 $/AP/DEV/src/Web/MyWeb/Views/Home/Index.cshtml
----------------------------------------------------------------------------------------------------------------
變更集: 10800
使用者: Bob
日期: 2018年10月06日 下午 03:24:01
註解:
選單調整
項目:
編輯 $/AP/DEV/src/Web/MyWeb/Views/Shared/Header.cshtml
程式不難寫,逐行讀入檔案,簡單識別標題、特徵取出變更集號碼、作者、日期、註解及項目,最後輸出成 HTML:
static void Main(string[] args)
{
//發現tf history > *.txt即使chcp 65001也是BIG5編碼,故讀取時需指定語系
using (var sr = new StreamReader(@"E:\TFS-History.txt",
Encoding.GetEncoding(950)))
{
var report = new Dictionary<string, List<string>>();
string line;
int changeSetNo = 0;
string author = "NA";
DateTime date = DateTime.Today;
string comment = string.Empty;
while ((line = sr.ReadLine()) != null)
{
if (line.StartsWith("變更集: "))
changeSetNo = int.Parse(line.Split(' ').Last());
else if (line.StartsWith("使用者: "))
author = line.Substring(5);
else if (line.StartsWith("日期: "))
date = DateTime.Parse(line.Substring(4), new CultureInfo("zh-TW"));
else if (line.StartsWith("註解:"))
{
comment = sr.ReadLine();
}
else if (line.StartsWith("項目:"))
{
while ((line = sr.ReadLine()).Contains("$"))
{
var i = line.IndexOf("$");
var act = line.Substring(0, i - 1).Trim().Replace(", ", "/");
var item = line.Substring(i).Trim();
if (!report.ContainsKey(item))
report.Add(item, new List<string>());
var x = new XElement("span") {Value = $"{changeSetNo} {act}"};
x.SetAttributeValue("title",
$"{author} {date:yyyy-MM-dd HH:mm} {comment}");
report[item].Add(x.ToString());
}
}
}
var sb = new StringBuilder();
sb.AppendLine("<html>");
sb.AppendLine(@"
<head><style>
table { font-size: 9pt; color: #444; width: 640px; border-collapse: collapse; }
td,th { padding: 3px; border: 1px solid gray; }
th { background-color: #679ac3; color: white; font-weight: normal; }
td span { cursor: pointer; color: blue; text-decoration: underline; margin-right: 6px; }
td span:hover { color: purple; font-weight: bold; }
tr:nth-child(even) { background-color: #edeff3; }
</style></head>
");
sb.AppendLine("<body><table><thead>");
sb.AppendLine("<tr><th>項目</th><th>異動記錄</th></tr>");
sb.AppendLine("<tbody>");
foreach (var item in report.Keys.OrderBy(o => o))
{
sb.AppendLine($@"<tr>
<td>{item}</td>
<td>{string.Join(" ", report[item].ToArray())}</td>
</tr>");
}
sb.AppendLine("</tbody></table></body></html>");
File.WriteAllText("E:\\TFS-Report.html", sb.ToString(), Encoding.UTF8);
}
}
最後產生的檔案異動報表如下。Changeset 號碼加了 Title,滑鼠停留時可顯示修改者、時間及註解,若專案有其他需求,調整組裝邏輯即可。
Sample code to parse "tf history" output and convert it to changeset and modified file list during specific period.
Comments
# by 小船
請問這個TF.EXE 是在哪邊開啟?
# by Jeffrey
to 小船,可開啟 Visual Studio 的開發人員命令提示字元 https://docs.microsoft.com/zh-tw/dotnet/framework/tools/developer-command-prompt-for-vs 輸入指令。