// FX builds duration value static string GetDurationOrBlank(BuildStage target) => target.CompletionStatus == StageCompletionStatusEnum.Success || target.CompletionStatus == StageCompletionStatusEnum.Failure || target.CompletionStatus == StageCompletionStatusEnum.Warning || target.CompletionStatus == StageCompletionStatusEnum.InProcess || target.CompletionStatus == StageCompletionStatusEnum.Aborted ? GetDuration(target.RunTimeDuration()) : string.Empty;
/// <summary> /// Gets the requested build stage from the Known Build Stages list. Throws exception if build stage is not found. /// </summary> /// <param name="buildStageName">Name of the build stage to retrieve</param> /// <returns></returns> public BuildStage GetBuildStage(string buildStageName) { // Find the target in the build stages list BuildStage buildStage = _buildStages.Find(x => x.Name == buildStageName); if (buildStage == null) { throw new ApplicationException("The requested build stage of [" + buildStageName + "] is not a valid build stage."); } return(buildStage); }
/// <summary> /// Writes End of slugBuilder Summary info. /// </summary> internal virtual void WriteSummary(ExecutionPlan plan, bool isInteractive, CISession ciSession) { Console.WriteLine(); Misc.WriteFinalHeader(plan.PlanStatus, ciSession); // Build dictionary of each Build Stage in order, assigning a letter to each stage. The letter will allow user to see detailed info // about the stage. Dictionary <char, BuildStage> stageInfo = new Dictionary <char, BuildStage>(); char letter = 'A'; foreach (BuildStage buildStage in plan.Plan) { stageInfo.Add(letter, buildStage); letter++; } bool continueLooping = true; while (continueLooping) { // Print info for non interactive sessions if (!isInteractive) { if (Logger.OutputSink.SevereMessages.Count > 0) { CISession.OutputSink.WriteNormal(""); WriteSevereMessages(); WriteStageStats(plan, stageInfo); } } else { CISession.OutputSink.WriteNormal(""); WriteStageStats(plan, stageInfo); CISession.OutputSink.WriteNormal(""); } // Write Version info if successful build if (plan.WasSuccessful) { CISession.OutputSink.WriteSuccess($"Build succeeded on {DateTime.Now.ToString(CultureInfo.CurrentCulture)}"); Console.WriteLine(); Console.WriteLine("Version Built was: ", Color.Yellow); Console.WriteLine(" Semantic Version: " + ciSession.VersionInfo.SemVersionAsString, Color.Yellow); Console.WriteLine(" Assembly Version: " + ciSession.VersionInfo.AssemblyVersion, Color.Yellow); Console.WriteLine(" File Version: " + ciSession.VersionInfo.FileVersion, Color.Yellow); Console.WriteLine(" Info Version: " + ciSession.VersionInfo.InformationalVersion, Color.Yellow); } else { CISession.OutputSink.WriteError($"Build failed on {DateTime.Now.ToString(CultureInfo.CurrentCulture)}"); } // Exit if non-interactive as rest is user prompting and responding if (!isInteractive) { return; } Console.WriteLine("Press (x) to exit, (1) to display git history (9) to view detailed error information OR"); Console.WriteLine(" Press letter from above build stage to see detailed output of that build stage."); ConsoleKeyInfo keyInfo = Console.ReadKey(); if (keyInfo.Key == ConsoleKey.X) { return; } // Detailed error info if (keyInfo.Key == ConsoleKey.D9) { CISession.OutputSink.WriteNormal(""); WriteSevereMessages(); } // Git history if (keyInfo.Key == ConsoleKey.D1) { ciSession.GitProcessor.PrintGitHistory(); Console.WriteLine("Press [space] key to return to menu", Color.Yellow); while (Console.ReadKey().Key != ConsoleKey.Spacebar) { } } // Check to see if letter is in StageInfo Dictionary. char keyPress = keyInfo.KeyChar; if (keyPress > 96) { keyPress = (char)(keyPress - 32); } // Display detailed info about a specific stage... if (stageInfo.ContainsKey(keyPress)) { // Display detailed info BuildStage stage = stageInfo [keyPress]; Console.WriteLine(); Misc.WriteSubHeader(stage.Name, new List <string>() { "Detailed Output" }); Color lineColor = Color.WhiteSmoke; foreach (LineOutColored output in stage.StageOutput) { output.WriteToConsole(); } Console.WriteLine(); Console.WriteLine("Press [space] key to return to menu", Color.Yellow); while (Console.ReadKey().Key != ConsoleKey.Spacebar) { } } } }
/// <summary> /// Inserts the requested buildStage into the Execution plan. It will then add all predecessor Build Stages as well. /// </summary> /// <param name="buildStage"></param> /// <param name="parent"></param> private void AddBuildStage_ToExecutionPlan(BuildStage buildStage, BuildStage parent) { LinkedListNode <BuildStage> newNode = new LinkedListNode <BuildStage>(buildStage); // Add ourselves into the Execution plan at the proper place. if (parent == null) { _executionPlan.AddFirst(newNode); } else { // Need to ensure we add this before the parent LinkedListNode <BuildStage> parentNode = _executionPlan.Find(parent); if (parentNode == null) { throw new ApplicationException("Failed to locate the parent node for the BuildStage object [" + buildStage.Name + "]"); } // Determine if we are already in the list (Maybe some other stage also has us as a predecessor..) LinkedListNode <BuildStage> myself = _executionPlan.Find(buildStage); if (myself != null) { // Need to make sure the parent is not before us... If so we need to move ourselves, to before the parent bool continueSearching = true; LinkedListNode <BuildStage> priorParentLinkedListNode = myself.Previous; while (continueSearching) { // We were already at first item there are no more. if (priorParentLinkedListNode == null) { continueSearching = false; } // We found parent before us. We need to move ourselves to before the parent. else if (priorParentLinkedListNode.Value == parent) { _executionPlan.Remove(myself); _executionPlan.AddBefore(priorParentLinkedListNode, myself); continueSearching = false; } else if (priorParentLinkedListNode == _executionPlan.First) { continueSearching = false; } else { priorParentLinkedListNode = priorParentLinkedListNode.Previous; } } } else { myself = newNode; // Add ourselves ahead of the parent _executionPlan.AddBefore(parentNode, myself); } } // Now, add our predecessors foreach (string predecessor in buildStage.PredecessorList) { BuildStage childBuildStage = GetBuildStage(predecessor); AddBuildStage_ToExecutionPlan(childBuildStage, buildStage); } }
/// <summary> /// Builds the planned processing sequence for the build stages, depending on the final requested build stage /// </summary> /// <param name="endingStageName">The final build stage to stop at.</param> public void BuildExecutionPlan(string endingStageName) { BuildStage buildStage = GetBuildStage(endingStageName); AddBuildStage_ToExecutionPlan(buildStage, null); }
/// <summary> /// Adds the given Build Stage to the known List /// </summary> /// <param name="buildStage"></param> public void AddKnownStage(BuildStage buildStage) { _buildStages.Add(buildStage); }