Extending Sake¶
.shade
files containing functions, classes, or custom element tags can be imported into the primary build file. These files can be placed in a directory, which is then provided to Sake using the I
argument. For example, the following command would run Sake with import files in a directory named imports
:
Sake.exe -I imports -f makefile.shade %*
Custom Functions¶
Import files can contain C# functions and classes in a functions code block:
use namespace="System"
use namespace="System.Collections.Generic"
functions
@{
private List<CustomItem> _items = new List<CustomItem>();
public void AddCustomItem(string name)
{
_items.Add(new CustomItem { Name = name });
}
public void PrintCustomItems()
{
foreach(var item in _items)
{
Console.WriteLine(item.Name);
}
}
public class CustomItem
{
public string Name { get; set; }
}
}
These functions can be included in another .shade
file using the import
element:
use import="CustomFunctions"
#default
@{
AddCustomItem('foo');
AddCustomItem('bar');
AddCustomItem('baz');
PrintCustomItems();
}
Running this produces the following output:
>build.cmd
foo
bar
baz
Custom Element Tags¶
Import files can also be used to create custom element tags. To create a custom element, name the file with a leading underscore; the remainder of the file name will then be the element name. Within the file, default values for attributes can be specified, and any attribute values not provided with default values must be provided when the element is used.
The following simple example defines a default value of "Hello"
for the greeting
attribute. A value will be required for the name
attribute when the element is used.
default greeting='Hello'
@{
Log.Info(greeting + " " + name);
}
If the sample above is saved as _echo.shade
, it can be used in a target like so:
#echotag
echo name="Bob"
Running the echotag
target produces the following output:
>build.cmd echotag
info: Hello Bob
To use a custom element in C# code, you can define a macro
:
macro name='Echo' name='string' greeting='string'
echo
The macro can then be called as you would a C# function:
#echomacro
@{
Echo("Jack", "Good morning");
}
Examples¶
The following files include the code samples in this page. The build.cmd
file calls Sake specifying an import folder:
@echo off
cd %~dp0
SETLOCAL
SET NUGET_VERSION=latest
SET CACHED_NUGET=%LocalAppData%\NuGet\nuget.%NUGET_VERSION%.exe
IF EXIST "%CACHED_NUGET%" goto copynuget
echo Downloading latest version of NuGet.exe...
IF NOT EXIST "%LocalAppData%\NuGet" md "%LocalAppData%\NuGet"
@powershell -NoProfile -ExecutionPolicy unrestricted -Command "$ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest 'https://dist.nuget.org/win-x86-commandline/%NUGET_VERSION%/nuget.exe' -OutFile '%CACHED_NUGET%'"
:copynuget
IF EXIST .nuget\nuget.exe goto restore
md .nuget
copy "%CACHED_NUGET%" .nuget\nuget.exe > nul
:restore
IF EXIST packages\Sake goto run
.nuget\NuGet.exe install Sake -ExcludeVersion -Source https://www.nuget.org/api/v2/ -Out packages
:run
packages\Sake\tools\Sake.exe -I imports -f makefile.shade %*
Save the makefile.shade
file in the same folder as the build.cmd
file:
use import="CustomFunctions"
#default
@{
AddCustomItem('foo');
AddCustomItem('bar');
AddCustomItem('baz');
PrintCustomItems();
}
#echotag
echo name="Bob"
#echomacro
@{
Echo("Jack", "Good morning");
}
macro name='Echo' name='string' greeting='string'
echo
Create an imports
folder within the folder containing the build.cmd
file and create the following files in it.
CustomFunctions.shade
:
use namespace="System"
use namespace="System.Collections.Generic"
functions
@{
private List<CustomItem> _items = new List<CustomItem>();
public void AddCustomItem(string name)
{
_items.Add(new CustomItem { Name = name });
}
public void PrintCustomItems()
{
foreach(var item in _items)
{
Console.WriteLine(item.Name);
}
}
public class CustomItem
{
public string Name { get; set; }
}
}
_echo.shade
:
default greeting='Hello'
@{
Log.Info(greeting + " " + name);
}