工作需求,上線前置作業想從 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 輸入指令。

Post a comment