A simple binary to do project templating
MIT License
spiro
- a project template generatorSpiro is an template structure generator that uses Golangs text/template library. It accepts both single files as well as directory trees as input and will interpret any template calls found inside the files and the file/directory names.
{{ .name }}.txt.templated:
{{ if .enabled }}x = {{ .x }}
y = {{ .y }}
{{ end }}
Footer content. Generated at {{ now.Format "2006-01-02" }}
spec.yaml:
name: example
enabled: true
x: 10
y: hello world
Then you can execute spiro '{{ .name }}.txt.templated' spec.yaml .
in order to generate a file called example.txt
that contains:
x = 10
y = hello world
Footer content. Generated at 2018-03-18
The rule-set is probably a bit complex to display here, but the following links are useful:
The only additional rule is the rule that controls whether a file or directory is processed or not. If a file name is templated like {{ if .blah }}filename.txt{{ end }}
then that file will only be processed if the name evaluates to a non-empty string.
The contents of a file will only be treated as templated if the file name has a .templated
suffix. If it does, the contents will be evaluated and the .templated
suffix will be removed.
Templating inside the file is evaluated after any template in the file name. So if you want an optional file that has templated content you'll need to use a name like {{ if .blah }}filename.txt.templated{{ end }}
. If the .templated
declaration is outside the condition the behaviour should be similar but is probably not the convention.
Some additional template functions are supplied:
title
: capitalise string (string) -> (string)
upper
: convert string to upper case (string) -> (string)
lower
: convert string to lower case (string) -> (string)
now
: return current time object () -> (time.Time)
json
: output a structure as json (object) -> (string)
jsonindent
: output a structure as indented json (object) -> (string)
unescape
: unescape escaped html characters (string) -> (string)
stringreplace
: basic string replace (subject, old, new) -> (string)
regexreplace
: regular expression based string replace (subject, pattern, repl) -> (string)
add
: Calculate the sum of two numbers (int, int) -> (int)
The spec file should be in JSON or Yaml form and will be passed to each template invocation. The specfile can be "-" to indicate that YAML should be read from stdin.
Permission bits for any files, including .templated
ones, will be copied to the destination files.
You have a file on disk called {{ lower .projectname }}.md.templated
with the following content:
# Heading for {{ .projectname }}
This project was started on {{ now.Format "2006-01-02" }} by {{ .author }}.
And if you feed it the following spec JSON:
{
"projectname": "HelloWorld",
"author": "Joe Soap"
}
You'll end up with a file called helloworld.md
containing:
# Heading for HelloWorld
This project was started on 2017-02-11 by Joe Soap.
By default the normal Golang template characters {{
are used but sometimes the files you're working with containing and you have to laboriously escape them.
You can provide the special key _spiro_delimiters_
in your spec file in order to override them:
_spiro_delimiters_:
- "<<<"
- ">>>"
spiro
versionSometimes new features are added to Spiro which are not supported by earlier versions. Sometimes templates rely on these features. By specifying a _spiro_min_version_
in your spec file, an error will be thrown if an earlier version of spiro
is used to build the template.
_sprio_min_version_: 1.5
The version rules work as follows:
major.minor.patch
)X.Y
== X.Y.0
and X
== X.0.0
X.Z
>= X.0
spiro
!Some demos exist in the /demo
directory. Run them as follows:
$ rm -rfv demo/output/project
$ ./spiro demo/example1 demo/example1.yml demo/output
Processing 'demo/example1/' -> 'demo/output/example1/'
Processing 'demo/example1/demo-{{upper .animal}}.templated' -> 'demo/output/example1/demo-BEAR'
Processing 'demo/example1/{{ if .x }}dontskip.txt{{ end }}' -> 'demo/output/example1/dontskip.txt'
Skipping 'demo/example1/{{ if not .x }}skipthis.txt{{ end }}' since the name evaluated to ''
Processing 'demo/example1/{{.subdir}}-thing/' -> 'demo/output/example1/Elephant-thing/'
Processing 'demo/example1/{{.subdir}}-thing/noop' -> 'demo/output/example1/Elephant-thing/noop'
Processing 'demo/example1/{{.subdir}}-thing/{{.subfile.name}}.{{.subfile.type}}' -> 'demo/output/example1/Elephant-thing/snake.xml'
$ find demo/output
demo/output
demo/output/example1
demo/output/example1/demo-BEAR
demo/output/example1/dontskip.txt
demo/output/example1/Elephant-thing
demo/output/example1/Elephant-thing/noop
demo/output/example1/Elephant-thing/snake.xml
The best option is to download the latest binaries from the releases page. Extract the one for your platform and put it in any directory where you have access.
Alternatively, use the install script which will do this for you:
$ curl https://raw.githubusercontent.com/astromechza/spiro/master/install.sh | sh
If a binary is not available for your platform, you'll need to build one yourself.
v1.8
-edit
option to the CLIv1.7
-
is given (#5)v1.6.0