Devinit is a command-line utility written in Rust that provides the ability to write templates for files and projects and interactively apply them to make boilerplate less annoying.
See the examples/
directory for examples of writing file and project templates.
A tracker for planned features can be found on Trello.
Note
If you use VS Code, official Devinit integration is available via the extension on the marketplace.
# Configure a file at path 'licence.txt' with the 'LicenceBlock' template,
# specifying values for the variables 'name' and 'year'.
$ devinit file -p licence.txt "LicenceBlock" -Dname="John Doe" -Dyear="2024"
# Process the template 'EditorConfig' and output the result to stdout.
$ devinit file --dry-run "EditorConfig"
# Create and populate a folder called 'dotnet-project' from the project
# template 'DotNet', specifying the variable 'projectName'.
$ devinit project -p dotnet-project/ "DotNet" -DprojectName="Utils"
# List all available templates on the system
$ devinit list
# List all variables found in the file template 'exampletpl' or its parents
$ devinit file --list-vars "exampletpl"
Devinit is configured using the devinitrc.yml
file, which can be stored at either ~/.devinit/
or ~/.config/devinit/
. Otherwise, it can be
explicitly specified using the --config
command-line option.
devinitrc.yml
enforces a standard YAML syntax. The following fields are required:
Field | Value |
---|---|
file_templates_loc |
File template directory, relative to the configuration file |
project_templates_loc |
Project template directory, relative to the configuration file |
Any folder in the project_templates_loc
directory containing a templaterc.yml
file will be registered as a project template. This
configuration file is YAML, the same as the devinitrc file, and describes which files to process and where to output them.
Field | Value |
---|---|
files |
Dictionary of output paths (relative to evaluated template output) mapped to inputs, e.g. out.txt: input.txt |
A templating engine is provided to allow your configurations to use a simple format similar to Jinja, courtesy of the Tera project - see their documentation for an overview of the syntax.
In addition to a multitude of built-in functions/filters provided by Tera (see docs here), some extras are also provided by Devinit, and are documented below.
Expand a software licence, where id
is a valid SPDX id.
This function returns an object containing each component of the licence. The returned object is split up into the following elements (accessible by dot or square bracket notation):
name
- the licence nameheader
- the standard licence header*text
- the complete licence body
A lot of licences have places to substitute values, like year and copyright holder - it's recommended to use the provided replace filter to handle these template-side.
*Not all licences support the header component (the MIT licence, for example), and attempting to access it on them will result in an error. In these
cases, use the guaranteed text
field instead.
{% set gpl = licence(id = "GPL-2.0-only") -%}
{{ gpl.name }}
{{ gpl.header }}
{{ gpl.text }} {# A very long string #}
Assume a programming language ID from the specified filename. If filename
contains an extension, that is checked - otherwise filename
itself is
checked.
For a comprehensive list of possible language IDs, see the language_specifics.rs
source file.
One example use case could be with the file_name
builtin - this would give you the assumed file format of the output file,
when using the --path
option.
If the filename does not conform to any expected languages, "unknown" will be returned instead.
Return an object containing comment syntax, depending on lang_id
, which is any one of the language IDs returned by the
lang_by_filename function. If lang_id
isn't associated with any comment styles, then "unknown" is
returned instead.
The output object prefers comment blocks, and is in the order [ start, prefix, end ], where start
and end
should be on their own lines and
prefix
should be before each line of commented text.
For example, if the output is equal to ["#", "##", "###"], it is representing comment block syntax that looks like this:
#
## comment block
###
See the copyright example for a practical use case.
Break up the given string into lines of maximum length len
, without breaking individual words.
{{ gpl.text | wrap(len = 80) }}
Devinit provides built-in variables that are evaluated behind-the-scenes at render time. They are all contained in the BUILTIN
object, so they
can be accessed with dot notation (BUILTIN.foo
) or square bracket notation (BUILTIN["foo"]
).
identifier | Value |
---|---|
file_name * |
If --path is used - the name of the output file the template is being rendered to - otherwise, an empty string. |
file_contents * |
If --path is used, and it directs to an already-existing file, this contains the contents of that existing file. |
parent_name * |
If --path is used - the name of the first parent directory of the output file - otherwise, an empty string. |
*Not available in project templates.