Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cake: Build script progress

Tags:

c#

cakebuild

I'm currently building a Cake build script with interaction to teamcity and I'd like to provide progress messages. I can easily report the task name, but I am unable to find out what the progress is within the build script. Think like ("executing task 1 of 5").

Is there any way to find the progress within the build script?

like image 259
Sebazzz Avatar asked Aug 04 '16 08:08

Sebazzz


1 Answers

You could utilize TaskSetup and Tasks which are provided globally on the IScriptHost and always available.

An example of this below:

string target = "A";
int taskCounter = 0;
TaskSetup(
    taskSetupContext => {
        ICakeTaskInfo task = taskSetupContext.Task;
        Information("Executing Task {0} of {1} (Name: {2}, Description: {3}, Dependencies: {4})",
            ++taskCounter,
            Tasks.Count,
            task.Name,
            task.Description,
            string.Join(",",
                    task.Dependencies
                    )
            );
    });


Task("A")
    .Description("Alpha")
    .IsDependentOn("B")
    .Does(()=>{});

Task("B")
    .Description("Beta")
    .IsDependentOn("C")
    .Does(()=>{});

Task("C")
    .Description("Charlie")
    .IsDependentOn("D")
    .Does(()=>{});

Task("D")
    .Description("Delta")
    .Does(()=>{});

RunTarget(target);

The output of this script would be like below: Cake Script Output

It's got one flaw though if you got registered tasks not included in the current target they'll count too.

For example, if I add these Tasks:

Task("E")
    .Description("Echo")
    .Does(()=>{});

Task("F")
    .Description("Foxtrot")
    .Does(()=>{});

Output Tasks.Count will be 6 and the output will be like this: Cake Build Script Output 6 Tasks

Task graph is internal, albeit not optimal (but more correct), you could potentially walk the dependency graph yourself and count how many unique tasks there are, example of that below:

string target = "A";
int taskCounter = 0;
int taskCount = 0;

Setup(context => {
            // declare recursive task count function
            Func<string, List<string>, int> countTask = null;
            countTask = (taskName, countedTasks) => {
                    if (string.IsNullOrEmpty(taskName) || countedTasks.Contains(taskName))
                    {
                        return 0;
                    }

                    countedTasks.Add(taskName);

                    var task = Tasks.Where(t=>t.Name == taskName).FirstOrDefault();
                    if (task == null)
                    {
                        return 0;
                    }

                    int result = 1;
                    countedTasks.Add(taskName);
                    foreach(var dependecy in task.Dependencies)
                    {
                        result+=countTask(dependecy, countedTasks);
                    }

                    return result;
            };

        // count the task and store in globally available variable
        taskCount = countTask(target, new List<string>());
    });

TaskSetup(
    taskSetupContext => {
        ICakeTaskInfo task = taskSetupContext.Task;
        Information("Executing Task {0} of {1} (Name: {2}, Description: {3}, Dependencies: {4})",
            ++taskCounter,
            taskCount,
            task.Name,
            task.Description,
            string.Join(",",
                    task.Dependencies
                    )
            );
    });

Task("A")
    .Description("Alpha")
    .IsDependentOn("B")
    .Does(()=>{});

Task("B")
    .Description("Beta")
    .IsDependentOn("C")
    .Does(()=>{});

Task("C")
    .Description("Charlie")
    .IsDependentOn("D")
    .Does(()=>{});

Task("D")
    .Description("Delta")
    .Does(()=>{});

Task("E")
    .Description("Echo")
    .Does(()=>{});

Task("F")
    .Description("Foxtrot")
    .Does(()=>{});


RunTarget(target);

Output of this script would be: Cake script output

To summarize, what you want can be achieved utilizing:

  • Setup task to count Tasks available by given target using an recursive function, storing result in globally available variable.
  • TaskSetup to display your message
like image 61
devlead Avatar answered Sep 22 '22 17:09

devlead