I'm refactoring a Cake build script, and decided to introduce a class to hold some build settings that get passed around a lot and/or that exist in the global scope.
Some of the settings come from arguments, and are set using the Argument<T>(string name, string defaultValue)
syntax.
I'd like to create something like this:
var context = BuildContext.FromArguments();
For that I need acquire an instance of the current ICakeContext. The reason for that I believe is that all methods defined in cake scripts become methods of a custom-built ICakeContext
that probably inherits from CakeContext
and thus can call all of its (extension) methods, but once you define a class, it becomes a nested class that no longer has access to nice helpers like Argument<T>(name, defaultValue)
.
I was hoping I could either do ICakeContext.Current
or simply pass this
as in BuildContext.FromArguments(this)
or something similar.
But the keyword this
is not allowed at that level of a Cake script (not sure why, is the top level a static method?
So, the question is: how do I get a reference to the current ICakeContext
?
The reason that this
does not work, is because of the way Roslyn implements scripting, and there is no concept of this
in the script's outer scope.
You can access the context in a couple of different ways.
From a Task
:
Task("MyTask")
.Does(ctx =>
{
BuildContext.FromArguments(ctx);
});
From Setup
/Teardown
:
Setup(ctx =>
{
BuildContext.FromArguments(ctx);
});
Teardown(ctx =>
{
BuildContext.FromArguments(ctx);
});
From TaskSetup
/TaskTeardown
:
TaskSetup(ctx =>
{
BuildContext.FromArguments(ctx);
});
TaskTeardown(ctx =>
{
BuildContext.FromArguments(ctx);
});
From the outer script scope:
#load "somefile.csx"
BuildContext.FromArguments(Context);