グーグルのバグ予測アルゴリズムを実装したツール「bugspots」、オープンソースで公開 - Publickey
gitとsubversionだけで悔しいので、BugSpotsをTFSで実装してみました(結構しょうもないところで詰まったのは内緒だ)。ちょっと前にSQL Serverのビュー定義のことを書きましたが、少し変えています。TFS2010でしか確認していません。
一式動くプロジェクトが必要ならgithubか私のところかどこかにあげます。
USE [Tfs_DefaultCollection] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE VIEW [dbo].[My_BugSpots] AS SELECT TOP (100) PERCENT a.ItemId, a.CreationDate, b.ParentPath, b.ChildItem FROM (SELECT dbo.tbl_Version.ItemId, dbo.tbl_ChangeSet.CreationDate FROM dbo.tbl_ChangeSet INNER JOIN dbo.tbl_Version ON dbo.tbl_ChangeSet.ChangeSetId = dbo.tbl_Version.VersionFrom WHERE (dbo.tbl_Version.Encoding >= 0)) AS a INNER JOIN dbo.tbl_VersionedItem AS b ON a.ItemId = b.ItemId ORDER BY a.CreationDate GO
これでdbo.My_BugSpotsというビューができるので、このビューをEntityFrameworkなどで参照してください。Primary Keyがないので参照しかできないといわれますが、更新しないので無視で。
C#側のソースです。コンソールプロジェクトです。WPFやらSilverlightやらでりっちにしてみてください。チェックインコメントは取っていませんが、まぁできると思います。
using System; using System.Collections.Generic; using System.Linq; namespace BugSpotsConsole { class Program { static void Main(string[] args) { var Spots = new Dictionary<string, List<DateTime>>(); var tfsBugSportConnection = new Tfs_DefaultCollectionEntities(); var results = tfsBugSportConnection.My_BugSpots. OrderBy(x => x.ParentPath).OrderBy(x => x.ChildItem). OrderBy(x => x.CreationDate); foreach(var result in results) { var fullpath = default(string); fullpath = result.ParentPath + result.ChildItem.Substring(0, result.ChildItem.Length - 1); var currentSpot = Spots.Where(y => y.Key == fullpath); if (currentSpot.Count() == 0) { var DateList = new List<DateTime>() { result.CreationDate }; Spots.Add(fullpath, DateList); } else { currentSpot.First().Value.Add(result.CreationDate); } } var Now = DateTime.Now; var ranking = new Dictionary<string, double>(); foreach (var Spot in Spots) { var FirstCheckinTime = Spot.Value.Min(); var SpotValue = default(double); Spot.Value.ForEach(y => { var t = 1.0 - ((double)(Now - y).Ticks / (double)(Now - FirstCheckinTime).Ticks); SpotValue += 1.0 / (1.0 + Math.Exp((-12.0 * t) + 12.0)); }); ranking.Add(Spot.Key, SpotValue); } var limits = ranking.OrderBy(x => x.Value); foreach (var limit in limits) { Console.WriteLine("File:{0} Rate:{1:F4}", limit.Key, limit.Value); } } } }