Directory template
Project Flow directory template consist of layers. Each layer will be used
only if a switch is turned on in the mustache context (if that switch is named
in layer config). Every file, whose extension is .mustache, will have this
extension removed while copying the file to its destination, with the contents
processed by mustache engine.
Mustache context
Currently, a handful of proj-flow init settings are defined, each building
the mustache context a bit.
Interactive settings
Each setting defaults to first value, if it represents a list, or the current value itself if is is a scalar.
Context path |
Interactive label and values |
|---|---|
|
Project name Current directory name |
|
Project description Empty |
|
Valid email, e.g. for CODE_OF_CONDUCT Result of calling |
|
Year for copyright notices Current year |
|
Holder of the copyright Result of calling |
|
License one of
|
|
Prefix for includes (as in #include “{PREFIX}/version.hpp”) Current value of |
|
CMake variable name prefix Current value of |
|
C++ namespace for the project Current value of |
|
Extension for code files one of
(see note) |
|
Directory for code files
|
|
Directory for include files
|
|
CMake project type one of
(see note) |
Note
During the interactive phase, the EXT context is a string holding one of
the three code extensions, but afterwards it is removed and replaced with
an object consisting of EXT.cxx (holding the original extension) and
EXT.hxx (holding matching header extension, one of .hpp, .hh and
.hxx).
Note
The INCLUDEDIR context default value is "include", but after
the interactive phase it is amended to "{INCLUDEDIR}/{INCLUDE_PREFIX}".
Note
During the post process phase, PROJECT.TYPE context is used to add a
cmake context according to mapping below:
Project type |
|
|---|---|
|
{
"cmd": "add_executable",
"type": "",
"console-application": true,
"console": true,
"application": true,
"link_access": "PRIVATE",
},
|
|
{
"cmd": "add_executable",
"type": " WIN32",
"win32-application": true,
"win32": true,
"application": true,
"link_access": "PRIVATE",
},
|
|
{
"cmd": "add_library",
"type": " STATIC",
"static-library": true,
"static": true,
"library": true,
"link_access": "PUBLIC",
},
|
|
{
"cmd": "add_library",
"type": " SHARED",
"shared-library": true,
"shared": true,
"library": true,
"link_access": "PUBLIC",
},
|
|
{
"cmd": "add_library",
"type": " MODULE",
"plugin-library": true,
"plugin": true,
"library": true,
"link_access": "PUBLIC",
},
|
Interactive switches
Switches are used mostly to guard inclusion of various template layers. Each of
them allows true/false answers and all are true by default, with only
exception set to false being with.github.auto-release. The interactive
prompts accept yes, on and 1 for true value, and no, off
and 0 for false value.
Context switch |
Interactive label |
|---|---|
|
Use Conan for dependency manager |
|
Use CMake |
|
Use Github Actions |
|
Make a GitHub release automatically on each closed PR |
|
Use Github ISSUE_TEMPLATE, CONTRIBUTING.md, etc. |
Non-interactive settings
In addition to above, there are some context settings, which are only calculated after the interactive phase. With already mentioned, those are:
Context path |
Value source |
|---|---|
|
Current value of |
|
Header analogue for |
|
Object mapped using
|
|
|
|
|
|
|
Note
The ${ context path is useful in mustached CMake scripts, where a
variable reference would start with a mustache replacement. In such case
${{{PREFIX}}_SUFFIX}
would result in bad context lookup. This could be fixed with a
{{${}}{{PREFIX}}_SUFFIX}
which would replace ${ with itself, the PREFIX with its proper
value, rendering the whole thing as a proper CMake variable expression.
Layer schema
For a given layer directory, there exists a JSON config named after the
directory (e.g. layer.json for layer/). Each config must be a JSON
object with each property is optional (so a minimal config would be just
an empty object, or {}).
whenIf present, names a mustache context, which must be true-ish in order for any file to be copied over. If this property is missing, the layer is always added to the project.
filelistIf present, it is an object allowing special treatment of files in the layer. Any file not mentioned here will be treated as if both their
whenandpathwere missing. If this property is missing, it will be treated as an empty object, as if all files in layer were missing from it.filelist.<in-layer-path>.whenIf present, names a mustache context, which must be true-ish in order for this file to be copied over. If this property is missing, the file is added as if naming an always-true context.
filelist.<in-layer-path>.pathIf present, names a mustache expression, which will be used for destination filename. If this property is missing, the source filename is used, with the .mustache extension removed as needed.
Layer example
+- layer/
+- code/
| +- main.mustache
| +- header.mustache
+- flow
+- flow.cmd
+- README.md.mustache
{
"filelist": {
"code/main.mustache": {
"path": "{{SRCDIR}}/main{{EXT.cxx}}",
"when": "cmake.application"
},
"code/header.mustache": {
"path": "{{INCLUDEDIR}}/main{{EXT.hxx}}",
}
}
}
{
"EXT": { "cxx": "cpp", "hxx": "hpp" },
"SRCDIR": "source",
"INCLUDEDIR": "include/project",
"cmake": { "application": false }
}
+- project/
+- include/
| +- project/
| +- main.hpp
+- flow
+- flow.cmd
+- README.md
Here, both include/project/main.hpp and README.md are filtered through
the mustache engine and other files copied directly. If the
cmake.application context was true, the project directory would have an
additional source/main.cpp file rendered from layer/code/main.mustache.