Beispiel #1
0
        private static void ShowJSON(string jql)
        {
            try
            {
                ConsoleUtil.WriteLine("");
                ConsoleUtil.WriteLine(string.Format("getting issues from JQL:{0}", Environment.NewLine));
                ConsoleUtil.WriteLine(string.Format("{0}", jql));
                ConsoleUtil.WriteLine("");
                ConsoleUtil.WriteLine("Querying JIRA ...");
                ConsoleUtil.WriteLine("");

                var issues = JiraUtil.JiraRepo.GetIssues(jql);

                ConsoleUtil.WriteLine(string.Format("Retrieved {0} issues", issues.Count()));

                List <JIssue> jissues = new List <JIssue>();

                foreach (var issue in issues)
                {
                    ConsoleUtil.WriteLine(string.Format("getting changelogs for {0}", issue.Key.Value));
                    JIssue newIssue = new JIssue(issue);
                    newIssue.AddChangeLogs(JiraUtil.JiraRepo.GetIssueChangeLogs(issue));

                    jissues.Add(newIssue);
                }

                var extractFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "JiraCon");
                if (!Directory.Exists(extractFolder))
                {
                    Directory.CreateDirectory(extractFolder);
                }

                DateTime now            = DateTime.Now;
                string   fileNameSuffix = string.Format("_{0:0000}{1}{2:00}_{3}.txt", now.Year, now.ToString("MMM"), now.Day, now.ToString("hhmmss"));
                string   jsonFile       = String.Format("JiraCon_JSON_{0}", fileNameSuffix);

                ConsoleUtil.WriteLine(string.Format("saving JSON to {0}", Path.Combine(extractFolder, jsonFile)));

                using (StreamWriter w = new StreamWriter(Path.Combine(extractFolder, jsonFile)))
                {
                    foreach (var jiss in jissues)
                    {
                        w.WriteLine(JsonConvert.SerializeObject(jiss, Formatting.Indented));
                    }
                }

                ConsoleUtil.WriteLine("file saved successfully");
            }
            catch (Exception ex)
            {
                ConsoleUtil.WriteLine("*** An error has occurred ***", ConsoleColor.DarkRed, ConsoleColor.Gray, false);
                ConsoleUtil.WriteLine(ex.Message, ConsoleColor.DarkRed, ConsoleColor.Gray, false);
                ConsoleUtil.WriteLine(ex.StackTrace, ConsoleColor.DarkRed, ConsoleColor.Gray, false);
            }
        }
Beispiel #2
0
        public static void AnalyzeOneIssue(string key, bool includeDescAndComments)
        {
            ConsoleUtil.WriteLine("");
            ConsoleUtil.WriteLine("***** Jira Card: " + key, ConsoleColor.DarkBlue, ConsoleColor.White, false);

            var issue = JiraUtil.JiraRepo.GetIssue(key);

            //issue.

            if (issue == null)
            {
                ConsoleUtil.WriteLine("***** Jira Card: " + key + " NOT FOUND!", ConsoleColor.DarkBlue, ConsoleColor.White, false);
                return;
            }

            ConsoleUtil.WriteLine(string.Format("***** loading change logs for {0}-({1}):", key, issue.Summary));

            var jIss = new JIssue(issue);

            jIss.AddChangeLogs(JiraUtil.JiraRepo.GetIssueChangeLogs(issue));

            ConsoleUtil.WriteLine(string.Format("Found {0} change logs for {1}", jIss.ChangeLogs.Count, key));

            for (int i = 0; i < jIss.ChangeLogs.Count; i++)
            {
                JIssueChangeLog changeLog = jIss.ChangeLogs[i];


                foreach (JIssueChangeLogItem cli in changeLog.Items)
                {
                    if (cli.FieldName.ToLower().StartsWith("desc") || cli.FieldName.ToLower().StartsWith("comment"))
                    {
                        if (includeDescAndComments)
                        {
                            ConsoleUtil.WriteAppend(string.Format("{0} - Changed On {1}, {2} field changed ", issue.Key, changeLog.CreatedDate.ToString(), cli.FieldName), true);
                            ConsoleUtil.WriteAppend(string.Format("\t{0} changed from ", cli.FieldName), true);
                            ConsoleUtil.WriteAppend(string.Format("{0}", cli.FromValue), ConsoleColor.DarkGreen, Console.BackgroundColor, true);
                            ConsoleUtil.WriteAppend(string.Format("\t{0} changed to ", cli.FieldName), true);
                            ConsoleUtil.WriteAppend(string.Format("{0}", cli.ToValue), ConsoleColor.Green, Console.BackgroundColor, true);
                        }
                    }
                    else
                    {
                        if (cli.FieldName.ToLower().StartsWith("status"))
                        {
                            ConsoleUtil.WriteAppend(string.Format("{0} - Changed On {1}, {2} field changed from '{3}' to ", issue.Key, changeLog.CreatedDate.ToString(), cli.FieldName, cli.FromValue), false);
                            ConsoleUtil.WriteAppend(string.Format("{0}", cli.ToValue), ConsoleColor.White, ConsoleColor.Red, true);
                        }
                        else if (cli.FieldName.ToLower().StartsWith("label"))
                        {
                            ConsoleUtil.WriteAppend(string.Format("{0} - Changed On {1}, {2} field changed from '{3}' to ", issue.Key, changeLog.CreatedDate.ToString(), cli.FieldName, cli.FromValue), false);
                            ConsoleUtil.WriteAppend(string.Format("{0}", cli.ToValue), ConsoleColor.White, ConsoleColor.Blue);
                        }

                        else
                        {
                            ConsoleUtil.WriteLine($"{issue.Key} - Changed On {changeLog.CreatedDate}, {cli.FieldName} field changed from '{cli.FromValue}' to '{cli.ToValue}'");
                        }
                    }
                }
            }

            //ConsoleUtil.WriteLine("***** JSON for  " + key + " *****", ConsoleColor.Black, ConsoleColor.Cyan, false);
            //ConsoleUtil.WriteLine(JsonConvert.SerializeObject(jIss,Formatting.Indented), ConsoleColor.DarkBlue, ConsoleColor.Cyan, false);

            //ConsoleUtil.WriteLine("***** Jira Card: " + key + " END", ConsoleColor.DarkBlue, ConsoleColor.White, false);
        }
Beispiel #3
0
        public static void CreateWorkMetricsFile(string jql, int startHour, int endHour, string epicKey)
        {
            try
            {
                DateTime now            = DateTime.Now;
                string   fileNameSuffix = string.Format("_{0:0000}{1}{2:00}_{3}.txt", now.Year, now.ToString("MMM"), now.Day, now.ToString("hhmmss"));

                string workMetricsFile = String.Format("JiraCon_WorkMetrics_{0}", fileNameSuffix);
                if (epicKey != null && epicKey.Length > 0)
                {
                    workMetricsFile = String.Format("JiraCon_WorkMetrics_Epic_{0}_{1}", epicKey, fileNameSuffix);
                }

                ConsoleUtil.WriteLine(string.Format("getting issues from JQL:{0}", Environment.NewLine));
                ConsoleUtil.WriteLine(string.Format("{0}", jql));
                ConsoleUtil.WriteLine("");

                var issues = JiraUtil.JiraRepo.GetIssues(jql);

                ConsoleUtil.WriteLine(string.Format("Retrieved {0} issues", issues.Count()));

                List <JIssue> jissues = new List <JIssue>();

                foreach (var issue in issues)
                {
                    ConsoleUtil.WriteLine(string.Format("getting changelogs for {0}", issue.Key.Value));
                    JIssue newIssue = new JIssue(issue);
                    newIssue.AddChangeLogs(JiraUtil.JiraRepo.GetIssueChangeLogs(issue));

                    jissues.Add(newIssue);
                }

                var extractFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "JiraCon");
                if (!Directory.Exists(extractFolder))
                {
                    Directory.CreateDirectory(extractFolder);
                }

                ConsoleUtil.WriteLine("Calculating work time metrics ...");

                var metrics = new WorkMetrics(JiraUtil.JiraRepo, startHour, endHour);

                SortedDictionary <string, string> forceIgnoreReasons = new SortedDictionary <string, string>();
                //build workMetrics ONLY FOR PARENTS AND SUB-TASKS, then go back and update exclusions for parent/sub-tasks
                var tempMetrics = new WorkMetrics(JiraUtil.JiraRepo, startHour, endHour);
                foreach (JIssue j in jissues)
                {
                    if (j.SubTasks.Count > 0)
                    {
                        var    workMetrics           = tempMetrics.AddIssue(j, jissues);
                        double parentActiveWorkTotal = workMetrics.Sum(item => item.Total8HourAdjBusinessHours);

                        List <WorkMetric> subTaskWorkMetrics = new List <WorkMetric>();
                        foreach (var subtask in j.SubTasks)
                        {
                            if (jissues.Any(x => x.Key == subtask.Key))
                            {
                                subTaskWorkMetrics.AddRange(tempMetrics.AddIssue(jissues.Single(x => x.Key == subtask.Key), jissues));
                            }
                        }
                        var subTasksActiveWorkTotal = subTaskWorkMetrics.Sum(item => item.Total8HourAdjBusinessHours);
                        if (parentActiveWorkTotal > subTasksActiveWorkTotal)
                        {
                            //use parent, ignore subtasks
                            foreach (var subtask in j.SubTasks)
                            {
                                forceIgnoreReasons.Add(subtask.Key, string.Format("Parent {0} active work time ({1}) is greater than combined sub-task active work time ({2})", j.Key, Math.Round(parentActiveWorkTotal, 2), Math.Round(subTasksActiveWorkTotal, 2)));
                            }
                        }
                        else
                        {
                            //use subtasks, ignore parent
                            var subTaskKeys = string.Join("*", j.SubTasks.Select(x => x.Key).ToList());

                            forceIgnoreReasons.Add(j.Key, string.Format("subtasks {0} active work time ({1}) is greater than parent active work time ({2})", subTaskKeys, Math.Round(subTasksActiveWorkTotal, 2), Math.Round(parentActiveWorkTotal, 2)));
                        }
                    }
                }

                foreach (var kvp in forceIgnoreReasons)
                {
                    metrics.AddForceIgnore(kvp.Key, kvp.Value);
                }

                using (StreamWriter writer = new StreamWriter(Path.Combine(extractFolder, workMetricsFile)))
                {
                    writer.WriteLine("key,type,created,featureTeam,summary,epicKey,parentIssueKey,currentStatus,labels,start,end,status,activeWork,calendarWork,totalBusinessDays,totalBusinessHours_8HourDay,transitionAfterHours,exclude,reason");
                    foreach (JIssue j in jissues)
                    {
                        ConsoleUtil.WriteLine(string.Format("analyzing {0} - {1}", j.Key, j.IssueType));
                        var workMetrics = metrics.AddIssue(j, jissues);
                        ConsoleUtil.WriteLine("key,type,created,featureTeam,summary,epicKey,parentIssueKey,currentStatus,labels,start,end,status,activeWork,calendarWork,totalBusinessDays,totalBusinessHours_8HourDay,transitionAfterHours,exclude,reason");
                        foreach (var wm in workMetrics)
                        {
                            string text = string.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15},{16},{17},{18}",
                                                        j.Key, j.IssueType, j.CreateDate.Value.ToShortDateString(), j.FeatureTeamChoices, JHelper.RemoveCommas(j.Summary),
                                                        j.EpicLinkKey, j.ParentIssueKey, JHelper.RemoveCommas(j.StatusName),
                                                        JHelper.RemoveCommas(j.LabelsToString), wm.Start, wm.End,
                                                        wm.ItemStatus.StatusName, wm.ItemStatus.ActiveWork, wm.ItemStatus.CalendarWork,
                                                        wm.TotalBusinessDays, wm.Total8HourAdjBusinessHours, wm.TransitionAfterHours,
                                                        wm.Exclude, wm.ExcludeReasons);
                            writer.WriteLine(text);
                            ConsoleUtil.WriteLine(text);
                        }
                    }
                }

                ConsoleUtil.WriteLine(string.Format("data has been written to {0}/{1}", extractFolder, workMetricsFile));
            }
            catch (Exception ex)
            {
                ConsoleUtil.WriteLine("*** An error has occurred ***", ConsoleColor.DarkRed, ConsoleColor.Gray, false);
                ConsoleUtil.WriteLine(ex.Message, ConsoleColor.DarkRed, ConsoleColor.Gray, false);
                ConsoleUtil.WriteLine(ex.StackTrace, ConsoleColor.DarkRed, ConsoleColor.Gray, false);
            }
        }
Beispiel #4
0
        private static void CreateExtractFiles(string jql, bool includeCommentsAndDesc)
        {
            try
            {
                DateTime now            = DateTime.Now;
                string   fileNameSuffix = string.Format("_{0:0000}{1}{2:00}_{3}.txt", now.Year, now.ToString("MMM"), now.Day, now.ToString("hhmmss"));

                string cycleTimeFile     = String.Format("JiraCon_CycleTime_{0}", fileNameSuffix);
                string qaFailFile        = String.Format("JiraCon_QAFailure_{0}", fileNameSuffix);
                string velocityFile      = String.Format("JiraCon_Velocity_{0}", fileNameSuffix);
                string changeHistoryFile = String.Format("JiraCon_ChangeHistory_{0}", fileNameSuffix);
                string extractConfigFile = String.Format("JiraCon_ExtractConfig_{0}", fileNameSuffix);


                ConsoleUtil.WriteLine(string.Format("getting issues from JQL:{0}", Environment.NewLine));
                ConsoleUtil.WriteLine(string.Format("{0}", jql));
                ConsoleUtil.WriteLine("");

                var issues = JiraUtil.JiraRepo.GetIssues(jql);

                ConsoleUtil.WriteLine(string.Format("Retrieved {0} issues", issues.Count()));

                List <JIssue> jissues = new List <JIssue>();

                foreach (var issue in issues)
                {
                    ConsoleUtil.WriteLine(string.Format("getting changelogs for {0}", issue.Key.Value));
                    JIssue newIssue = new JIssue(issue);
                    newIssue.AddChangeLogs(JiraUtil.JiraRepo.GetIssueChangeLogs(issue));

                    jissues.Add(newIssue);
                }

                var extractFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "JiraCon");
                if (!Directory.Exists(extractFolder))
                {
                    Directory.CreateDirectory(extractFolder);
                }

                ConsoleUtil.WriteLine("Calculating QA Failures ...");
                CreateQAFailExtract(jissues, Path.Combine(extractFolder, qaFailFile));
                ConsoleUtil.WriteLine(string.Format("Created qa failures file ({0})", qaFailFile));

                ConsoleUtil.WriteLine("Calculating cycle times...");
                CreateCycleTimeExtract(jissues, Path.Combine(extractFolder, cycleTimeFile));
                ConsoleUtil.WriteLine(string.Format("Created cycle time file ({0})", cycleTimeFile));

                ConsoleUtil.WriteLine("Calculating velocities ...");
                CreateVelocityExtract(jissues, Path.Combine(extractFolder, velocityFile));
                ConsoleUtil.WriteLine(string.Format("Created velocity file ({0})", velocityFile));

                ConsoleUtil.WriteLine("Organizing change logs ...");
                CreateChangeLogExtract(jissues, Path.Combine(extractFolder, changeHistoryFile), includeCommentsAndDesc);
                ConsoleUtil.WriteLine(string.Format("Created change log file ({0})", changeHistoryFile));

                ConsoleUtil.WriteLine("writing config for this extract process ...");
                CreateConfigExtract(Path.Combine(extractFolder, extractConfigFile), jql);

                ConsoleUtil.WriteLine(string.Format("Created config file ({0})", extractConfigFile));
                ConsoleUtil.WriteLine("");
                ConsoleUtil.WriteLine(string.Format("Files are located in: {0}", extractFolder));
                ConsoleUtil.WriteLine("");
            }
            catch (Exception ex)
            {
                ConsoleUtil.WriteLine("*** An error has occurred ***", ConsoleColor.DarkRed, ConsoleColor.Gray, false);
                ConsoleUtil.WriteLine(ex.Message, ConsoleColor.DarkRed, ConsoleColor.Gray, false);
                ConsoleUtil.WriteLine(ex.StackTrace, ConsoleColor.DarkRed, ConsoleColor.Gray, false);
            }
        }
Beispiel #5
0
        private static bool Menu()
        {
            BuildMenu();
            ConsoleUtil.Lines.WriteQueuedLines(true);

            //string jql2 = string.Format("project in (BAM,POS) AND parentEpic={0}", epicKey);

            //project in (require 1 or more))

            /*
             * 1.  specify 1 or more projects, space delimited
             * 2.  optional
             *   - ANY search terms found in Summary OR Description
             *   - ALL search terms found in Summary OR Description
             *   -
             *
             *
             *
             */

            var resp = Console.ReadKey(true);

            if (resp.Key == ConsoleKey.K)
            {
                ConsoleUtil.WriteLine("Enter Epic Key (e.g. BAM-1234)");
                var epicKey = Console.ReadLine();
                ConsoleUtil.WriteLine(string.Format("Create time metrics for Epic: {0}? (ENTER 'Y' TO CONTINUE OR PRESS ANOTHER KEY TO RETURN TO MENU", epicKey));
                var read = Console.ReadKey(true);
                if (read.Key != ConsoleKey.Y)
                {
                    return(true);
                }

                var dic       = MainClass.GetBusinessHours();
                int startHour = dic["start"];
                int endHour   = dic["end"];

                MainClass.CreateWorkMetricsFile(BuildJQL_EpicChildren(epicKey), startHour, endHour, epicKey);

                ConsoleUtil.WriteLine("");
                ConsoleUtil.WriteLine("Press any key to continue.");
                Console.ReadKey(true);
            }
            else if (resp.Key == ConsoleKey.F)
            {
                string projects           = string.Empty;
                bool   ANDED              = false;
                bool   SUMMARY_ONLY       = false;
                bool   RETURN_ALL_RESULTS = false;;
                string searchTerms        = string.Empty;

                ConsoleUtil.WriteLine("You are required to enter 1 or more project keys.", ConsoleColor.White, ConsoleColor.DarkCyan, false);
                ConsoleUtil.WriteLine("optionally you can enter search terms to finds Epics by Summary (Title) or Description.", ConsoleColor.White, ConsoleColor.DarkCyan, false);
                ConsoleUtil.WriteLine("ENTER 1 OR MORE PROJECT KEYS, SEPARATED BY SPACES (e.g. BAM POS)", ConsoleColor.White, ConsoleColor.DarkCyan, false);
                projects = Console.ReadLine();
                ConsoleUtil.WriteLine("***** Epic Summary (Title) and Description Search *****", ConsoleColor.White, ConsoleColor.DarkCyan, false);
                ConsoleUtil.WriteLine("***** Choose a search option *****", ConsoleColor.White, ConsoleColor.DarkCyan, false);
                ConsoleUtil.WriteLine("1 - Return epics where Summary or Description contain ANY search terms", ConsoleColor.White, ConsoleColor.DarkCyan, false);
                ConsoleUtil.WriteLine("2 - Return epics where Summary or Description contain ALL search terms", ConsoleColor.White, ConsoleColor.DarkCyan, false);
                ConsoleUtil.WriteLine("3 - Return epics where Summary (Title) contains ANY search terms", ConsoleColor.White, ConsoleColor.DarkCyan, false);
                ConsoleUtil.WriteLine("4 - Return epics where Summary (Title) contains ALL search terms", ConsoleColor.White, ConsoleColor.DarkCyan, false);
                ConsoleUtil.WriteLine("5 - View list of all epics for selected project(s).", ConsoleColor.White, ConsoleColor.DarkCyan, false);

                var    searchOption       = Console.ReadKey(true);
                string searchStrategyDesc = string.Empty;

                if (searchOption.KeyChar.ToString() == "1")
                {
                    ConsoleUtil.WriteLine("Search Option 1 selected", ConsoleColor.White, ConsoleColor.DarkYellow, false);
                    searchStrategyDesc = "Enter 1 or more search terms, separated by spaces. Epics that contain ** ANY ** search terms (Summary or Desc fields) will be returned.";
                    ANDED = false;
                }
                else if (searchOption.KeyChar.ToString() == "2")
                {
                    ConsoleUtil.WriteLine("Search Option 2 selected", ConsoleColor.White, ConsoleColor.DarkYellow, false);
                    searchStrategyDesc = "Enter 1 or more search terms, separated by spaces. Epics that contain ** ALL ** search terms (Summary or Desc fields) will be returned.";
                    ANDED = true;
                }
                else if (searchOption.KeyChar.ToString() == "3")
                {
                    ConsoleUtil.WriteLine("Search Option 3 selected", ConsoleColor.White, ConsoleColor.DarkYellow, false);
                    searchStrategyDesc = "Enter 1 or more search terms, separated by spaces. Epics that contain ** ANY ** search terms (Summary field) will be returned.";
                    ANDED        = false;
                    SUMMARY_ONLY = true;
                }
                else if (searchOption.KeyChar.ToString() == "4")
                {
                    ConsoleUtil.WriteLine("Search Option 4 selected", ConsoleColor.White, ConsoleColor.DarkYellow, false);
                    searchStrategyDesc = "Enter 1 or more search terms, separated by spaces. Epics that contain ** ALL ** search terms (Summary field) will be returned.";
                    ANDED        = true;
                    SUMMARY_ONLY = true;
                }
                else if (searchOption.KeyChar.ToString() == "5")
                {
                    ConsoleUtil.WriteLine("Search Option 5 selected", ConsoleColor.White, ConsoleColor.DarkYellow, false);

                    RETURN_ALL_RESULTS = true;
                }



                if (projects == null || projects.Trim().Length == 0)
                {
                    ConsoleUtil.WriteLine("1 Or More Project Keys is required!  Doh!", ConsoleColor.Red, ConsoleColor.White, false);
                    ConsoleUtil.PressAnyKeyToContinue();
                    return(true);
                }
                if (!RETURN_ALL_RESULTS)
                {
                    ConsoleUtil.WriteLine(searchStrategyDesc, ConsoleColor.White, ConsoleColor.DarkCyan, false);
                    searchTerms = Console.ReadLine();

                    if (searchTerms == null || searchTerms.Trim().Length == 0)
                    {
                        ConsoleUtil.WriteLine("You chose to search for epics based on search terms, but failed to enter any search terms.  Doh!", ConsoleColor.Red, ConsoleColor.Yellow, false);
                        ConsoleUtil.PressAnyKeyToContinue();
                        return(true);
                    }
                }
                string epicSearchJQL = BuildJQL_EpicSearch(projects, searchTerms, ANDED, SUMMARY_ONLY, RETURN_ALL_RESULTS);;
                ConsoleUtil.WriteLine(string.Format("AWESOME -- Please be patient while your results are fetched using the following *** JQL: {0}", epicSearchJQL), ConsoleColor.DarkBlue, ConsoleColor.Gray, false);

                var epics = JiraUtil.JiraRepo.GetIssues(epicSearchJQL);
                ConsoleUtil.WriteLine("***** ***** *****", ConsoleColor.White, ConsoleColor.Black, false);
                ConsoleUtil.WriteLine("***** ***** *****", ConsoleColor.White, ConsoleColor.Black, false);
                ConsoleUtil.WriteLine(string.Format("{0} epics were found matching your search criteria", epics.Count), ConsoleColor.White, ConsoleColor.Black, false);
                ConsoleUtil.WriteLine("***** ***** *****", ConsoleColor.White, ConsoleColor.Black, false);
                ConsoleUtil.WriteLine("***** ***** *****", ConsoleColor.White, ConsoleColor.Black, false);
                ConsoleUtil.PressAnyKeyToContinue();

                if (epics.Count == 0)
                {
                    return(true);
                }
                ConsoleUtil.WriteLine("Please wait while the search results are evaluated", ConsoleColor.DarkBlue, ConsoleColor.Gray, false);
                SortedList <JIssue, List <JIssue> > epicsWithChildren = new SortedList <JIssue, List <JIssue> >();

                string[] projArray       = projects.ToUpper().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                string   projSearchItems = projArray.Length == 1 ? projArray[0] : String.Join(",", projArray);

                int epicsEvaluated  = 0;
                int totalEpicsFound = epics.Count;

                foreach (Issue epic in epics)
                {
                    epicsEvaluated += 1;
                    SortedDictionary <string, int> epicIssueBreakdown = new SortedDictionary <string, int>();
                    JIssue jepic = new JIssue(epic);
                    ConsoleUtil.WriteLine(string.Format("Analyzing Epic: {0} ({1}) - {2}", jepic.Key, jepic.StatusName, jepic.Summary), ConsoleColor.DarkBlue, ConsoleColor.Gray, false);

                    string epicIssuesJQL = string.Format("project in({0}) AND parentEpic={1}", projSearchItems, jepic.Key);

                    List <Issue>  epicIssues   = JiraUtil.JiraRepo.GetIssues(epicIssuesJQL);
                    List <JIssue> epicChildren = new List <JIssue>();
                    foreach (Issue epicIssue in epicIssues)
                    {
                        JIssue epicChild = new JIssue(epicIssue);
                        epicChildren.Add(epicChild);
                        if (epicIssueBreakdown.ContainsKey(epicChild.IssueType.ToLower()))
                        {
                            epicIssueBreakdown[epicChild.IssueType.ToLower()] = epicIssueBreakdown[epicChild.IssueType.ToLower()] + 1;
                        }
                        else
                        {
                            epicIssueBreakdown.Add(epicChild.IssueType.ToLower(), 1);
                        }
                    }
                    ConsoleTable table = new ConsoleTable(string.Format("Epic:{0} ({1}/{2} results)", jepic.Key, epicsEvaluated, totalEpicsFound), "ChildType", "Qty");
                    foreach (var kvp in epicIssueBreakdown)
                    {
                        table.AddRow(" ***** ", kvp.Key, kvp.Value);
                    }
                    table.Write();

                    ConsoleUtil.WriteLine(string.Format("Isn't this cool? -- Do you want to generate the Work Time Analytics for this Epic ({0})? (Don't worry, we'll come back here where you left off if you decide to do that!)", jepic.Key), ConsoleColor.DarkBlue, ConsoleColor.Gray, false);
                    ConsoleUtil.WriteLine(string.Format("Press 'Y' to generate the Work Time Analytics file for epic {0}", jepic.Key), ConsoleColor.DarkBlue, ConsoleColor.Gray, false);
                    ConsoleUtil.WriteLine(string.Format("Press 'E' to stop reviewing epic search results", jepic.Key), ConsoleColor.DarkBlue, ConsoleColor.Gray, false);
                    ConsoleUtil.WriteLine(string.Format("Press any other key to continue reviewing epic search results.", jepic.Key), ConsoleColor.DarkBlue, ConsoleColor.Gray, false); var read = Console.ReadKey(true);
                    if (read.Key == ConsoleKey.Y)
                    {
                        MainClass.CreateWorkMetricsFile(epicIssuesJQL, 7, 18, jepic.Key);
                        ConsoleUtil.PressAnyKeyToContinue();
                    }
                    else if (read.Key == ConsoleKey.E)
                    {
                        return(true);
                    }
                }
            }
            else if (resp.Key == ConsoleKey.M)
            {
                return(false);
            }

            return(true);
        }