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); } }
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); }
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); } }
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); } }