# Authoring templates
Tenpureto tries to make template authoring as easy as possible. You don't need to learn any new templating language, a
template is just a regular Git repository, that you can build and test as you would usually do. Every template feature
is a branch in the template repository, and the only special thing you need to do is to add a .template.yaml
file to
tell Tenpureto how to use the template.
# Basics
One of the big advantages of Tenpureto is that the templates are composable. This allows starting projects with a template that is as close as possible to the desired set of features while keeping template maintenance manageable. When you create a template think of the options you want to provide. The examples of template features you might think of are:
- Programming languages (e.g. JavaScript and TypeScript flavors of the same template),
- Project types (e.g. a library, a pure backend service, or a service that has both a backend and a frontend),
- Service deployment alternatives (e.g. different cloud providers, Kubernetes, or serverless),
- CI services.
You will create a template branch for each of the features you want to provide, and Tenpureto will take care of merging them. Note that some features can be built on top of others. For example, a "full-stack service" will be an extension to the "pure backend service".
The second aspect you need to think of when you create a template is variables. Tenpureto templates don't have any
special syntax to mark the variables to be replaced. All you need is to define the variables in .template.yaml
, and
Tenpureto will replace all occurrences. It will also take care of using the correct style of the variable value:
template-project
will be replaced with my-cool-service
, while Template Project
will become My Cool Service
.
# Template descriptor
Every branch of the template needs to have a .template.yaml
file describing the feature this branch provides and
relations to other features and template variables. The file format is the following:
variables:
<variable name>: <value used in the template>
...
features:
- <feature name>:
description: <feature description>
stability: stable | experimental | deprecated
hidden: true | false
- ...
conflicts:
- <feature name>
- ...
excludes:
- <exclude pattern>
# Variables
The variables
section defines all template variables relevant to the template feature. It is a dictionary, with
human-friendly variable names as keys, and default variable values as dictionary values. Every occurence of a default
variable value in the template (both in a file content and in a file path) will be replaced with a value provided by a
user. Tenpureto will match the style of the value when doing a replacement. In the .template.yaml
try to use the most
natural value style. For example, the project description will probably be just a text, and for a Java package name, it
makes sense to use a dot-separated value.
# Features
In the features
section you describe the template features provided by the template branch. The feature names must
match the Git branch names. You need to list all features provided by this template branch, including the ones coming
from the parent branches. For each feature you may provide some additional information:
description
— human-friendly feature description that will be shown by thetenpureto
CLI when using the template,stability
— how mature the feature is, all features that are not marked asstable
will have a corresponding note in the CLI,hidden
— whether the feature should be available for selection in the CLI. In some cases, it is convenient to have a feature branch that is not directly available for selection, but that template authors can use to share code between other branches.
# Conflicts
In some cases, you may want to mark features as conflicting with each other. For example, you probably don't want to
have a project built by two different CI services simultaneously. You can list the features that conflict with the
current one in the conflicts
section.
# Excludes
Sometimes you want to have files in the template repository that shouldn't end up in generated projects. The typical
examples are README files, or a CI pipeline definition (if the template uses a different CI system than the target
projects). You can list these files in the excludes
section using the same pattern format as is used for
gitignore (opens new window) files.