Search code examples
cakebuild

How to write a simple cake module


I want to change the way cake logs results, so I must write a "module".

Unfortuntely there is no documentation for that, just a long and outdated (4+ years) video. I also looked at other modules, but they are too complicated - it's hard to tell the difference between the actual module stuff (what I'm interested in) and the library's domain code (what I'm not interested in).

Is there current documentation or a simple example for a "hello world" module?


Solution

  • A Cake module is a .NET assembly that can replace core internal features of Cake. Simplified a module declares which feature it wants to replace, it does so by registering that a core Cake interface should use another concrete implementation. Then during Cake startup Cake bootstraps by acquiring modules from NuGet and scans each module for Cake modules, instantiates modules and invokes each modules registrations which results in modifying Cake dependency injection to prefer module implementation over built-in.

    First of all a module needs an assembly level attribute declaring which modules it contains and each module needs to implement the ICakeModule interface, this could look something like

    using System;
    using Cake.Core;
    using Cake.Core.Annotations;
    using Cake.Core.Composition;
    using Cake.Core.Diagnostics;
    [assembly: CakeModule(typeof(Cake. CustomLog.Module.CustomLogModule))]
    namespace Cake.CustomLog.Module
    {
        public class CustomLogModule : ICakeModule
        {
            public void Register(ICakeContainerRegistrar registrar)
            {
                if (registrar is null)
                {
                    throw new ArgumentNullException(nameof(registrar));
                }
    
                registrar.RegisterType<CustomLog>().As<ICakeLog>().Singleton();
            }
        }
    }
    

    The assembly name needs follow the naming convention of Cake.{module name}.Module i.e. Cake.CustomLog.Module

    Modules are bootstrapped in scripts using the #module directive i.e.

    #module nuget:?package=Cake.CustomLog.Module&version=1.0
    

    The Cake.Core assembly contains core interfaces and implementations, so module needs to reference it and ideally the same version as the runner you plan to use it on, it can be found on NuGet at https://www.nuget.org/packages/Cake.Core

    To get a sense of which interfaces used you can look at one of the runners i.e. Cake.Tool to get a sense of what's registered in the IoC

    https://github.com/cake-build/cake/blob/develop/src/Cake/Program.cs and https://github.com/cake-build/cake/blob/develop/src/Cake/Infrastructure/ContainerConfigurator.cs good starting points.

    A dated/unfinished but fairly minimal module example can be found here https://github.com/devlead/Cake.LightModeConsole.Module