private void PrintTask(ICakeTaskInfo task, string indent, bool isLast, int depth) { // Builds ASCII graph _console.Write(indent); if (isLast) { _console.Write(_corner); indent += " "; } else if (depth > 0) { _console.Write(_cross); indent += _vertical; } PrintName(task, depth); if ((_maxDepth > 0) && (depth >= _maxDepth)) { return; } for (var i = 0; i < task.Dependencies.Count; i++) { // First() is safe as CakeGraphBuilder has already validated graph is valid var childTask = Tasks .Where(x => x.Name.Equals(task.Dependencies[i].Name, StringComparison.OrdinalIgnoreCase)) .First(); PrintTask(childTask, indent, i == (task.Dependencies.Count - 1), depth + 1); } }
private static string ConvertToString(ICakeTaskInfo task, IReadOnlyCollection <string> edges) { var sb = new StringBuilder(); if (!string.IsNullOrWhiteSpace(task.Description)) { sb.Append($"<p>{task.Description}</p>"); } sb.AppendLine("<div class=\"mermaid\">"); sb.AppendLine("graph TD;"); if (edges.Count == 0) { sb.AppendLine($"{task.Name};"); } foreach (var edge in edges) { sb.AppendLine(edge); } sb.AppendLine("</div>"); return(sb.ToString()); }
private IReadOnlyList <Node> GetTaskGraphNodes(ICakeContext context, ICakeTaskInfo task, IReadOnlyList <ICakeTaskInfo> tasks) { var taskDictionary = tasks.ToDictionary(); var nodes = new List <Node>(); var stack = new Stack <ICakeTaskInfo>(); stack.Push(task); while (stack.Count > 0) { var currentNode = stack.Pop(); context.Log.Write(Verbosity.Diagnostic, LogLevel.Debug, $"Creating Node for {currentNode.Name} which has {currentNode.Dependencies.Count} dependencies"); nodes.Add(new Node(currentNode.Name)); foreach (var dependencyName in currentNode.Dependencies) { var dependencyTask = TaskGraphGeneratorHelpers.GetTaskDependency(context, taskDictionary, dependencyName.Name); stack.Push(dependencyTask); context.Log.Write(Verbosity.Diagnostic, LogLevel.Debug, $"Creating Edge from {currentNode.Name} to {dependencyTask.Name}"); nodes.Add(new Node(Guid.NewGuid().ToString(), currentNode.Name, dependencyTask.Name)); } } return(nodes); }
/// <summary> /// Converts the task to a graph and outputs the string for displaying /// </summary> /// <param name="context"></param> /// <param name="task"></param> /// <param name="tasks"></param> /// <returns></returns> public Task <string> SerializeAsync(ICakeContext context, ICakeTaskInfo task, IReadOnlyList <ICakeTaskInfo> tasks) { TaskGraphGeneratorHelpers.ValidateParameters(context, task, tasks); var nodes = GetTaskGraphNodes(context, task, tasks); return(Task.FromResult(JsonConvert.SerializeObject(nodes))); }
/// <summary> /// Initializes a new instance of the <see cref="SetupContext"/> class. /// </summary> /// <param name="context">The Cake context.</param> /// <param name="targetTask">The target (initiating) task.</param> /// <param name="tasksToExecute">The tasks to execute.</param> public SetupContext(ICakeContext context, ICakeTaskInfo targetTask, IEnumerable <ICakeTaskInfo> tasksToExecute) : base(context) { TargetTask = targetTask; TasksToExecute = new List <ICakeTaskInfo>(tasksToExecute ?? Array.Empty <ICakeTaskInfo>()); }
/// <summary> /// Convert the task and dependencies to mermaid syntax string /// </summary> /// <param name="context"></param> /// <param name="task"></param> /// <param name="tasks"></param> /// <returns></returns> public async Task <string> SerializeAsync(ICakeContext context, ICakeTaskInfo task, IReadOnlyList <ICakeTaskInfo> tasks) { TaskGraphGeneratorHelpers.ValidateParameters(context, task, tasks); var edges = GetEdges(context, task, tasks); return(ConvertToString(task, edges)); }
/// <summary> /// Converts the task to a graph and outputs the string for displaying /// </summary> /// <param name="context"></param> /// <param name="task"></param> /// <param name="tasks"></param> /// <returns></returns> public string Serialize(ICakeContext context, ICakeTaskInfo task, IReadOnlyList <ICakeTaskInfo> tasks) { var graph = graphGenerator.Serialize(context, task, tasks); var model = new GraphHtmlModel(task.Name, MermaidJsSource, graph); var html = graphTemplateManager.ParseTemplate(TemplateTypes.Mermaid, model); return(html); }
/// <summary> /// Initializes a new instance of the <see cref="TaskSetupContext"/> class. /// </summary> /// <param name="task">The task.</param> public TaskSetupContext(ICakeTaskInfo task) { if (task == null) { throw new ArgumentNullException("task"); } _task = task; }
/// <inheritdoc /> public async Task <string> SerializeAsync(ICakeContext context, ICakeTaskInfo task, IReadOnlyList <ICakeTaskInfo> tasks) { var graph = await graphGenerator.SerializeAsync(context, task, tasks); var model = new GraphHtmlModel(task.Name, CytoscapeJsSource, graph); var html = await graphTemplateManager.ParseTemplateAsync(templateType, model); return(html); }
/// <summary> /// Initializes a new instance of the <see cref="TaskSetupContext"/> class. /// </summary> /// <param name="context">The Cake Context.</param> /// <param name="task">The task.</param> public TaskSetupContext(ICakeContext context, ICakeTaskInfo task) : base(context) { if (task == null) { throw new ArgumentNullException(nameof(task)); } Task = task; }
/// <summary> /// Initializes a new instance of the <see cref="TaskTeardownContext"/> class. /// </summary> /// <param name="task">The task.</param> /// <param name="duration">The duration of the task.</param> /// <param name="skipped">if set to <c>true</c>, the task was not executed.</param> public TaskTeardownContext(ICakeTaskInfo task, TimeSpan duration, bool skipped) { if (task == null) { throw new ArgumentNullException("task"); } _task = task; _duration = duration; _skipped = skipped; }
/// <summary> /// Initializes a new instance of the <see cref="TaskTeardownContext"/> class. /// </summary> /// <param name="context">The Cake Context.</param> /// <param name="task">The task.</param> /// <param name="duration">The duration of the task.</param> /// <param name="skipped">if set to <c>true</c>, the task was not executed.</param> public TaskTeardownContext(ICakeContext context, ICakeTaskInfo task, TimeSpan duration, bool skipped) : base(context) { if (task == null) { throw new ArgumentNullException(nameof(task)); } Task = task; Duration = duration; Skipped = skipped; }
public static CakeTaskBuilder CreateModifiedTaskBuilder(ICakeTaskInfo task) { try { var builderType = typeof(CakeTaskBuilder); var constr = builderType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { typeof(CakeTask) }, null); return((CakeTaskBuilder)constr.Invoke(null, new[] { task })); } catch (Exception ex) { throw new InvalidOperationException("Unable to create task builder.", ex); } }
private void PrintName(ICakeTaskInfo task, int depth) { var originalColor = _console.ForegroundColor; if (depth == 0) { _console.ForegroundColor = ConsoleColor.Cyan; } else if (task is CakeTask cakeTask && (cakeTask.Actions.Any() || cakeTask.DelayedActions.Any())) { _console.ForegroundColor = ConsoleColor.Green; }
/// <summary> /// Ensure parameters are valid /// </summary> /// <param name="context"></param> /// <param name="task"></param> /// <param name="tasks"></param> /// <exception cref="ArgumentNullException"></exception> public static void ValidateParameters(ICakeContext context, ICakeTaskInfo task, IReadOnlyList <ICakeTaskInfo> tasks) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (task == null) { throw new ArgumentNullException(nameof(task)); } if (tasks == null) { throw new ArgumentNullException(nameof(tasks)); } }
public void Should_Implement_ICakeTaskInfo() { // Given var task = new CakeTask("task"); task.AddDependency("dependency1"); task.AddDependency("dependency2"); task.Description = "my description"; // When ICakeTaskInfo result = task; // Then Assert.IsAssignableFrom <ICakeTaskInfo>(task); Assert.Equal("task", result.Name); Assert.Equal("my description", result.Description); Assert.Equal(new[] { "dependency1", "dependency2" }, result.Dependencies.Select(x => x.Name).ToArray()); }
private static IReadOnlyCollection <string> GetEdges(ICakeContext context, ICakeTaskInfo task, IReadOnlyList <ICakeTaskInfo> tasks) { var taskDictionary = tasks.ToDictionary(); var stack = new Stack <ICakeTaskInfo>(); stack.Push(task); var edges = new List <string>(); var visited = new HashSet <string>(); while (stack.Count > 0) { var currentNode = stack.Pop(); context.Log.Write(Verbosity.Diagnostic, LogLevel.Debug, $"Creating Node for {currentNode.Name} which has {currentNode.Dependencies.Count} dependencies"); foreach (var dependencyName in currentNode.Dependencies) { var dependencyTask = TaskGraphGeneratorHelpers.GetTaskDependency(context, taskDictionary, dependencyName.Name); if (visited.Contains(dependencyTask.Name, StringComparer.InvariantCultureIgnoreCase)) { continue; } visited.Add(dependencyTask.Name); stack.Push(dependencyTask); context.Log.Write(Verbosity.Diagnostic, LogLevel.Debug, $"Creating Edge from {currentNode.Name} to {dependencyTask.Name}"); var edge = $"{currentNode.Name}-->{dependencyTask.Name};"; edges.Add(edge); } } return(edges); }
private void PerformTaskTeardown(ICakeContext context, IExecutionStrategy strategy, ICakeTaskInfo task, TimeSpan duration, bool skipped, Exception taskException) { var exceptionWasThrown = taskException != null; var taskTeardownContext = new TaskTeardownContext(context, task, duration, skipped, taskException); PublishEvent(BeforeTaskTeardown, new BeforeTaskTeardownEventArgs(taskTeardownContext)); #pragma warning disable 618 PublishEvent(TaskTeardown, new TaskTeardownEventArgs(taskTeardownContext)); #pragma warning restore 618 try { if (_actions.TaskTeardown != null) { try { strategy.PerformTaskTeardown(_actions.TaskTeardown, taskTeardownContext); } catch (Exception ex) { _log.Error("An error occurred in the custom task teardown action ({0}).", task.Name); if (!exceptionWasThrown) { // If no other exception was thrown, we throw this one. throw; } _log.Error("Task Teardown error ({0}): {1}", task.Name, ex.ToString()); } } } finally { PublishEvent(AfterTaskTeardown, new AfterTaskTeardownEventArgs(taskTeardownContext)); } }
private void PerformTaskSetup(ICakeContext context, IExecutionStrategy strategy, ICakeTaskInfo task, bool skipped) { var taskSetupContext = new TaskSetupContext(context, task); PublishEvent(BeforeTaskSetup, new BeforeTaskSetupEventArgs(taskSetupContext)); #pragma warning disable 618 PublishEvent(TaskSetup, new TaskSetupEventArgs(taskSetupContext)); #pragma warning restore 618 // Trying to stay consistent with the behavior of script-level Setup & Teardown (if setup fails, don't run the task, but still run the teardown) try { if (_actions.TaskSetup != null) { try { strategy.PerformTaskSetup(_actions.TaskSetup, taskSetupContext); } catch (Exception exception) { PerformTaskTeardown(context, strategy, task, TimeSpan.Zero, skipped, exception); throw; } } } finally { PublishEvent(AfterTaskSetup, new AfterTaskSetupEventArgs(taskSetupContext)); } }
private void PerformTaskSetup(ICakeContext context, IExecutionStrategy strategy, ICakeTaskInfo task, bool skipped) { var taskSetupContext = new TaskSetupContext(context, task); PublishEvent(TaskSetup, new TaskSetupEventArgs(taskSetupContext)); // Trying to stay consistent with the behavior of script-level Setup & Teardown (if setup fails, don't run the task, but still run the teardown) if (_actions.TaskSetup != null) { try { strategy.PerformTaskSetup(_actions.TaskSetup, taskSetupContext); } catch { PerformTaskTeardown(context, strategy, task, TimeSpan.Zero, skipped, true); throw; } } }
private void PerformTaskTeardown(ICakeContext context, IExecutionStrategy strategy, ICakeTaskInfo task, TimeSpan duration, bool skipped, bool exceptionWasThrown) { if (TaskTeardownAction == null) { return; } var taskTeardownContext = new TaskTeardownContext(task, duration, skipped); try { strategy.PerformTaskTeardown(TaskTeardownAction, context, taskTeardownContext); } catch (Exception ex) { _log.Error("An error occured in the custom task teardown action ({0}).", task.Name); if (!exceptionWasThrown) { // If no other exception was thrown, we throw this one. throw; } _log.Error("Task Teardown error ({0}): {1}", task.Name, ex.ToString()); } }
private void PerformTaskSetup(ICakeContext context, IExecutionStrategy strategy, ICakeTaskInfo task, bool skipped) { // Trying to stay consistent with the behavior of script-level Setup & Teardown (if setup fails, don't run the task, but still run the teardown) if (TaskSetupAction == null) { return; } try { var taskSetupContext = new TaskSetupContext(task); strategy.PerformTaskSetup(TaskSetupAction, context, taskSetupContext); } catch { PerformTaskTeardown(context, strategy, task, TimeSpan.Zero, skipped, true); throw; } }
public GraphGeneratorTests() { tasks = TestHelpers.CreateTasksWithDependencies(); taskC = tasks.First(x => string.Equals(x.Name, "C")); }