Template your files
This a tool/library born from the necessity of templating multiple files and pushing them in multiple locations.
- run
tp generate <mapping> [context-selector]
- interpolates Mapping and the selected context to generate a rendered mapping
- Interpolates rendered mapping with the selected context to get a contexts for each templates
- Interpolates Template A with its context to get rendered Template A
- Interpolates Template B with its context to get rendered Template B
- Using the destinations in rendered mapping and rendered Template A and rendered Template B generates a github PR
I know it is confusing, you might want to check out the examples
npm i -g @gitops-toolbox/templator
tp
Head over to templator-examples to try the tool
git clone https://github.com/gitops-toolbox/templator
cd templator
npm i
> ./bin/cli.js -b examples list templates # listTemplates
[
"context.js",
"context.njk"
]
> ./bin/cli.js -b examples list mappings # listMappings
[
"delete_location.json",
"example.js",
"readme.json",
"nested/example.njk"
]
> ./bin/cli.js -b examples context # showContext
{
"dev": {
"environment": "development",
"components": {
"application": {
"name": "templator"
},
"database": {
"name": "Database"
}
}
},
"prd": {
"environment": "production",
"components": {
"database": {
"name": "Database"
}
}
}
}
> ./bin/cli.js -b examples -o yaml context # showYamlContext
dev:
environment: development
components:
application:
name: templator
database:
name: Database
prd:
environment: production
components:
database:
name: Database
> ./bin/cli.js -b examples context dev.components.application # showContextSelector
{
"name": "templator"
}
> ./bin/cli.js -b examples context '["dev", "components", "application"]' # showContextSelectorJson
{
"name": "templator"
}
> ./bin/cli.js -b examples generate --just-mapping nested/example.njk dev # renderMapping
{
"mapping": {
"locations": [
{
"template": "context.njk",
"contextSelector": "components.application",
"destination": {
"type": "echo",
"params": {
"repo": "myorg/development",
"filepath": "application.json"
}
},
"tags": {
"type": "application"
},
"templateData": {
"context": {
"name": "templator"
},
"meta": {
"__mapping": "mappings/nested/example.njk",
"__template": "templates/context.njk"
}
}
},
{
"template": "context.js",
"contextSelector": "components.database",
"destination": {
"type": "echo",
"params": {
"repo": "myorg/development",
"filepath": "database.json"
}
},
"tags": {
"type": "database"
},
"templateData": {
"context": {
"name": "Database"
},
"meta": {
"__mapping": "mappings/nested/example.njk",
"__template": "templates/context.js"
}
}
}
]
},
"context": {
"environment": "development",
"components": {
"application": {
"name": "templator"
},
"database": {
"name": "Database"
}
}
}
}
> ./bin/cli.js -b examples generate -o yaml nested/example.njk dev # renderTemplate
locations:
- template: context.njk
contextSelector: components.application
destination:
type: echo
params:
repo: myorg/development
filepath: application.json
tags:
type: application
templateData:
context:
name: templator
meta:
__mapping: mappings/nested/example.njk
__template: templates/context.njk
renderedTemplate: |
# Template file templates/context.njk
# Mapping file mappings/nested/example.njk
{"name":"templator"}
- template: context.js
contextSelector: components.database
destination:
type: echo
params:
repo: myorg/development
filepath: database.json
tags:
type: database
templateData:
context:
name: Database
meta:
__mapping: mappings/nested/example.njk
__template: templates/context.js
renderedTemplate: |
# Template file templates/context.js
# Mapping file mappings/nested/example.njk
{"name":"Database"}
> ./bin/cli.js -b examples generate nested/example.njk dev -h # renderHumanReadable
---
{"destination":{"type":"echo","params":{"repo":"myorg/development","filepath":"application.json"}},"tags":{"type":"application"}}
---
# Template file templates/context.njk
# Mapping file mappings/nested/example.njk
{"name":"templator"}
---
{"destination":{"type":"echo","params":{"repo":"myorg/development","filepath":"database.json"}},"tags":{"type":"database"}}
---
# Template file templates/context.js
# Mapping file mappings/nested/example.njk
{"name":"Database"}
> ./bin/cli.js -b examples generate nested/example.njk dev -h --filter-by '{"type": "database"}' # renderHumanReadableFilterBy
---
{"destination":{"type":"echo","params":{"repo":"myorg/development","filepath":"database.json"}},"tags":{"type":"database"}}
---
# Template file templates/context.js
# Mapping file mappings/nested/example.njk
{"name":"Database"}
> ./bin/cli.js -b examples generate nested/example.njk dev -h --filter-by '{"type": "database"}' --hide-headers # renderFileContent
# Template file templates/context.js
# Mapping file mappings/nested/example.njk
{"name":"Database"}
> ./bin/cli.js -b examples generate delete_location.json dev -h # nullTemplate
---
{"destination":{},"tags":{}}
---
null
./bin/cli.js -b examples generate nested/example.njk dev --persist # persist
{
"echo": {
"templates": [
{
"template": "context.njk",
"contextSelector": "components.application",
"destination": {
"type": "echo",
"params": {
"repo": "myorg/development",
"filepath": "application.json"
}
},
"tags": {
"type": "application"
},
"templateData": {
"context": {
"name": "templator"
},
"meta": {
"__mapping": "mappings/nested/example.njk",
"__template": "templates/context.njk"
}
},
"renderedTemplate": "# Template file templates/context.njk\n# Mapping file mappings/nested/example.njk\n\n{\"name\":\"templator\"}\n"
},
{
"template": "context.js",
"contextSelector": "components.database",
"destination": {
"type": "echo",
"params": {
"repo": "myorg/development",
"filepath": "database.json"
}
},
"tags": {
"type": "database"
},
"templateData": {
"context": {
"name": "Database"
},
"meta": {
"__mapping": "mappings/nested/example.njk",
"__template": "templates/context.js"
}
},
"renderedTemplate": "# Template file templates/context.js\n# Mapping file mappings/nested/example.njk\n\n{\"name\":\"Database\"}\n"
}
]
}
}
./bin/cli.js -b examples generate nested/example.njk dev --persist --group-by type # groupBy
{
"echo": {
"application": {
"templates": [
{
"template": "context.njk",
"contextSelector": "components.application",
"destination": {
"type": "echo",
"params": {
"repo": "myorg/development",
"filepath": "application.json"
}
},
"tags": {
"type": "application"
},
"templateData": {
"context": {
"name": "templator"
},
"meta": {
"__mapping": "mappings/nested/example.njk",
"__template": "templates/context.njk"
}
},
"renderedTemplate": "# Template file templates/context.njk\n# Mapping file mappings/nested/example.njk\n\n{\"name\":\"templator\"}\n",
"group": "application"
}
]
},
"database": {
"templates": [
{
"template": "context.js",
"contextSelector": "components.database",
"destination": {
"type": "echo",
"params": {
"repo": "myorg/development",
"filepath": "database.json"
}
},
"tags": {
"type": "database"
},
"templateData": {
"context": {
"name": "Database"
},
"meta": {
"__mapping": "mappings/nested/example.njk",
"__template": "templates/context.js"
}
},
"renderedTemplate": "# Template file templates/context.js\n# Mapping file mappings/nested/example.njk\n\n{\"name\":\"Database\"}\n",
"group": "database"
}
]
}
}
}
./bin/cli.js new mapping.njk # createNjkMapping
{# You can access the context with 'this' #}
{# the output should be a valid json #}
{% set destination = "echo" %}
{
"locations": [
{
"template": "{{ TEMPLATE }}",
"contextSelector": "PATH.TO.{{ this.CONTEXT }}",
"destination": {
"type": "{{ destination }}",
"params": {
"repo": "{{this.ORG}}/{{this.REPO}}",
"filepath": "PATH_ON_REPO"
}
},
"tags": {
"KEY1": "VALUE1",
"KEY2": "VALUE2"
}
}
]
}
> ./bin/cli.js --help # showHelp
cli.js <command>
Commands:
cli.js context [context-selector] Output the full context
cli.js generate <mapping> [context-selector] Output the rendered templates
cli.js list <target> List one between templates and mappings
cli.js new <mapping> Output a template for the selected mapping
Options:
--help Show help [boolean]
--version Show version number [boolean]
-b, --base-dir path where to find the config [string] [default: "."]
--context-dir directory name of the context folder [string] [default: "context"]
--mappings-dir directory where to search for mappings [string] [default: "mappings"]
--templates-dir directory where to find the templates [string] [default: "templates"]
The data folder (default to context
) should only contain folders and json
files.
The data will be merged as for the logic in the config-loader
library.
The mappings folder (default to mappings
) can contain .json
or .njk
or .js
mapping files.
Each mapping files should return a valid object or json with the following content:
{
"locations": [
{
"template": "<template-path>",
"contextSelector": "<context-selector>",
"tags": {"tagName": "tagValue"}, # Optional
"destination": { "type": "<destination-type>", ... }
}
]
}
The templates folder (default to templates
).
The templates will be rendered by the mappings using Nunjucks.