コード例 #1
0
        public List <Issue> GetAllOpenIssues(string label)
        {
            var repoService   = new RepositoryManagementService();
            var allOpenIssues = repoService.GetAllCommunityIssues(false).Where(x => x.ClosedDateTime == null).ToList();

            foreach (var issue in allOpenIssues)
            {
                var firstLabel = issue.Events.OrderBy(x => x.CreateDateTime).FirstOrDefault(x => x.Name == "labeled");
            }


            foreach (var issue in allOpenIssues)
            {
                var firstComment = issue.Comments.OrderBy(x => x.CreateDateTime).FirstOrDefault();
            }

            // Added label by HQ
            // -- Discussion / HQ Reply
            // -- Estimation
            //

            //foreach (var issue in labelIssues)
            //{
            //    foreach (var issueEvent in issue.Events)
            //    {
            //        if (issueEvent.Name == "labeled" && string.Equals(issueEvent.Label.Name, label, StringComparison.InvariantCultureIgnoreCase))
            //        {
            //            issue.LabelAdded = issueEvent.CreateDateTime;
            //        }
            //    }
            //}

            return(allOpenIssues.ToList());
        }
コード例 #2
0
        public List <Issue> GetAssignedIssues()
        {
            var repoService    = new RepositoryManagementService();
            var assignedIssues = repoService.GetAllCommunityIssues(false)
                                 .Where(x => x.ClosedDateTime == null && x.Labels.Any(l => l.Name == "status/idea") == false && x.Assignees.Any()).ToList();

            return(assignedIssues);
        }
コード例 #3
0
        public List <Issue> GetIdeasIssues()
        {
            var repoService = new RepositoryManagementService();
            var ideasIssues = repoService.GetAllCommunityIssues(false)
                              .Where(x => x.ClosedDateTime == null && x.Labels.Any(l => l.Name == "status/idea")).ToList();

            foreach (var issue in ideasIssues)
            {
                var ideaLabelEvent = issue.Events.FirstOrDefault(x => x.Name == "labeled" && x.Label.Name == "status/idea");
                if (ideaLabelEvent != null)
                {
                    issue.SetToIdea = ideaLabelEvent.CreateDateTime;
                }
            }

            return(ideasIssues);
        }
コード例 #4
0
        public List <Issue> GetOpenPulls()
        {
            var repoService = new RepositoryManagementService();
            var openPrs     = repoService.GetAllCommunityIssues(true)
                              .Where(x => x.ClosedDateTime == null).ToList();

            foreach (var pr in openPrs)
            {
                var lastReview = pr.Reviews.LastOrDefault();
                if (lastReview != null)
                {
                    pr.ReviewState    = lastReview.State;
                    pr.LastReviewDate = lastReview.CreateDateTime;
                }
            }

            return(openPrs.OrderByDescending(x => x.LastReviewDate).ToList());
        }
コード例 #5
0
        public List <Issue> GetNoCommentIssues()
        {
            var repoService     = new RepositoryManagementService();
            var communityIssues = repoService.GetAllCommunityIssues(false)
                                  .Where(x => x.ClosedDateTime == null && x.Labels.Any(l => l.Name == "status/idea") == false).ToList();

            var noCommentIssues = new List <Issue>();

            foreach (var issue in communityIssues)
            {
                var firstTeamEvent = GetFirstTeamEventDateTime(issue);
                if (firstTeamEvent == null || firstTeamEvent == default(DateTime))
                {
                    noCommentIssues.Add(issue);
                }
            }

            return(noCommentIssues);
        }
コード例 #6
0
        public List <Issue> GetIssuesWithLabel(string label)
        {
            var repoService = new RepositoryManagementService();
            var labelIssues = repoService.GetAllCommunityIssues(false)
                              .Where(x => x.ClosedDateTime == null &&
                                     x.Labels.Any(l => l.Name == "status/idea") == false &&
                                     x.Labels.Any(l => string.Equals(l.Name, label, StringComparison.InvariantCultureIgnoreCase))).ToList();

            foreach (var issue in labelIssues)
            {
                foreach (var issueEvent in issue.Events)
                {
                    if (issueEvent.Name == "labeled" && string.Equals(issueEvent.Label.Name, label, StringComparison.InvariantCultureIgnoreCase))
                    {
                        issue.LabelAdded = issueEvent.CreateDateTime;
                    }
                }
            }

            return(labelIssues.OrderByDescending(x => x.LabelAdded).ToList());
        }
コード例 #7
0
        public List <Issue> GetOldUpForGrabsIssues()
        {
            var repoService        = new RepositoryManagementService();
            var allCommunityIssues = repoService.GetAllCommunityIssues(false)
                                     .Where(x => x.ClosedDateTime == null && x.Labels.Any(l => l.Name == "status/idea") == false).ToList();

            var oldDate = DateTime.Now.AddDays(-120);

            var upForGrabsIssues = allCommunityIssues
                                   .Where(x => x.Labels.Any(l => l.Name == "community/up-for-grabs" || l.Name == "help wanted"))
                                   .OrderBy(x => x.CreateDateTime)
                                   .ToList();

            var oldUpForGrabsIssues = new List <Issue>();

            foreach (var issue in upForGrabsIssues)
            {
                foreach (var issueEvent in issue.Events)
                {
                    if (issueEvent.Name == "labeled" &&
                        (issueEvent.Label.Name == "community/up-for-grabs" || issueEvent.Label.Name == "help wanted"))
                    {
                        if (issueEvent.CreateDateTime <= oldDate)
                        {
                            issue.SetToUpForGrabs = issueEvent.CreateDateTime;
                            if (oldUpForGrabsIssues.Any(x => x.Number == issue.Number) == false)
                            {
                                oldUpForGrabsIssues.Add(issue);
                            }
                        }
                    }
                }
            }

            return(oldUpForGrabsIssues);
        }
コード例 #8
0
        public List <IssuesInPeriod> GetGroupedIssuesData(int fromDay, int fromMonth, int fromYear, int toDay,
                                                          int toMonth, int toYear, string repository = "")
        {
            var gitHubService = new GitHubService();
            var teamMembers   = new List <string>();

            foreach (var team in gitHubService.GetTeamMembers())
            {
                teamMembers.AddRange(team.Members);
            }

            if (fromDay == 0)
            {
                fromDay = 1;
            }
            if (toDay == 0)
            {
                toDay = DateTime.DaysInMonth(toYear, toMonth);
            }

            var fromDate = DateTime.Parse($"{fromYear}-{fromMonth}-{fromDay} 00:00:00");
            var toDate   = DateTime.Parse($"{toYear}-{toMonth}-{toDay} 23:59:59");

            var repoService        = new RepositoryManagementService();
            var allCommunityIssues = repoService.GetAllCommunityIssues(false)
                                     .Where(x => x.Labels.Any(l => l.Name == "status/idea") == false).ToList();

            if (string.IsNullOrWhiteSpace(repository) == false)
            {
                allCommunityIssues = allCommunityIssues.Where(x => x.RepositoryName == repository).ToList();
            }

            var issues = allCommunityIssues
                         .Where(x => x.CreateDateTime >= fromDate && x.CreateDateTime <= toDate)
                         .OrderBy(x => x.CreateDateTime)
                         .GroupBy(x => new { x.CreateDateTime.Year, x.CreateDateTime.Month })
                         .ToDictionary(x => x.Key, x => x.ToList());

            var groupedIssues = new List <IssuesInPeriod>();

            foreach (var issuesInPeriod in issues)
            {
                var period    = $"{issuesInPeriod.Key.Year}{issuesInPeriod.Key.Month:00}";
                var groupName =
                    $"{DateTimeFormatInfo.CurrentInfo.GetAbbreviatedMonthName(issuesInPeriod.Key.Month)} {issuesInPeriod.Key.Year}";
                var issuesList = new IssuesInPeriod
                {
                    MonthYear = period,
                    GroupName = groupName,

                    AllIssueClosingTimesInHours    = string.Empty,
                    IssueAverageClosingTimeInHours = 0,
                    IssueMedianClosingTimeInHours  = 0,
                    TargetClosingTimeInHours       = 2880, // 120 business days

                    AllIssueFirstCommentTimesInHours     = string.Empty,
                    IssueAverageFirstCommentTimesInHours = 0,
                    IssueMedianFirstCommentTimesInHours  = 0,
                    TargetFirstCommentTimeInHours        = 48, // 2 business days

                    NumberClosed  = 0,
                    NumberOpen    = 0,
                    NumberCreated = issuesInPeriod.Value.Count
                };

                var year           = issuesInPeriod.Key.Year;
                var month          = issuesInPeriod.Key.Month;
                var periodFirstDay = new DateTime(year, month, 1);
                var periodLastDay  = new DateTime(year, month, DateTime.DaysInMonth(year, month));

                foreach (var issue in allCommunityIssues)
                {
                    if (issue.CreateDateTime <= periodLastDay && issue.State != "closed")
                    {
                        issuesList.NumberOpen = issuesList.NumberOpen + 1;
                    }
                }

                var allClosingTimesInHours      = new List <double>();
                var allFirstCommentTimesInHours = new List <double>();
                foreach (var issue in issuesInPeriod.Value)
                {
                    if (issue.State == "closed" && issue.ClosedDateTime.HasValue)
                    {
                        var createDateTime = issue.CreateDateTime;
                        var closedDateTime = issue.ClosedDateTime.Value;

                        if (closedDateTime < periodFirstDay || closedDateTime > periodLastDay)
                        {
                            continue;
                        }

                        issuesList.NumberClosed = issuesList.NumberClosed + 1;

                        var hoursOpen = createDateTime.BusinessHoursUntil(closedDateTime);
                        allClosingTimesInHours.Add(hoursOpen);
                    }
                    else
                    {
                        //var dateLastDayOfMonth = issue.CreateDateTime.GetDateLastDayOfMonth().AddDays(1).AddSeconds(-1);
                        var hoursOpen = issue.CreateDateTime.BusinessHoursUntil(DateTime.Now);
                        allClosingTimesInHours.Add(hoursOpen);
                    }

                    double hoursBeforeFirstReply = 0;
                    double hoursBeforeFirstLabel = 0;
                    foreach (var comment in issue.Comments.OrderBy(x => x.CreateDateTime))
                    {
                        if (teamMembers.InvariantContains(comment.User.Login))
                        {
                            hoursBeforeFirstReply = issue.CreateDateTime.BusinessHoursUntil(comment.CreateDateTime);
                        }
                        else
                        {
                            //var dateLastDayOfMonth = issue.CreateDateTime.GetDateLastDayOfMonth().AddDays(1).AddSeconds(-1);
                            hoursBeforeFirstReply = issue.CreateDateTime.BusinessHoursUntil(DateTime.Now);
                        }
                    }

                    if (issue.Events.Any())
                    {
                        var firstLabel = issue.Events.OrderBy(x => x.CreateDateTime)
                                         .FirstOrDefault(x => x.Name == "labeled");
                        if (firstLabel != null)
                        {
                            hoursBeforeFirstLabel = issue.CreateDateTime.BusinessDaysUntil(firstLabel.CreateDateTime);
                        }
                    }

                    if (hoursBeforeFirstLabel != 0 && hoursBeforeFirstReply != 0)
                    {
                        double hours;
                        if (hoursBeforeFirstLabel < hoursBeforeFirstReply)
                        {
                            hours = hoursBeforeFirstLabel;
                        }
                        else
                        {
                            hours = hoursBeforeFirstReply;
                        }

                        allFirstCommentTimesInHours.Add(hours);
                    }
                }

                issuesList.AllIssueClosingTimesInHours = string.Join(",", allClosingTimesInHours);
                if (allClosingTimesInHours.Any())
                {
                    issuesList.IssueAverageClosingTimeInHours = allClosingTimesInHours.Average();
                    issuesList.IssueMedianClosingTimeInHours  = allClosingTimesInHours.Median();
                }

                issuesList.AllIssueFirstCommentTimesInHours = string.Join(",", allFirstCommentTimesInHours);

                if (allFirstCommentTimesInHours.Any())
                {
                    issuesList.IssueAverageFirstCommentTimesInHours = allFirstCommentTimesInHours.Average();
                    issuesList.IssueMedianFirstCommentTimesInHours  = allFirstCommentTimesInHours.Median();
                }

                groupedIssues.Add(issuesList);
            }

            //foreach (var issuesInPeriod in issues)
            //{
            //    foreach (var issue in issuesInPeriod.Value)
            //    {
            //        if(issue.CreateDateTime >= fromDate && issue.CreateDateTime <= toDate)
            //        {
            //            var year = issuesInPeriod.Key.Year;
            //            var month = issuesInPeriod.Key.Month;
            //            if(issue.ClosedDateTime != null && issue.ClosedDateTime > new DateTime(year, month, DateTime.DaysInMonth(year, month))
            //               groupedIssues.Where(x => x.MonthYear == )
            //        }
            //    }
            //}

            return(groupedIssues.OrderBy(x => x.MonthYear).ToList());
        }
コード例 #9
0
        public List <Contributions> GetContributorStatistics(int startMonth = 6, int startYear = 2010, string repository = "", bool monthly = true)
        {
            var totalContributors = new List <Contributions>();

            var firstPrs = new List <string>();

            var repoService = new RepositoryManagementService();

            var pullsNonHq = string.IsNullOrWhiteSpace(repository)
                ? repoService.GetAllCommunityIssues(true).ToList()
                : repoService.GetAllCommunityIssues(true).Where(x => x.RepositoryName == repository).ToList();

            var date = new DateTime(startYear, startMonth, 1);

            while (date < DateTime.Now)
            {
                var year = date.Year;

                var endMonth = monthly ? date.AddMonths(1).Month : date.AddYears(1).Month;
                var endYear  = monthly ? date.AddMonths(1).Year : date.AddYears(1).Year;

                var startDate = new DateTime(year, date.Month, 1);
                var endDate   = new DateTime(endYear, endMonth, 1);

                var prsCreated = pullsNonHq.Where(x => x.CreateDateTime >= startDate && x.CreateDateTime < endDate).ToList();

                var repoStatistics = new Contributions
                {
                    CodegardenYear         = year,
                    Title                  = date.ToString(monthly ? "yyyyMM" : "yyyy"),
                    FirstCommentStatistics = new FirstCommentStatistics {
                        AllFirstEventTimesInHours = new List <double>()
                    },
                    AllPulls = prsCreated
                };

                var allFirstCommentTimesInHours = new List <double>();
                var allClosingTimesInHours      = new List <double>();

                foreach (var pr in prsCreated)
                {
                    var firstCommentStatistics = GetFirstEventStatistics(pr);
                    repoStatistics.FirstCommentStatistics.FirstEventOnTime += firstCommentStatistics.FirstEventOnTime;
                    repoStatistics.FirstCommentStatistics.FirstEventLate   += firstCommentStatistics.FirstEventLate;
                    repoStatistics.FirstCommentStatistics.TeamEventMissing += firstCommentStatistics.TeamEventMissing;
                    allFirstCommentTimesInHours.AddRange(firstCommentStatistics.AllFirstEventTimesInHours);

                    if (pr.ClosedDateTime != null)
                    {
                        var timeSpan = Convert.ToInt32(pr.CreateDateTime.BusinessHoursUntil(pr.ClosedDateTime.Value));
                        allClosingTimesInHours.Add(timeSpan);

                        if (pr.Labels.Any(x => x.Name.StartsWith("release/")))
                        {
                            repoStatistics.ReleasePullRequests += 1;
                        }
                    }
                }

                if (allFirstCommentTimesInHours.Any())
                {
                    repoStatistics.AverageHoursToFirstComment = (int)Math.Round(allFirstCommentTimesInHours.Average());
                    repoStatistics.MedianHoursToFirstComment  = (int)Math.Round(allFirstCommentTimesInHours.Median());
                }

                if (allClosingTimesInHours.Any())
                {
                    repoStatistics.AverageHoursToClose = (int)Math.Round(allClosingTimesInHours.Average());
                    repoStatistics.MedianHoursToClose  = (int)Math.Round(allClosingTimesInHours.Median());
                }

                repoStatistics.PullRequestsCreated = prsCreated.Count;

                // GitHub marks all merged PRs as "closed", so we want to differentiate: if there's no "merged" event then it was closed without merging
                var prsClosed = pullsNonHq.Where(x => x.State == "closed" &&
                                                 x.Events.Any(y => y.Name == "merged") == false &&
                                                 x.ClosedDateTime >= startDate &&
                                                 x.ClosedDateTime < endDate).ToList();

                // There was a "merged" event and it was in the current period
                var prsMerged = pullsNonHq.Where(x => x.State == "closed" &&
                                                 x.Events.Any(y => y.Name == "merged") == true &&
                                                 x.Events.First(y => y.Name == "merged").CreateDateTime >= startDate &&
                                                 x.Events.First(y => y.Name == "merged").CreateDateTime < endDate).ToList();

                // Created in this period and still open now or merged/closed after the last date in this period
                var prsStillOpen = pullsNonHq.Where(x =>
                                                    x.CreateDateTime >= startDate &&
                                                    x.CreateDateTime < endDate &&
                                                    (x.State == "open" || x.ClosedDateTime >= endDate || x.ClosedDateTime > endDate)).ToList();

                repoStatistics.PullRequestsClosed            = prsClosed.Count;
                repoStatistics.PullRequestsMerged            = prsMerged.Count;
                repoStatistics.PullRequestsProcessed         = prsClosed.Count + prsMerged.Count;
                repoStatistics.PullRequestsStillOpenInPeriod = prsStillOpen.Count;

                foreach (var pr in prsMerged)
                {
                    if (firstPrs.Any(x => x == pr.User.Login))
                    {
                        continue;
                    }

                    firstPrs.Add(pr.User.Login);
                    repoStatistics.FirstAcceptedPullRequests += 1;
                }

                var contributors = prsMerged.Select(x => x.User.Login).Distinct().ToList();
                repoStatistics.UniqueContributorCount = contributors.Count;
                totalContributors.Add(repoStatistics);

                date = monthly ? date.AddMonths(1) : date.AddYears(1);
            }

            return(new List <Contributions>(totalContributors.Where(x => x.UniqueContributorCount != 0).OrderBy(x => x.CodegardenYear)));
        }
コード例 #10
0
        public List <IssueStatistics> GetIssueStatistics(int startMonth = 6, int startYear = 2010, string repository = "", bool monthly = true)
        {
            var repoService = new RepositoryManagementService();

            var allCommunityIssues = string.IsNullOrWhiteSpace(repository)
                ? repoService.GetAllCommunityIssues(false).ToList()
                : repoService.GetAllCommunityIssues(false).Where(x => x.RepositoryName == repository).ToList();

            var issueStatistics = new List <IssueStatistics>();
            var date            = new DateTime(startYear, startMonth, 1);

            while (date < DateTime.Now)
            {
                var year = date.Year;

                var endMonth = monthly ? date.AddMonths(1).Month : date.AddYears(1).Month;
                var endYear  = monthly ? date.AddMonths(1).Year : date.AddYears(1).Year;

                var startDate = new DateTime(year, date.Month, 1);
                var endDate   = new DateTime(endYear, endMonth, 1);

                var issuesInPeriod       = allCommunityIssues.Where(x => x.CreateDateTime >= startDate && x.CreateDateTime < endDate).ToList();
                var issuesClosedInPeriod = issuesInPeriod.Where(x => x.State == "closed" && x.ClosedDateTime >= startDate && x.ClosedDateTime < endDate).ToList();

                var yearStatistics = new IssueStatistics
                {
                    CodegardenYear         = year,
                    Title                  = date.ToString(monthly ? "yyyyMM" : "yyyy"),
                    CreatedIssues          = issuesInPeriod.Count,
                    ClosedIssues           = issuesClosedInPeriod.Count,
                    FirstCommentStatistics = new FirstCommentStatistics {
                        AllFirstEventTimesInHours = new List <double>()
                    },
                    AllIssues = issuesInPeriod
                };

                var allFirstCommentTimesInHours = new List <double>();
                var allClosingTimesInHours      = new List <double>();

                foreach (var issue in issuesInPeriod)
                {
                    var firstCommentStatistics = GetFirstEventStatistics(issue);
                    yearStatistics.FirstCommentStatistics.FirstEventOnTime += firstCommentStatistics.FirstEventOnTime;
                    yearStatistics.FirstCommentStatistics.FirstEventLate   += firstCommentStatistics.FirstEventLate;
                    yearStatistics.FirstCommentStatistics.TeamEventMissing += firstCommentStatistics.TeamEventMissing;
                    allFirstCommentTimesInHours.AddRange(firstCommentStatistics.AllFirstEventTimesInHours);

                    if (issue.ClosedDateTime != null)
                    {
                        var timeSpan = Convert.ToInt32(issue.CreateDateTime.BusinessHoursUntil(issue.ClosedDateTime.Value));
                        allClosingTimesInHours.Add(timeSpan);

                        if (issue.Labels.Any(x => x.Name.StartsWith("release/")))
                        {
                            yearStatistics.ReleaseIssues += 1;
                        }
                    }
                }

                if (allFirstCommentTimesInHours.Any())
                {
                    yearStatistics.AverageHoursToFirstComment = (int)Math.Round(allFirstCommentTimesInHours.Average());
                    yearStatistics.MedianHoursToFirstComment  = (int)Math.Round(allFirstCommentTimesInHours.Median());
                }

                if (allClosingTimesInHours.Any())
                {
                    yearStatistics.AverageHoursToClose = (int)Math.Round(allClosingTimesInHours.Average());
                    yearStatistics.MedianHoursToClose  = (int)Math.Round(allClosingTimesInHours.Median());
                }

                issueStatistics.Add(yearStatistics);

                date = monthly ? date.AddMonths(1) : date.AddYears(1);
            }

            return(issueStatistics);
        }