예제 #1
0
        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());
        }
예제 #3
0
        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);
        }
예제 #4
0
        /// <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)));
        }
예제 #5
0
 /// <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);
        }
예제 #8
0
        /// <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);
        }
예제 #10
0
        /// <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;
        }
예제 #11
0
        /// <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;
        }
예제 #12
0
        /// <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;
        }
예제 #13
0
 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);
     }
 }
예제 #14
0
        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;
            }
예제 #15
0
 /// <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));
     }
 }
예제 #16
0
        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);
        }
예제 #18
0
파일: CakeEngine.cs 프로젝트: twenzel/cake
        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));
            }
        }
예제 #19
0
파일: CakeEngine.cs 프로젝트: twenzel/cake
        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));
            }
        }
예제 #20
0
파일: CakeEngine.cs 프로젝트: allenk/cake
        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;
                }
            }
        }
예제 #21
0
        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());
            }
        }
예제 #22
0
        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;
            }
        }
예제 #23
0
 public GraphGeneratorTests()
 {
     tasks = TestHelpers.CreateTasksWithDependencies();
     taskC = tasks.First(x => string.Equals(x.Name, "C"));
 }