The project uses Sourcery with Stencil templates to automate code generation for the Turnkey SDK. The specific template used is TurnkeyClient.stencil
, located in the @templates
folder.
Sourcery leverages the TurnkeyClient.stencil
template to generate Swift code based on the types defined in the Sources/TurnkeySDK/Generated
directory. The output of this process is a Swift file named TurnkeyClient.generated.swift
, which is placed in the Sources/TurnkeySDK
directory.
The process of running Sourcery with the Stencil templates is integrated into the project's Makefile
. Here's how the templates are run:
-
Generate Command: This is the main command that triggers the entire generation process, including running Sourcery.
generate: generate
-
Sourcery Command: This specific command runs Sourcery using the
TurnkeyClient.stencil
template.turnkey_client: sourcery --sources Sources/TurnkeySDK/Generated \ --output Sources/TurnkeySDK/TurnkeyClient.generated.swift \ --templates TurnkeyClient.stencil \ $(if $(WATCH),--watch,)
--sources
: Specifies the directory containing the source files that Sourcery will scan.--output
: Specifies where the generated Swift file will be placed.--templates
: Points to the Stencil template file.--watch
: An optional flag that, if set, makes Sourcery watch the source and template directories for changes and regenerate the output automatically.
The macros.stencil
file defines several macros that are reusable pieces of template code used to generate Swift code dynamically based on the types and methods defined in the Sourcery scanned data. Here's a breakdown of each macro:
-
- Generates method parameters for a given method name by matching structs whose names, when "Request" is removed, match the method name.
- It iterates over the methods of these structs and outputs each parameter's name and type, formatting the type by removing the "Swift." prefix.
-
- Similar to addMethodParams, but instead of just listing parameters, it constructs an instance of the struct with parameters passed to it.
-
- This macro is specialized for activity methods, excluding parameters named "_type" and "timestampMs".
- If the parameter is named "parameters", it maps the variables of the parameter's type into a list of parameters.
-
- Retrieves the type of activity from a method by finding the "_type" parameter and returning its value.
-
- Generates a list of parameters for a given intent struct name by mapping the struct's variables into a format suitable for initializing an instance of the struct.
-
- This is a comprehensive macro that generates a complete method for activity handling.
- It sets up the request and intent structures, prepares the input for the method call, and finally makes the call using the underlying client.
In the TurnkeyClient.stencil
file, these macros are imported and used to generate methods within the TurnkeyClient struct. Here's how they are utilized:
-
Importing Macros: At the beginning of the
TurnkeyClient.stencil
, macros frommacros.stencil
are imported.{% import "macros.stencil" %}
-
Using Macros in Method Generation:
- For each method in classes implementing
APIProtocol
, the template checks if it's an activity request (by checking if the method's parameters include "_type"). - Depending on whether it's an activity request or a regular request, it either calls
generateActivityMethod
or usesaddMethodParams
to generate the method signature and body. - For activity requests,
generateActivityMethod
is called, which internally uses other macros likeaddActivityMethodParams
,getActivityType
, andgetIntentParams
to generate a complete method. - For regular requests,
addMethodParams
is used to generate the method parameters, and the method body is constructed inline in theTurnkeyClient.stencil
.
- For each method in classes implementing
StencilSwiftKit
is an extension to Stencil that provides additional tags and filters useful for Swift code generation. In the context of these templates:
- Macros are defined using
{% macro macroName %}
and called using{% call macroName %}
. - The use of macros helps in reusing template code and keeping the
TurnkeyClient.stencil
file cleaner and more maintainable by abstracting complex logic into themacros.stencil
file.