Skip to content

Builders

Builders are Go templates in YAML format that contain the structure of folders and files to be created.

Structure

A builder is defined as follows:

global: Global variables that can be used in all templates.

structure: The structure of folders and files that will be created.

Directories: The structure is defined in a tree format, where each nested item in the tree represents a directory.

Files: For Mr. Smith to identify an item as a file, an extension must be defined. In a file, there are the properties:

  • template: path to the file that contains the base template of the file to be created.
  • data: a map of data that will be transformed into variables to be used in the template.
  • includes: a list of templates that can be used within the base template.

Example:

.mr-smith/base.yaml
global:
packageName: "github.com/mr-smith-org/simple-project"
structure:
src:
services:
UserService.ts:
template: templates/Service.ts
data:
name: User
includes:
- templates/ImportResolver.ts
index.ts
template: templates/index.ts

Result:

  • Directorysrc
    • Directoryservices
      • UserService.ts
    • index.ts

Variables

Since Builders are nothing more than Go templates, it is possible to build them dynamically using variables. Variables within Go templates are defined between {{}}. In Mr. Smith, they need to be prefixed with .data to take effect, see the example:

.mr-smith/base.yaml
global:
packageName: {{.data.packageName}}
structure:
src:
services:
{{.data.serviceName}}Service.ts:
template: templates/Service.ts
data:
name: {{.data.serviceName}}
includes:
- templates/ImportResolver.ts
index.ts
template: templates/index.ts

Variables:

  • packageName: github.com/mr-smith-org/simple-project
  • serviceName: User

Result:

  • Directorysrc
    • Directoryservices
      • UserService.ts
    • index.ts

Advanced Usage

It is possible to create really complex structures using builders. In the example below, the builder is generated from a Swagger.json file and creates the folder structure dynamically according to the definitions and tags found in the file:

{{$base := .data.apiData}}
structure:
src:
dto:
index.ts:
template: templates/DTOExporter.gtpl
data:
{{range $name, $prop := $base.definitions }}{{ if eq $prop.type "object" }}
- {{ $name }}
{{end}}{{end}}
{{range $name, $prop := $base.definitions }}{{ if eq $prop.type "object" }}{{ toSnakeCase $name }}.ts:
template: templates/DTO.gtpl
includes:
- templates/TypeResolver.gtpl
data:
name: {{ $name }}
{{ range toYaml . }}{{ . }}
{{end}}
{{end}}{{end}}
services:
builder.ts:
template: templates/ServiceBuilder.gtpl
data:
{{range $base.tags}}
- {{.name}}
{{end}}
index.ts:
template: templates/ServiceExporter.gtpl
data:
{{range $base.tags}}
- {{.name}}
{{end}}
{{range $base.tags}}{{toSnakeCase .name}}:
{{$tag := .}}
service.ts:
template: templates/Service.gtpl
includes:
- templates/TypeResolver.gtpl
- templates/ResponseTypeResolver.gtpl
data:
name: {{$tag.name}}
description: {{$tag.description}}
operations:
{{range $path, $req := getPathsByTag $base.paths $tag.name}}
{{$path}}:
{{range toYaml $req}}{{.}}
{{end}}
{{end}}
{{end}}

To learn more about text templates and how to use them with Mr. Smith, visit the link: Text Templates in Go