static async Task Main(string[] args) { if (args.count != 1) { Console.Err.WriteLine("Expected 1 argument (github PAT). Found " + args.Count); return; } var client = new GitHubClient(new ProductHeaderValue("nuget-github-issue-tagger")); client.Credentials = new Credentials(args[0]); await PullRequestUtilities.ProcessPullRequestStatsAsync(client); }
// Ugly code alert. This method is a collection of random code :) public static async Task ProcessPullRequestStatsAsync(GitHubClient client) { bool FetchDataFromRemote = false; bool Preprocess = false; bool AnalyzeReviewDistribution = false; bool AnalyzeTimeToReview = true; var outputFileName = "statistics.json"; var closedIssueFileName = "closed-processed.json"; if (FetchDataFromRemote) { // Load code paths var statistics = await PullRequestUtilities.GeneratePullRequestStatistics(client, "nuget", "NuGet.Client", 3200, 3302); var json = JsonConvert.SerializeObject(statistics, Formatting.Indented); File.WriteAllText(outputFileName, json); } if (Preprocess) { var lines = File.ReadAllText(outputFileName); var stats = JsonConvert.DeserializeObject <IDictionary <int, PullRequestStatistic> >(lines); var importantStat = stats.Where(e => e.Value.State == "closed" && e.Value.MergedDate != null).OrderByDescending(e => e.Value.MergedDate) .Select(e => new Stat(e.Value.Creator, e.Key, e.Value.CreatedAt, (DateTimeOffset)e.Value.MergedDate, (DateTimeOffset)e.Value.GetFirstEngagementDate(), e.Value.GetReviewers())).ToArray(); File.WriteAllText(closedIssueFileName, JsonConvert.SerializeObject(importantStat, Formatting.Indented)); } if (AnalyzeReviewDistribution) { var lines = File.ReadAllText(closedIssueFileName); var stats = JsonConvert.DeserializeObject <Stat[]>(lines); var interestingPeople = new string[] { "kartheekp-ms", "cristinamanum", "zivkan", "heng-liu", "nkolev92", "aortiz-msft", "dominoFire", "rrelyea", "dtivel", "donnie-msft", "zkat" }; var reviews = interestingPeople.ToDictionary(item => item, item => 0); var potentialReviews = interestingPeople.ToDictionary(item => item, item => stats.Length); foreach (var issue in stats) { if (potentialReviews.ContainsKey(issue.Name)) { potentialReviews[issue.Name]--; } foreach (var reviewer in issue.Reviewers) { if (reviews.ContainsKey(reviewer)) { reviews[reviewer]++; } } } var finalDict = new Dictionary <string, Tuple <int, int> >(); foreach (var review in reviews) { var countReview = review.Value; var countPotentialReview = potentialReviews[review.Key]; finalDict.Add(review.Key, new Tuple <int, int>(countReview, countPotentialReview)); } foreach (var entry in finalDict) { Console.WriteLine($"{entry.Key},{entry.Value.Item1},{entry.Value.Item2}"); } } if (AnalyzeTimeToReview) { var lines = File.ReadAllText(closedIssueFileName); var stats = JsonConvert.DeserializeObject <Stat[]>(lines); var timings = new List <Tuple <int, TimeSpan, TimeSpan> >(); foreach (var stat in stats) { timings.Add(new Tuple <int, TimeSpan, TimeSpan>(stat.Number, stat.FirstReview.Subtract(stat.StartedOn), stat.EndedOn.Subtract(stat.StartedOn))); } foreach (var entry in timings) { Console.WriteLine($"{entry.Item1},{entry.Item2.TotalDays},{entry.Item3.TotalDays}{Environment.NewLine}"); } } }