Ejemplo n.º 1
0
        // Returns null if the report is empty
        protected static string GenerateReport(
            Alert alert,
            string htmlTemplate,
            IEnumerable <DataModelIssue> beginIssues,
            IEnumerable <DataModelIssue> endIssues,
            IEnumerable <Label> areaLabels)
        {
            IEnumerable <DataModelIssue> beginQuery = alert.Query.Evaluate(beginIssues);
            IEnumerable <DataModelIssue> endQuery   = alert.Query.Evaluate(endIssues);

            IEnumerable <DataModelIssue> goneIssues = beginQuery.Except_ByIssueNumber(endQuery);
            IEnumerable <DataModelIssue> newIssues  = endQuery.Except_ByIssueNumber(beginQuery);

            if (goneIssues.None() && newIssues.None())
            {
                Console.WriteLine("    No changes to the query, skipping.");
                Console.WriteLine();
                return(null);
            }

            string text = htmlTemplate;

            text = text.Replace("%ISSUES_LINKED_COUNTS%",
                                AlertReport.GetLinkedCount("", newIssues.Concat(goneIssues)));

            IEnumerable <IssueEntry> newIssueEntries = newIssues
                                                       .Select(issue => new IssueEntry(issue, IssueEntry.EntryKind.New));
            IEnumerable <IssueEntry> goneIssueEntries = goneIssues
                                                        .Select(issue =>
            {
                DataModelIssue newIssue = endIssues.FirstOrNull_ByIssueNumber(issue);
                if (newIssue == null)
                {       // Closed issue
                    return(new IssueEntry(issue, IssueEntry.EntryKind.Closed));
                }
                return(new IssueEntry(newIssue, IssueEntry.EntryKind.Moved, areaLabels, "moved_area"));
            });

            text = text.Replace("%ISSUES_TABLE%", FormatIssueTable(newIssueEntries.Concat(goneIssueEntries)
                                                                   .OrderBy(entry => entry.OrderType)
                                                                   .ThenBy(entry => entry.IssueNumber)));

            return(text);
        }
Ejemplo n.º 2
0
        // Returns null if the report is empty
        protected static string GenerateReport(
            Alert alert,
            string htmlTemplate,
            IEnumerable <DataModelIssue> issues,
            IEnumerable <string> inputFiles,
            ExpressionUntriaged untriagedExpression)
        {
            IEnumerable <DataModelIssue> matchingIssues = alert.Query.Evaluate(issues);
            var untriagedFlagsMap = new Dictionary <DataModelIssue, ExpressionUntriaged.Flags>();

            foreach (DataModelIssue issue in matchingIssues)
            {
                ExpressionUntriaged.Flags flags = untriagedExpression.GetUntriagedFlags(issue);
                if (flags != 0)
                {
                    untriagedFlagsMap[issue] = flags;
                }
            }

            if (untriagedFlagsMap.None())
            {
                Console.WriteLine("    No untriaged issues, skipping.");
                Console.WriteLine();
                return(null);
            }

            string text = htmlTemplate;

            text = text.Replace("%UNTRIAGED_ISSUES_START%", "");
            text = text.Replace("%UNTRIAGED_ISSUES_END%", "");

            text = text.Replace("%UNTRIAGED_ISSUES_LINKED_COUNTS%",
                                AlertReport.GetLinkedCount("is:issue is:open", untriagedFlagsMap.Keys));

            IEnumerable <IssueEntry> untriagedIssueEntries = untriagedFlagsMap.Keys.Select(issue => new IssueEntry(issue));

            text = text.Replace("%UNTRIAGED_ISSUES_TABLE%", FormatIssueTable(untriagedFlagsMap));

            text = text.Replace("%INPUT_FILES_LIST%", FormatInputFilesList(inputFiles));

            return(text);
        }
Ejemplo n.º 3
0
        // Returns null if the report is empty
        protected static string GenerateReport(
            Alert alert,
            string htmlTemplate,
            IEnumerable <DataModelIssue> issues,
            IEnumerable <DataModelIssue> comments)
        {
            // Create a Dictionary mapping issues to comments for that issue
            Dictionary <int, List <DataModelIssue> > issueComments  = new Dictionary <int, List <DataModelIssue> >();
            Dictionary <int, DataModelIssue>         issuesMap      = new Dictionary <int, DataModelIssue>();
            IEnumerable <DataModelIssue>             matchingIssues = alert.Query.Evaluate(issues);

            if (matchingIssues.None())
            {
                Console.WriteLine("    No changes to the query, skipping.");
                Console.WriteLine();
                return(null);
            }
            foreach (DataModelIssue issue in matchingIssues)
            {
                issueComments.Add(issue.Number, new List <DataModelIssue>());
                issuesMap.Add(issue.Number, issue);
            }
            foreach (DataModelIssue comment in comments)
            {
                int startIndex = comment.HtmlUrl.IndexOf("/issues/") + 8;
                if (startIndex < 8)
                {
                    startIndex = comment.HtmlUrl.IndexOf("/pull/") + 6;
                }
                int endIndex = comment.HtmlUrl.IndexOf("#");

                string issueString = comment.HtmlUrl.Substring(startIndex, endIndex - startIndex);
                int    issueID     = int.Parse(issueString);
                if (issueComments.ContainsKey(issueID))
                {
                    issueComments[issueID].Add(comment);
                }
            }

            // Filter our issues to ones that haven't had an owner response after our grace waiting period
            Dictionary <DataModelIssue, TimeSpan?> needsResponse = new Dictionary <DataModelIssue, TimeSpan?>();

            foreach (KeyValuePair <int, List <DataModelIssue> > pair in issueComments)
            {
                TimeSpan?lastComment;
                // First check if there are no comments and the issue was opened past the threshold.
                if (pair.Value.Count == 0 && ((lastComment = (DateTime.Now - issuesMap[pair.Key].CreatedAt)) > _acceptableResponseDelay))
                {
                    needsResponse.Add(issuesMap[pair.Key], lastComment);
                }

                // Next check if the last issue occurred past the threshold
                else if (pair.Value.Count > 0 && ((lastComment = (DateTime.Now - pair.Value.Max((issue) => issue.CreatedAt))) > _acceptableResponseDelay))
                {
                    needsResponse.Add(issuesMap[pair.Key], lastComment);
                }
            }

            if (needsResponse.None())
            {
                Console.WriteLine("    No changes to the query, skipping.");
                Console.WriteLine();
                return(null);
            }

            string text = htmlTemplate;

            text = text.Replace("%NEEDSMSRESPONSE_ACCEPTABLE_RESPONSE_DELAY%", _acceptableResponseDelay.Days.ToString());

            text = text.Replace("%NEEDSMSRESPONSE_ISSUES_START%", "");
            text = text.Replace("%NEEDSMSRESPONSE_ISSUES_END%", "");

            text = text.Replace("%NEEDSMSRESPONSE_ISSUES_LINKED_COUNTS%",
                                AlertReport.GetLinkedCount("is:issue is:open", needsResponse.Keys));
            text = text.Replace("%NEEDSMSRESPONSE_ISSUES_COUNT%", needsResponse.Count().ToString());

            text = text.Replace("%NEEDSMSRESPONSE_ISSUES_TABLE%", FormatIssueTable(needsResponse.OrderByDescending((pair) => pair.Value.Value.Days)));

            return(text);
        }