project-scaffolder v0.3.0
project-scaffolder
Create project from templates with cool templating capabilities to replace variables in files and paths.
Installation — Documentation — Contributing — License
Installation
To start to use Project Scaffolder, you should first create a npm module with its package.json.
Then, You should create:
- A folder
templatewhich will contain your project template files - A configuration file
scaff.ymlwhich contains the configuration of your template
projectFolder
|- package.json
|- scaff.yml
|- template/At this stage, you will be able to install the module project-scaffolder.
npm install --save project-scaffolderDocumentation
This README is the main usage documentation.
Project Scaffolder uses external libraries to provide some of its functionality; refer to their documentation for more information:
The source code is also heavily commented and run through Docker, so you can read the resulting annotated source code for more details about the implementation.
Check the CHANGELOG for information about new features and breaking changes.
Usage
- Examples
- How to create a project template
- How to override config file and template folder
- How to write the configuration file
Examples
Before going in the details, let's take a look to some examples.
First project template example
In order to generate a new project based on a template, you should prepare that template. Let's start with a basic example.
Our template project (you can take a look to the First example.) has the following content:
examples/first/
|- package.json
|- scaff.yml
|- template/
|- templateFile.txtThe resulting project from that template will be:
results/first/
|- templateFile.txtIn fact, the content of the templateFile.txt
Welcome {{ username }}!will become (if the username has the value John):
Welcome John!To get that result, we use the following commands and we give the answer John to the question and also an output folder to store the generated content.
$> cd <projectTemplatePath>
$> project-scaffolder
prompt: Enter your username: John
prompt: finally the output directory (will be created if not existing): <outputFolder>
Project configuration:
username: JohnThen you can see the result.
Second project template example
In the second example, we will see an example that use also filtering into the file paths.
Our template project (you can take a look to the Second example.) has the following content:
examples/second/
|- package.json
|- scaff.yml
|- template/
|- __subPath__/
|- templateFile.txtThe resulting project from that template will be (if subpath value is one/two/three):
destination/folder/
|- one/
|- two/
|- three/
|- templateFile.txtIn fact, the content of the templateFile.txt
Welcome {{ username }}!will become (if the username has the value John):
Welcome John!To get that result, we use the following commands and we give the answer John to the question and also an output folder to store the generated content.
$> cd <projectTemplatePath>
$> project-scaffolder
prompt: Enter your username: John
prompt: Enter the sub path: one/two/three
prompt: finally the output directory (will be created if not existing): <outputFolder>
Project configuration:
username: John
subPath: one/two/threeThen you can see the result.
How to create a project
Based on the previous examples, you see that your project template need to contains several elements that are used to generate your project from your template.
package.jsonDefine yournpmmodule to allow usingproject-scaffolderin a specific version for your project template;scaff.ymlwhere you will store the configuration to be prompt to your template user (and later on, additional project template properties that can be used in the template generation proecss);templatethe folder where your template files are stored. The content of this folder will be processed and filtered to generate your project.
The files stored in the template folder can be:
textfiles that will be handled by templating engine to apply the filtering;binaryfile that will be simply copy from the project template to the project generated.
During the generation process, each text files will be given to Nunjucks which is the template engine used in project-scaffolder. This template engine is based on Jinja template engine. Then the syntax is quite similar and the possiblity to use filters is there. It means that you can be able to write something like that in your template files:
{{ someVariable | upper }}which will result to (if someVariable value is "John"):
JOHNThe same possibility is available to filter the paths but there, we need a different syntax.
The syntax for variable replacement and filtering is the following:
__variableName__
and
__variableName-filterName__The limitation of that syntax is that you cannot use - in the variable name or the filter name.
How to override the template config file and the template folder
By default, the scaff.yml and template folder are mandatory in a template project but you have the possibility to use a custom folder path and a custom configuration file.
For that, you have to use environment variables when you invoke project-scaffolder.
$> SCAFF_TEMPLATE_CONFIG_FILE=some/great/path/to/config.yml SCAFF_TEMPLATE_FOLDER=some/greate/to/project/template project-scaffolderYou can use only one of these options if you want.
How to write a configuration file
First, you need to create the file scaff.yml at the root of your template project.
Now, you are able to write something like that:
prompt:
properties:
propertyName:
message: Some message there
required: true
default: some default value
extras:
- extra-moduleThe prompt.properties configuration
This configuration section defines the questions that will be asked when the command project-scaffolder is run in the template project.
As the project-scaffolder use the module prompt to present the command line user interface, you can define the options as described in prompt documentation.
There is only one exception which do not allow to use before.
Then you can define a command line question like that:
propertyName:
description: String
type: String
pattern: RegExp
message: String
hidden: true|false
default: String
required: true|falseNote: The property name will be used as placeholder name during the templating process. Example:
package:
description: Define the root package for java classes
required: true
default: com.some.whereand one template somewhere:
package {{ package }}.else;
public class {
}which will produce that result if the default value is used:
package com.some.where.else;
public class {
}The extras configuration
This configuraiton section allow to load more modules for Nunjucks to enrich filters and tags.
The module names specified in the list should be installed in the project as usual via npm.
The modules must follow the requirements explained in project-scaffolder-extras
In summary, extra module must expose an object which contains the following structure:
module.syncFilters = {
syncFilterName: function(arg1, arg2, ...) {
...
return ...;
}
};
module.asyncFilters = {
asyncFilterName: function(arg1, arg2, callback) {
...
callback(err, res);
}
};
module.syncTags = {
syncTagName: function(...) {
...
return ...;
}
};
module.asyncTags = {
asyncTagName: function(..., callback) {
...
callback(err, res);
}
};You can also have this syntax:
module.filtersSync = {};
module.filtersAsync = {};
module.tagsSync = {};
module.tagsAsync = {};You should carefully read the documentation of Nunjucks to know how to write filters and tags (synchronous vs. asynchronous).
Note: Currently, the asynchronous filters are not supported for the filtering process done in file paths of the template.
Contributing
- Fork
- Create a topic branch -
git checkout -b feature - Push to your branch -
git push origin feature - Create a pull request from your branch
Please add a changelog entry with your name for new features and bug fixes.
License
Project Scaffolder is licensed under the MIT License. See LICENSE.txt for the full text.