/// <summary> /// Export the build graph to a Json file for parsing by Horde /// </summary> /// <param name="File">Output file to write</param> public void ExportForHorde(FileReference File) { DirectoryReference.CreateDirectory(File.Directory); using (JsonWriter JsonWriter = new JsonWriter(File.FullName)) { JsonWriter.WriteObjectStart(); JsonWriter.WriteArrayStart("Groups"); foreach (Agent Agent in Agents) { JsonWriter.WriteObjectStart(); JsonWriter.WriteArrayStart("Nodes"); foreach (Node Node in Agent.Nodes) { JsonWriter.WriteObjectStart(); JsonWriter.WriteValue("Name", Node.Name); JsonWriter.WriteValue("Group", Agent.Name); JsonWriter.WriteValue("RunEarly", Node.bRunEarly); JsonWriter.WriteValue("Exclusive", true); JsonWriter.WriteArrayStart("InputDependencies"); foreach (string InputDependency in Node.GetDirectInputDependencies().Select(x => x.Name)) { JsonWriter.WriteValue(InputDependency); } JsonWriter.WriteArrayEnd(); JsonWriter.WriteArrayStart("OrderDependencies"); foreach (string OrderDependency in Node.GetDirectOrderDependencies().Select(x => x.Name)) { JsonWriter.WriteValue(OrderDependency); } JsonWriter.WriteArrayEnd(); JsonWriter.WriteObjectEnd(); } JsonWriter.WriteArrayEnd(); JsonWriter.WriteObjectEnd(); } JsonWriter.WriteArrayEnd(); JsonWriter.WriteObjectEnd(); } }
/// <summary> /// Print the contents of the graph /// </summary> /// <param name="CompletedNodes">Set of nodes which are already complete</param> /// <param name="PrintOptions">Options for how to print the graph</param> public void Print(HashSet <Node> CompletedNodes, GraphPrintOptions PrintOptions) { // Print the options if ((PrintOptions & GraphPrintOptions.ShowCommandLineOptions) != 0) { // Get the list of messages List <string> Messages = new List <string>(); foreach (GraphOption Option in Options) { StringBuilder Message = new StringBuilder(); Message.AppendFormat("-set:{0}=... {1}", Option.Name, Option.Description); if (!String.IsNullOrEmpty(Option.DefaultValue)) { Message.AppendFormat(" (Default: {0})", Option.DefaultValue); } Messages.Add(Message.ToString()); } // Format them to the log if (Messages.Count > 0) { CommandUtils.LogInformation(""); CommandUtils.LogInformation("Options:"); CommandUtils.LogInformation(""); foreach (string Line in CommandUtils.FormatParams(Messages, 4, 24)) { CommandUtils.LogInformation(Line); } } } // Get a list of all the triggers, including the null global one List <ManualTrigger> AllTriggers = new List <ManualTrigger>(); AllTriggers.Add(null); AllTriggers.AddRange(NameToTrigger.Values.OrderBy(x => x.QualifiedName)); // Output all the triggers in order CommandUtils.LogInformation(""); CommandUtils.LogInformation("Graph:"); foreach (ManualTrigger Trigger in AllTriggers) { // Filter everything by this trigger Dictionary <Agent, Node[]> FilteredAgentToNodes = new Dictionary <Agent, Node[]>(); foreach (Agent Agent in Agents) { Node[] Nodes = Agent.Nodes.Where(x => x.ControllingTrigger == Trigger).ToArray(); if (Nodes.Length > 0) { FilteredAgentToNodes[Agent] = Nodes; } } // Skip this trigger if there's nothing to display if (FilteredAgentToNodes.Count == 0) { continue; } // Print the trigger name CommandUtils.LogInformation(" Trigger: {0}", (Trigger == null)? "None" : Trigger.QualifiedName); if (Trigger != null && PrintOptions.HasFlag(GraphPrintOptions.ShowNotifications)) { foreach (string User in Trigger.NotifyUsers) { CommandUtils.LogInformation(" notify> {0}", User); } } // Output all the agents for this trigger foreach (Agent Agent in Agents) { Node[] Nodes; if (FilteredAgentToNodes.TryGetValue(Agent, out Nodes)) { CommandUtils.LogInformation(" Agent: {0} ({1})", Agent.Name, String.Join(";", Agent.PossibleTypes)); foreach (Node Node in Nodes) { CommandUtils.LogInformation(" Node: {0}{1}", Node.Name, CompletedNodes.Contains(Node)? " (completed)" : Node.bRunEarly? " (early)" : ""); if (PrintOptions.HasFlag(GraphPrintOptions.ShowDependencies)) { HashSet <Node> InputDependencies = new HashSet <Node>(Node.GetDirectInputDependencies()); foreach (Node InputDependency in InputDependencies) { CommandUtils.LogInformation(" input> {0}", InputDependency.Name); } HashSet <Node> OrderDependencies = new HashSet <Node>(Node.GetDirectOrderDependencies()); foreach (Node OrderDependency in OrderDependencies.Except(InputDependencies)) { CommandUtils.LogInformation(" after> {0}", OrderDependency.Name); } } if (PrintOptions.HasFlag(GraphPrintOptions.ShowNotifications)) { string Label = Node.bNotifyOnWarnings? "warnings" : "errors"; foreach (string User in Node.NotifyUsers) { CommandUtils.LogInformation(" {0}> {1}", Label, User); } foreach (string Submitter in Node.NotifySubmitters) { CommandUtils.LogInformation(" {0}> submitters to {1}", Label, Submitter); } } } } } } CommandUtils.LogInformation(""); // Print out all the non-empty aggregates string[] AggregateNames = AggregateNameToNodes.Where(x => x.Value.Length > 0).Select(x => x.Key).OrderBy(x => x).ToArray(); if (AggregateNames.Length > 0) { CommandUtils.LogInformation("Aggregates:"); foreach (string AggregateName in AggregateNames) { CommandUtils.LogInformation(" {0}", AggregateName); } CommandUtils.LogInformation(""); } }
/// <summary> /// Print the contents of the graph /// </summary> /// <param name="NodeToState">Mapping of node to its current state</param> /// <param name="Options">Options for how to print the graph</param> public void Print(HashSet <Node> CompletedNodes, GraphPrintOptions Options) { // Get a list of all the triggers, including the null global one List <ManualTrigger> AllTriggers = new List <ManualTrigger>(); AllTriggers.Add(null); AllTriggers.AddRange(NameToTrigger.Values.OrderBy(x => x.QualifiedName)); // Output all the triggers in order CommandUtils.Log(""); CommandUtils.Log("Graph:"); foreach (ManualTrigger Trigger in AllTriggers) { // Filter everything by this trigger Dictionary <AgentGroup, Node[]> FilteredGroupToNodes = new Dictionary <AgentGroup, Node[]>(); foreach (AgentGroup Group in Groups) { Node[] Nodes = Group.Nodes.Where(x => x.ControllingTrigger == Trigger).ToArray(); if (Nodes.Length > 0) { FilteredGroupToNodes[Group] = Nodes; } } // Skip this trigger if there's nothing to display if (FilteredGroupToNodes.Count == 0) { continue; } // Print the trigger name CommandUtils.Log(" Trigger: {0}", (Trigger == null)? "None" : Trigger.QualifiedName); if (Trigger != null && Options.HasFlag(GraphPrintOptions.ShowNotifications)) { foreach (string User in Trigger.NotifyUsers) { CommandUtils.Log(" notify> {0}", User); } } // Output all the groups for this trigger foreach (AgentGroup Group in Groups) { Node[] Nodes; if (FilteredGroupToNodes.TryGetValue(Group, out Nodes)) { CommandUtils.Log(" Group: {0} ({1})", Group.Name, String.Join(";", Group.PossibleTypes)); foreach (Node Node in Nodes) { CommandUtils.Log(" Node: {0}{1}", Node.Name, CompletedNodes.Contains(Node)? " (completed)" : ""); if (Options.HasFlag(GraphPrintOptions.ShowDependencies)) { HashSet <Node> InputDependencies = new HashSet <Node>(Node.GetDirectInputDependencies()); foreach (Node InputDependency in InputDependencies) { CommandUtils.Log(" input> {0}", InputDependency.Name); } HashSet <Node> OrderDependencies = new HashSet <Node>(Node.GetDirectOrderDependencies()); foreach (Node OrderDependency in OrderDependencies.Except(InputDependencies)) { CommandUtils.Log(" after> {0}", OrderDependency.Name); } } if (Options.HasFlag(GraphPrintOptions.ShowNotifications)) { string Label = Node.bNotifyOnWarnings? "warnings" : "errors"; foreach (string User in Node.NotifyUsers) { CommandUtils.Log(" {0}> {1}", Label, User); } foreach (string Submitter in Node.NotifySubmitters) { CommandUtils.Log(" {0}> submitters to {1}", Label, Submitter); } } } } } } CommandUtils.Log(""); // Print out all the aggregates string[] AggregateNames = AggregateNameToNodes.Keys.OrderBy(x => x).ToArray(); if (AggregateNames.Length > 0) { CommandUtils.Log("Aggregates:"); foreach (string AggregateName in AggregateNames) { CommandUtils.Log(" {0}", AggregateName); } CommandUtils.Log(""); } }
/// <summary> /// Export the build graph to a Json file for parsing by Horde /// </summary> /// <param name="File">Output file to write</param> public void ExportForHorde(FileReference File) { DirectoryReference.CreateDirectory(File.Directory); using (JsonWriter JsonWriter = new JsonWriter(File.FullName)) { JsonWriter.WriteObjectStart(); JsonWriter.WriteArrayStart("Groups"); foreach (Agent Agent in Agents) { JsonWriter.WriteObjectStart(); JsonWriter.WriteArrayStart("Types"); foreach (string PossibleType in Agent.PossibleTypes) { JsonWriter.WriteValue(PossibleType); } JsonWriter.WriteArrayEnd(); JsonWriter.WriteArrayStart("Nodes"); foreach (Node Node in Agent.Nodes) { JsonWriter.WriteObjectStart(); JsonWriter.WriteValue("Name", Node.Name); JsonWriter.WriteValue("RunEarly", Node.bRunEarly); JsonWriter.WriteValue("Warnings", Node.bNotifyOnWarnings); JsonWriter.WriteArrayStart("InputDependencies"); foreach (string InputDependency in Node.GetDirectInputDependencies().Select(x => x.Name)) { JsonWriter.WriteValue(InputDependency); } JsonWriter.WriteArrayEnd(); JsonWriter.WriteArrayStart("OrderDependencies"); foreach (string OrderDependency in Node.GetDirectOrderDependencies().Select(x => x.Name)) { JsonWriter.WriteValue(OrderDependency); } JsonWriter.WriteArrayEnd(); JsonWriter.WriteObjectEnd(); } JsonWriter.WriteArrayEnd(); JsonWriter.WriteObjectEnd(); } JsonWriter.WriteArrayEnd(); JsonWriter.WriteArrayStart("Aggregates"); foreach (Aggregate Aggregate in NameToAggregate.Values) { JsonWriter.WriteObjectStart(); JsonWriter.WriteValue("Name", Aggregate.Name); JsonWriter.WriteArrayStart("Nodes"); foreach (Node RequiredNode in Aggregate.RequiredNodes.OrderBy(x => x.Name)) { JsonWriter.WriteValue(RequiredNode.Name); } JsonWriter.WriteArrayEnd(); JsonWriter.WriteObjectEnd(); } JsonWriter.WriteArrayEnd(); JsonWriter.WriteArrayStart("Labels"); foreach (Label Label in Labels) { JsonWriter.WriteObjectStart(); if (!String.IsNullOrEmpty(Label.DashboardName)) { JsonWriter.WriteValue("Name", Label.DashboardName); } if (!String.IsNullOrEmpty(Label.DashboardCategory)) { JsonWriter.WriteValue("Category", Label.DashboardCategory); } if (!String.IsNullOrEmpty(Label.UgsBadge)) { JsonWriter.WriteValue("UgsBadge", Label.UgsBadge); } if (!String.IsNullOrEmpty(Label.UgsProject)) { JsonWriter.WriteValue("UgsProject", Label.UgsProject); } if (Label.Change != LabelChange.Current) { JsonWriter.WriteValue("Change", Label.Change.ToString()); } JsonWriter.WriteArrayStart("RequiredNodes"); foreach (Node RequiredNode in Label.RequiredNodes.OrderBy(x => x.Name)) { JsonWriter.WriteValue(RequiredNode.Name); } JsonWriter.WriteArrayEnd(); JsonWriter.WriteArrayStart("IncludedNodes"); foreach (Node IncludedNode in Label.IncludedNodes.OrderBy(x => x.Name)) { JsonWriter.WriteValue(IncludedNode.Name); } JsonWriter.WriteArrayEnd(); JsonWriter.WriteObjectEnd(); } JsonWriter.WriteArrayEnd(); JsonWriter.WriteArrayStart("Badges"); foreach (Badge Badge in Badges) { HashSet <Node> Dependencies = Badge.Nodes; if (Dependencies.Count > 0) { // Reduce that list to the smallest subset of direct dependencies HashSet <Node> DirectDependencies = new HashSet <Node>(Dependencies); foreach (Node Dependency in Dependencies) { DirectDependencies.ExceptWith(Dependency.OrderDependencies); } JsonWriter.WriteObjectStart(); JsonWriter.WriteValue("Name", Badge.Name); if (!String.IsNullOrEmpty(Badge.Project)) { JsonWriter.WriteValue("Project", Badge.Project); } if (Badge.Change != 0) { JsonWriter.WriteValue("Change", Badge.Change); } JsonWriter.WriteValue("Dependencies", String.Join(";", DirectDependencies.Select(x => x.Name))); JsonWriter.WriteObjectEnd(); } } JsonWriter.WriteArrayEnd(); JsonWriter.WriteObjectEnd(); } }