Help ExampleΒΆ

This example shows custom functions and classes used to enumerate the targets in the build and list them in the console. Targets have a description attribute, and this example allows for a group to be included in the description, separated from the actual target description using a | character. This example makes use of the Console Example to output text in color; include Console.shade in the imports folder if you aren’t using the source code from github.

build.cmd:

@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 %*

Help.shade saved to the imports directory:

use namespace="System"
use namespace="System.IO"
use namespace="System.Collections"
use namespace="System.Collections.Generic"
use import="Console"

functions
   @{
      void WriteHelp()
      {
         WriteHelpHeader();

         var groups = GetTargetGroups();

         WriteHelpGroups(groups);
         WriteHelpFooter();
      }

      void WriteHelpHeader()
      {
         WriteLine();
         Write("********************************", ConsoleColor.DarkGreen);
         Write(" HELP ", ConsoleColor.Green);
         WriteLine("********************************", ConsoleColor.DarkGreen);
         WriteLine();
         Write("This build script has the following build ");
         Write("targets", ConsoleColor.Green);
         WriteLine(" set up:");
      }

      TargetGroups GetTargetGroups()
      {
         var groups = new TargetGroups();

         foreach(var kvp in Targets)
         {
            var target = kvp.Value;
            var tokens = target.Description.Split((char)'|'); 

            if (tokens.Length == 2)
            {
               groups.Add(tokens[0], target.Name, tokens[1]);
            }
            else
            {
               groups.AddUngrouped(target.Name, target.Description);
            }
         }

         return groups;
      }

      void WriteHelpGroups(TargetGroups groups)
      {
         // write out any ungrouped targets first
         foreach(var target in groups.UngroupedItems)
         {
            WriteLine();
            Write(" ");
            Write(target.Name, ConsoleColor.Green);
            Write(" = ");
            WriteLine(target.Description);
         }

         // write out groups
         foreach(var group in groups)
         {
            WriteLine();
            Write(" ");
            WriteLine(group.Name, ConsoleColor.DarkGreen);

            foreach(var target in group.Targets)
            {
               Write("  > ");
               Write(target.Name, ConsoleColor.Green);
               Write(" = ");
               WriteLine(target.Description);
            }
         }
      }

      void WriteHelpFooter()
      {
         WriteLine();
         WriteLine(" For a complete list of build tasks, view makefile.shade.");
         WriteLine();
         WriteLine("**********************************************************************", ConsoleColor.DarkGreen);
      }

      public class TargetItem
      {
         public TargetItem(string name, string description)
         {
            Name = name;
            Description = description;
         }

         public string Name { get; private set; }

         public string Description { get; private set; }
      }

      public class TargetGroup
      {
         private readonly List<TargetItem> _targets;

         public TargetGroup(string name) 
         {
            _targets = new List<TargetItem>();
            Name = name;
         }

         public string Name { get; private set; }

         public List<TargetItem> Targets { get { return _targets; } }

         public TargetItem Add(string name, string description)
         {
            var item = new TargetItem(name, description);
            _targets.Add(item);
            return item;
         }
      }

      public class TargetGroups : IEnumerable<TargetGroup>
      {
         private readonly Dictionary<string, TargetGroup> _groups;
         private readonly List<TargetItem> _ungrouped;

         public TargetGroups()
         {
            _groups = new Dictionary<string, TargetGroup>();	
            _ungrouped = new List<TargetItem>();			
         }

         public List<TargetItem> UngroupedItems 
         { 
            get { return _ungrouped; }
         }

         public TargetGroup Add(string groupName, string itemName, string itemDescription)
         {
            var group = _groups.ContainsKey(groupName) ? _groups[groupName] : null;

            if (group == null)
            {
               group = new TargetGroup(groupName);
               _groups.Add(group.Name, group);
            }

            group.Add(itemName, itemDescription);

            return group;
         }

         public TargetItem AddUngrouped(string itemName, string itemDescription)
         {
         	var item = new TargetItem(itemName, itemDescription);
            _ungrouped.Add(item);
            return item;
         }

         System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
         {
            return this.GetEnumerator();
         }

         public IEnumerator<TargetGroup> GetEnumerator()
         {
            foreach(var kvp in _groups)
            {
               yield return kvp.Value;
            }
         }
      }
   }

makefile.shade:

use import="Console"
use import="Help"

#default description="Comprehensive|Performs a full clean, build and test"

#clean description="Build|Remove artifacts of a previous build"

#dnx description="Build|Check for and install DNX."

#restore description="Build|Restore packages for the project"

#build description="Build|Build the project"

#alltest description="Test|Run all tests"

#unittest description="Test|Run unit tests"

#inttest description="Test|Run integration tests"

#help description="Help|Displays a list of build commands"
   @{
      WriteHelp();
   }

Output:

../_images/help.jpg